summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/TextSearch.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/utils/TextSearch.cpp
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip
sync with upstream
Diffstat (limited to 'xbmc/utils/TextSearch.cpp')
-rw-r--r--xbmc/utils/TextSearch.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/xbmc/utils/TextSearch.cpp b/xbmc/utils/TextSearch.cpp
new file mode 100644
index 0000000..1ada61d
--- /dev/null
+++ b/xbmc/utils/TextSearch.cpp
@@ -0,0 +1,146 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "TextSearch.h"
10
11#include "StringUtils.h"
12
13CTextSearch::CTextSearch(const std::string &strSearchTerms, bool bCaseSensitive /* = false */, TextSearchDefault defaultSearchMode /* = SEARCH_DEFAULT_OR */)
14{
15 m_bCaseSensitive = bCaseSensitive;
16 ExtractSearchTerms(strSearchTerms, defaultSearchMode);
17}
18
19bool CTextSearch::IsValid(void) const
20{
21 return m_AND.size() > 0 || m_OR.size() > 0 || m_NOT.size() > 0;
22}
23
24bool CTextSearch::Search(const std::string &strHaystack) const
25{
26 if (strHaystack.empty() || !IsValid())
27 return false;
28
29 std::string strSearch(strHaystack);
30 if (!m_bCaseSensitive)
31 StringUtils::ToLower(strSearch);
32
33 /* check whether any of the NOT terms matches and return false if there's a match */
34 for (unsigned int iNotPtr = 0; iNotPtr < m_NOT.size(); iNotPtr++)
35 {
36 if (strSearch.find(m_NOT.at(iNotPtr)) != std::string::npos)
37 return false;
38 }
39
40 /* check whether at least one of the OR terms matches and return false if there's no match found */
41 bool bFound(m_OR.empty());
42 for (unsigned int iOrPtr = 0; iOrPtr < m_OR.size(); iOrPtr++)
43 {
44 if (strSearch.find(m_OR.at(iOrPtr)) != std::string::npos)
45 {
46 bFound = true;
47 break;
48 }
49 }
50 if (!bFound)
51 return false;
52
53 /* check whether all of the AND terms match and return false if one of them wasn't found */
54 for (unsigned int iAndPtr = 0; iAndPtr < m_AND.size(); iAndPtr++)
55 {
56 if (strSearch.find(m_AND[iAndPtr]) == std::string::npos)
57 return false;
58 }
59
60 /* all ok, return true */
61 return true;
62}
63
64void CTextSearch::GetAndCutNextTerm(std::string &strSearchTerm, std::string &strNextTerm)
65{
66 std::string strFindNext(" ");
67
68 if (StringUtils::EndsWith(strSearchTerm, "\""))
69 {
70 strSearchTerm.erase(0, 1);
71 strFindNext = "\"";
72 }
73
74 size_t iNextPos = strSearchTerm.find(strFindNext);
75 if (iNextPos != std::string::npos)
76 {
77 strNextTerm = strSearchTerm.substr(0, iNextPos);
78 strSearchTerm.erase(0, iNextPos + 1);
79 }
80 else
81 {
82 strNextTerm = strSearchTerm;
83 strSearchTerm.clear();
84 }
85}
86
87void CTextSearch::ExtractSearchTerms(const std::string &strSearchTerm, TextSearchDefault defaultSearchMode)
88{
89 std::string strParsedSearchTerm(strSearchTerm);
90 StringUtils::Trim(strParsedSearchTerm);
91
92 if (!m_bCaseSensitive)
93 StringUtils::ToLower(strParsedSearchTerm);
94
95 bool bNextAND(defaultSearchMode == SEARCH_DEFAULT_AND);
96 bool bNextOR(defaultSearchMode == SEARCH_DEFAULT_OR);
97 bool bNextNOT(defaultSearchMode == SEARCH_DEFAULT_NOT);
98
99 while (strParsedSearchTerm.length() > 0)
100 {
101 StringUtils::TrimLeft(strParsedSearchTerm);
102
103 if (StringUtils::StartsWith(strParsedSearchTerm, "!") || StringUtils::StartsWithNoCase(strParsedSearchTerm, "not"))
104 {
105 std::string strDummy;
106 GetAndCutNextTerm(strParsedSearchTerm, strDummy);
107 bNextNOT = true;
108 }
109 else if (StringUtils::StartsWith(strParsedSearchTerm, "+") || StringUtils::StartsWithNoCase(strParsedSearchTerm, "and"))
110 {
111 std::string strDummy;
112 GetAndCutNextTerm(strParsedSearchTerm, strDummy);
113 bNextAND = true;
114 }
115 else if (StringUtils::StartsWith(strParsedSearchTerm, "|") || StringUtils::StartsWithNoCase(strParsedSearchTerm, "or"))
116 {
117 std::string strDummy;
118 GetAndCutNextTerm(strParsedSearchTerm, strDummy);
119 bNextOR = true;
120 }
121 else
122 {
123 std::string strTerm;
124 GetAndCutNextTerm(strParsedSearchTerm, strTerm);
125 if (strTerm.length() > 0)
126 {
127 if (bNextAND)
128 m_AND.push_back(strTerm);
129 else if (bNextOR)
130 m_OR.push_back(strTerm);
131 else if (bNextNOT)
132 m_NOT.push_back(strTerm);
133 }
134 else
135 {
136 break;
137 }
138
139 bNextAND = (defaultSearchMode == SEARCH_DEFAULT_AND);
140 bNextOR = (defaultSearchMode == SEARCH_DEFAULT_OR);
141 bNextNOT = (defaultSearchMode == SEARCH_DEFAULT_NOT);
142 }
143
144 StringUtils::TrimLeft(strParsedSearchTerm);
145 }
146}