[Apps Common] Merged generic SearchProvider from Memo. 21/90121/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Tue, 27 Sep 2016 08:15:39 +0000 (11:15 +0300)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Wed, 28 Sep 2016 10:48:48 +0000 (13:48 +0300)
Change-Id: Icb11cc33372a450ad9192bbbd6d62b0b6b92d438
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
lib-apps-common/inc/Model2/SearchData.h [new file with mode: 0644]
lib-apps-common/inc/Model2/SearchEngine.h [new file with mode: 0644]
lib-apps-common/inc/Model2/SearchProvider.h [new file with mode: 0644]
lib-apps-common/inc/Model2/SearchResult.h [new file with mode: 0644]
lib-apps-common/src/Model2/SearchData.cpp [new file with mode: 0644]
lib-apps-common/src/Model2/SearchEngine.cpp [new file with mode: 0644]
lib-apps-common/src/Model2/SearchProvider.cpp [new file with mode: 0644]
lib-apps-common/src/Model2/SearchResult.cpp [new file with mode: 0644]

diff --git a/lib-apps-common/inc/Model2/SearchData.h b/lib-apps-common/inc/Model2/SearchData.h
new file mode 100644 (file)
index 0000000..64b2f58
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef MODEL_SEARCH_DATA_H
+#define MODEL_SEARCH_DATA_H
+
+#include "Model2/DataItem.h"
+#include "Model2/SearchResult.h"
+
+namespace Model2
+{
+       class EXPORT_API SearchData : public DataItem
+       {
+       public:
+               /**
+                * @brief Called when SearchResult is changed.
+                * @param[in]   Search result
+                */
+               typedef std::function<void(const SearchResult *)> ChangeCallback;
+
+               /**
+                * @brief Create SearchData object.
+                * @param[in]   dataItem     Data item reference
+                */
+               explicit SearchData(DataItem &dataItem);
+
+               /**
+                * @return DataItem reference.
+                */
+               DataItem &getDataItem();
+
+               /**
+                * @return DataItem reference.
+                */
+               const DataItem &getDataItem() const;
+
+               /**
+                * @return Search result.
+                */
+               const SearchResult *getSearchResult() const;
+
+               /**
+                * @brief Set search result.
+                * @param[in]   searchResult    Search result
+                */
+               void setSearchResult(SearchResult *searchResult);
+
+               /**
+                * @brief Set change callback.
+                * @param[in]   callback    @see ChangeCallback
+                */
+               void setChangeCallback(ChangeCallback callback);
+
+       protected:
+               virtual int onUpdate(void *data) override;
+
+       private:
+               DataItem &m_DataItem;
+               SearchResult *m_SearchResult;
+               ChangeCallback m_OnChanged;
+       };
+}
+
+#endif /* MODEL_SEARCH_DATA_H */
diff --git a/lib-apps-common/inc/Model2/SearchEngine.h b/lib-apps-common/inc/Model2/SearchEngine.h
new file mode 100644 (file)
index 0000000..44821c2
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef MODEL_SEARCH_ENGINE_H
+#define MODEL_SEARCH_ENGINE_H
+
+#include "Model2/SearchResult.h"
+#include "Model2/DataProvider.h"
+
+#include <string>
+#include <vector>
+
+namespace Model2
+{
+       class SearchData;
+
+       /**
+        * @brief This is a callable object which provides match logic
+        * @param[in]   Search data
+        * @param[in]   Query
+        * @return Search result
+        */
+       typedef std::function<SearchResultPtr(const SearchData &, const std::string &)> SearchComparator;
+
+       /**
+        * @brief This class provides incremental search logic
+        */
+       class EXPORT_API SearchEngine
+       {
+       public:
+               typedef DataProvider::DataList DataList;
+
+               /**
+                * @brief Create search engine
+                * @param[in]   dataList    ContactData list
+                * @param[in]   comparator  Callable match comparator
+                */
+               explicit SearchEngine(const DataList &dataList, SearchComparator comparator);
+
+               /**
+                * @brief Perform incremental search
+                * @param[in]   query   Value to find
+                */
+               void search(std::string query);
+
+               /**
+                * @return true if there is no results, otherwise false
+                */
+               bool empty() const;
+
+               /**@{*/
+               /**
+                * @brief Notify engine that SearchData was Inserted/Updated/Deleted
+                * @param[in]   searchData  SearchData object
+                */
+               void insertSearchData(SearchData *searchData);
+               void updateSearchData(SearchData *searchData);
+               void deleteSearchData(SearchData *searchData);
+               /**@}*/
+
+       private:
+               typedef std::pair<SearchData *, SearchResultPtr> SearchResultItem;
+               typedef std::list<SearchResultItem> ResultList;
+               typedef std::vector<ResultList> SearchHistory;
+               typedef std::function<bool(const std::string &, ResultList &)> HistoryForFn;
+
+               bool needSearch(const std::string &query);
+               template <typename List>
+               void incrementalSearch(const List &list, const std::string &query);
+
+               SearchData *getSearchData(const DataItemPtr &data);
+               SearchData *getSearchData(const SearchResultItem &searchItem);
+
+               void updateSearchResult(ResultList &list);
+               void resetSearchResult();
+               void clear();
+
+               SearchHistory::iterator getMatch(const std::string &query);
+               SearchHistory::iterator skipEmptyResults(size_t offset);
+
+               void historyFor(HistoryForFn function);
+               static ResultList::iterator findSearchData(ResultList &list, SearchData *searchData);
+
+               std::string m_Query;
+               SearchHistory m_History;
+               int m_LastFoundIndex;
+
+               const DataList &m_DataList;
+
+               SearchComparator m_Comparator;
+       };
+}
+
+#endif /* MODEL_SEARCH_ENGINE_H */
diff --git a/lib-apps-common/inc/Model2/SearchProvider.h b/lib-apps-common/inc/Model2/SearchProvider.h
new file mode 100644 (file)
index 0000000..a81e076
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef MODEL_SEARCH_PROVIDER_H
+#define MODEL_SEARCH_PROVIDER_H
+
+#include "Model2/SearchEngine.h"
+#include "Model2/DataProvider.h"
+
+namespace Model2
+{
+       class SearchData;
+
+       class EXPORT_API SearchProvider : public DataProvider
+       {
+       public:
+
+               /**
+                * @brief Create SearchProvider
+                * @param[in]   provider    DataProvider
+                * @param[in]   comparator  Callable match comparator
+                */
+               explicit SearchProvider(DataProvider &provider, SearchComparator comparator);
+               virtual ~SearchProvider() override;
+
+               /**
+                * @brief Invoke search
+                * @param[in]   query   Passed search string
+                */
+               void search(const char *query);
+
+               /**
+                * @return Whether there is no results for the current query.
+                */
+               bool empty() const;
+
+       private:
+               virtual void onInitialize() override;
+
+               SearchData *createSearchData(DataItem &dataItem);
+               void onInserted(DataItem &dataItem);
+               void onUpdated(SearchData &searchData, int changes);
+               void onDeleted(SearchData &searchData);
+
+               DataProvider &m_Provider;
+               SearchEngine m_SearchEngine;
+       };
+}
+
+#endif /* MODEL_SEARCH_PROVIDER_H */
diff --git a/lib-apps-common/inc/Model2/SearchResult.h b/lib-apps-common/inc/Model2/SearchResult.h
new file mode 100644 (file)
index 0000000..b6d825b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef MODEL_SEARCH_RESULT_H
+#define MODEL_SEARCH_RESULT_H
+
+#include <memory>
+#include <tizen.h>
+#include "Utils/Range.h"
+
+namespace Model2
+{
+       class EXPORT_API SearchResult
+       {
+       public:
+               /**
+                * @brief Represents substring of matched string.
+                */
+               typedef Utils::Range<const char *> Substring;
+
+               SearchResult();
+
+               /**
+                * @brief Create SearchResult object.
+                * @param[in]   fieldId   Field ID matched with query
+                * @param[in]   str       Matched string
+                * @param[in]   substr    Matched substring
+                */
+               SearchResult(int fieldId, const char *str, Substring substr);
+
+               /**
+                * @return Field ID matched with query.
+                */
+               int getMatchedField() const;
+
+               /**
+                * @return Matched string.
+                */
+               const char *getMatchedString() const;
+
+               /**
+                * @return Matched substring.
+                */
+               const Substring &getMatchedSubstring() const;
+
+       private:
+               int m_MatchedField;
+               const char *m_MatchedString;
+               Substring m_MatchedSubstring;
+       };
+
+       typedef std::unique_ptr<SearchResult> SearchResultPtr;
+}
+
+#endif /* MODEL_SEARCH_RESULT_H */
diff --git a/lib-apps-common/src/Model2/SearchData.cpp b/lib-apps-common/src/Model2/SearchData.cpp
new file mode 100644 (file)
index 0000000..f22a877
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Model2/SearchData.h"
+
+using namespace Model2;
+
+SearchData::SearchData(DataItem &dataItem)
+       : m_DataItem(dataItem),
+         m_SearchResult(nullptr)
+{
+}
+
+DataItem &SearchData::getDataItem()
+{
+       return m_DataItem;
+}
+
+const DataItem &SearchData::getDataItem() const
+{
+       return m_DataItem;
+}
+
+const SearchResult *SearchData::getSearchResult() const
+{
+       return m_SearchResult;
+}
+
+void SearchData::setSearchResult(SearchResult *searchResult)
+{
+       m_SearchResult = searchResult;
+
+       if (m_OnChanged) {
+               m_OnChanged(m_SearchResult);
+       }
+}
+
+void SearchData::setChangeCallback(ChangeCallback callback)
+{
+       m_OnChanged = std::move(callback);
+}
+
+int SearchData::onUpdate(void *data)
+{
+       return (long) data;
+}
diff --git a/lib-apps-common/src/Model2/SearchEngine.cpp b/lib-apps-common/src/Model2/SearchEngine.cpp
new file mode 100644 (file)
index 0000000..8e78092
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Model2/SearchEngine.h"
+#include "Model2/SearchData.h"
+
+#include <utility>
+#include <algorithm>
+
+using namespace Model2;
+using namespace std::placeholders;
+
+SearchEngine::SearchEngine(const DataList &dataList, SearchComparator comparator)
+       : m_LastFoundIndex(-1),
+         m_DataList(dataList),
+         m_Comparator(std::move(comparator))
+{
+}
+
+void SearchEngine::search(std::string query)
+{
+       if (query.empty()) {
+               clear();
+               if (!m_Query.empty()) {
+                       resetSearchResult();
+               }
+       } else {
+               if (!needSearch(query)) {
+                       return;
+               }
+
+               auto matchIt = getMatch(query);
+               size_t matchPos = matchIt - m_History.begin();
+               bool nothingFound = matchIt == m_History.end();
+
+               m_History.erase(nothingFound ? m_History.begin() : (matchIt + 1), m_History.end());
+               m_History.resize(query.size());
+
+               if (m_Query.empty() || nothingFound) {
+                       incrementalSearch(m_DataList, query);
+               } else if (matchPos == m_History.size()) {
+                       updateSearchResult(m_History.back());
+               } else {
+                       incrementalSearch(m_History[matchPos], query);
+               }
+       }
+
+       m_Query = std::move(query);
+}
+
+bool SearchEngine::empty() const
+{
+       return m_History.empty() || m_History.back().empty();
+}
+
+void SearchEngine::insertSearchData(SearchData *searchData)
+{
+       SearchResult *lastResult = nullptr;
+
+       historyFor([searchData, &lastResult, this](const std::string &query, ResultList &list) {
+               SearchResultPtr searchResult = m_Comparator(*searchData, query);
+               lastResult = searchResult.get();
+
+               if (searchResult) {
+                       list.emplace_back(searchData, std::move(searchResult));
+                       return true;
+               }
+
+               return false;
+       });
+
+       searchData->setSearchResult(lastResult);
+}
+
+void SearchEngine::updateSearchData(SearchData *searchData)
+{
+       SearchResult *lastResult = nullptr;
+
+       historyFor([searchData, &lastResult, this](const std::string &query, ResultList &list) {
+               auto it = findSearchData(list, searchData);
+               if (it != list.end()) {
+                       SearchResultPtr searchResult = m_Comparator(*searchData, query);
+                       lastResult = searchResult.get();
+
+                       if (searchResult) {
+                               it->second = std::move(searchResult);
+                       } else {
+                               list.erase(it);
+                       }
+               }
+
+               return true;
+       });
+
+       searchData->setSearchResult(lastResult);
+}
+
+void SearchEngine::deleteSearchData(SearchData *searchData)
+{
+       for (auto &&list : m_History) {
+               auto it = findSearchData(list, searchData);
+               if (it != list.end()) {
+                       list.erase(it);
+               }
+       }
+}
+
+bool SearchEngine::needSearch(const std::string &query)
+{
+       if (query.size() >= m_Query.size()
+               &&(int)(m_History.size() - 1) > m_LastFoundIndex) {
+               return false;
+       }
+
+       return true;
+}
+
+template <typename List>
+void SearchEngine::incrementalSearch(const List &list, const std::string &query)
+{
+       ResultList resultList;
+       for (auto &&data : list) {
+               SearchData *searchData = getSearchData(data);
+               SearchResultPtr searchResult = m_Comparator(*searchData, query);
+               searchData->setSearchResult(searchResult.get());
+
+               if (searchResult) {
+                       resultList.emplace_back(searchData, std::move(searchResult));
+               }
+       }
+
+       if (!resultList.empty()) {
+               m_LastFoundIndex = m_History.size() - 1;
+               m_History.back() = std::move(resultList);
+       }
+}
+
+SearchData *SearchEngine::getSearchData(const DataItemPtr &data)
+{
+       return static_cast<SearchData *>(data.get());
+}
+
+SearchData *SearchEngine::getSearchData(const SearchResultItem &resultItem)
+{
+       return resultItem.first;
+}
+
+void SearchEngine::updateSearchResult(ResultList &list)
+{
+       for (auto &&resultItem : list) {
+               resultItem.first->setSearchResult(resultItem.second.get());
+       }
+}
+
+void SearchEngine::resetSearchResult()
+{
+       for (auto &&data : m_DataList) {
+               SearchData *searchData = static_cast<SearchData *>(data.get());
+               searchData->setSearchResult(nullptr);
+       }
+}
+
+void SearchEngine::clear()
+{
+       m_History.clear();
+       m_LastFoundIndex = -1;
+}
+
+SearchEngine::SearchHistory::iterator SearchEngine::getMatch(const std::string &query)
+{
+       size_t minSize = std::min(m_Query.size(), query.size());
+       auto itPair = std::mismatch(m_Query.begin(), m_Query.begin() + minSize, query.begin());
+
+       return skipEmptyResults(itPair.first - m_Query.begin());
+}
+
+SearchEngine::SearchHistory::iterator SearchEngine::skipEmptyResults(size_t offset)
+{
+       auto rIt = std::reverse_iterator<SearchHistory::iterator>(m_History.begin() + offset);
+
+       while (rIt != m_History.rend() && rIt->empty()) {
+               ++rIt;
+       }
+
+       return rIt == m_History.rend() ? m_History.end() : rIt.base() - 1;
+}
+
+void SearchEngine::historyFor(HistoryForFn function)
+{
+       std::string query;
+       query.reserve(m_Query.size());
+
+       for (size_t i = 0; i < m_History.size(); ++i) {
+               auto &list = m_History[i];
+               query.append(1, m_Query[i]);
+
+               if ((int) i < m_LastFoundIndex && list.empty()) {
+                       continue;
+               }
+
+               if (!function(query, list)) {
+                       break;
+               }
+       }
+}
+
+SearchEngine::ResultList::iterator SearchEngine::findSearchData(ResultList &list, SearchData *searchData)
+{
+       return std::find_if(list.begin(), list.end(),
+                       [searchData](const SearchResultItem &item) {
+                               return item.first == searchData;
+                       });
+}
diff --git a/lib-apps-common/src/Model2/SearchProvider.cpp b/lib-apps-common/src/Model2/SearchProvider.cpp
new file mode 100644 (file)
index 0000000..5d69e7e
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Model2/SearchProvider.h"
+#include "Model2/SearchData.h"
+
+using namespace Model2;
+using namespace std::placeholders;
+
+SearchProvider::SearchProvider(DataProvider &provider, SearchComparator comparator)
+       : m_Provider(provider), m_SearchEngine(getDataList(), std::move(comparator))
+{
+       m_Provider.setInsertCallback(std::bind(&SearchProvider::onInserted, this, _1));
+       m_Provider.setUpdateStartCallback(std::bind(&SearchProvider::onUpdateStarted, this));
+       m_Provider.setUpdateFinishCallback(std::bind(&SearchProvider::onUpdateFinished, this));
+}
+
+SearchProvider::~SearchProvider()
+{
+       m_Provider.setInsertCallback(nullptr);
+       m_Provider.setUpdateStartCallback(nullptr);
+       m_Provider.setUpdateFinishCallback(nullptr);
+}
+
+void SearchProvider::search(const char *query)
+{
+       m_SearchEngine.search(query ? query : "");
+}
+
+bool SearchProvider::empty() const
+{
+       return m_SearchEngine.empty();
+}
+
+void SearchProvider::onInitialize()
+{
+       m_Provider.initialize([this] {
+               DataList dataList;
+               for (auto &&dataItem : m_Provider.getDataList()) {
+                       dataList.push_back(DataItemPtr(createSearchData(*dataItem)));
+               }
+
+               onInitialized(std::move(dataList));
+       });
+}
+
+SearchData *SearchProvider::createSearchData(DataItem &dataItem)
+{
+       auto searchData = new SearchData(dataItem);
+       dataItem.setUpdateCallback(std::bind(&SearchProvider::onUpdated, this, std::ref(*searchData), _1));
+       dataItem.setDeleteCallback(std::bind(&SearchProvider::onDeleted, this, std::ref(*searchData)));
+       return searchData;
+}
+
+void SearchProvider::onInserted(DataItem &dataItem)
+{
+       SearchData *searchData = createSearchData(dataItem);
+       insertDataItem(DataItemPtr(searchData));
+       m_SearchEngine.insertSearchData(searchData);
+}
+
+void SearchProvider::onUpdated(SearchData &searchData, int changes)
+{
+       searchData.update((void *)(long) changes);
+       m_SearchEngine.updateSearchData(&searchData);
+}
+
+void SearchProvider::onDeleted(SearchData &searchData)
+{
+       m_SearchEngine.deleteSearchData(&searchData);
+       deleteDataItem(searchData);
+}
diff --git a/lib-apps-common/src/Model2/SearchResult.cpp b/lib-apps-common/src/Model2/SearchResult.cpp
new file mode 100644 (file)
index 0000000..115786b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Model2/SearchResult.h"
+
+using namespace Model2;
+
+SearchResult::SearchResult()
+       : m_MatchedField(-1),
+         m_MatchedString(nullptr)
+{
+}
+
+SearchResult::SearchResult(int fieldId, const char *str, Substring substr)
+       : m_MatchedField(fieldId),
+         m_MatchedString(str),
+         m_MatchedSubstring(substr)
+{
+}
+
+int SearchResult::getMatchedField() const
+{
+       return m_MatchedField;
+}
+
+const char *SearchResult::getMatchedString() const
+{
+       return m_MatchedString;
+}
+
+const SearchResult::Substring &SearchResult::getMatchedSubstring() const
+{
+       return m_MatchedSubstring;
+}