1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "hidl_test"
18 
19 #include "Trie.h"
20 #include <android-base/logging.h>
21 #include <inttypes.h>
22 #include <string>
23 
24 namespace android {
25 namespace hardware {
26 namespace tests {
27 namespace trie {
28 namespace V1_0 {
29 namespace implementation {
30 
31 // Methods from ::android::hardware::tests::trie::V1_0::ITrie follow.
newTrie(newTrie_cb _hidl_cb)32 Return<void> Trie::newTrie(newTrie_cb _hidl_cb) {
33     LOG(INFO) << "SERVER(Trie) newTrie()";
34 
35     TrieNode ret;
36     ret.isTerminal = false;
37     _hidl_cb(ret);
38     return Void();
39 }
40 
addStrings(const TrieNode & trie,const hidl_vec<hidl_string> & strings,addStrings_cb _hidl_cb)41 Return<void> Trie::addStrings(const TrieNode& trie, const hidl_vec<hidl_string>& strings,
42                               addStrings_cb _hidl_cb) {
43     LOG(INFO) << "SERVER(Trie) addStrings(trie, " << strings.size() << " strings)";
44 
45     // Make trie modifiable.
46     TrieNode newTrie = trie;
47 
48     for (const auto& str : strings) {
49         addString(&newTrie, str);
50     }
51     _hidl_cb(newTrie);
52     return Void();
53 }
54 
containsStrings(const TrieNode & trie,const hidl_vec<hidl_string> & strings,containsStrings_cb _hidl_cb)55 Return<void> Trie::containsStrings(const TrieNode& trie, const hidl_vec<hidl_string>& strings,
56                                    containsStrings_cb _hidl_cb) {
57     LOG(INFO) << "SERVER(Trie) containsStrings(trie, " << strings.size() << " strings)";
58 
59     std::vector<bool> ret(strings.size());
60     for (size_t i = 0; i != strings.size(); ++i) {
61         ret[i] = containsString(&trie, strings[i]);
62     }
63     _hidl_cb(ret);
64     return Void();
65 }
66 
addString(TrieNode * trieRoot,const std::string & str)67 void Trie::addString(TrieNode* trieRoot, const std::string& str) {
68     TrieNode* currNode = trieRoot;
69 
70     for (char ch : str) {
71         auto& vec = currNode->next;
72 
73         auto it = std::find_if(vec.begin(), vec.end(),
74                                [&](const TrieEdge& edge) { return ch == edge.character; });
75 
76         if (it == vec.end()) {
77             vec.resize(vec.size() + 1);
78             it = vec.end() - 1;
79             it->character = ch;
80             it->node.isTerminal = false;
81         }
82 
83         currNode = &(it->node);
84     }
85 
86     currNode->isTerminal = true;
87 }
88 
containsString(const TrieNode * trieRoot,const std::string & str)89 bool Trie::containsString(const TrieNode* trieRoot, const std::string& str) {
90     const TrieNode* currNode = trieRoot;
91 
92     for (char ch : str) {
93         const auto& vec = currNode->next;
94 
95         auto it = std::find_if(vec.begin(), vec.end(),
96                                [&](const TrieEdge& edge) { return ch == edge.character; });
97 
98         if (it == vec.end()) return false;
99         currNode = &(it->node);
100     }
101 
102     return currNode->isTerminal;
103 }
104 
HIDL_FETCH_ITrie(const char *)105 ITrie* HIDL_FETCH_ITrie(const char* /* name */) {
106     return new Trie();
107 }
108 
109 }  // namespace implementation
110 }  // namespace V1_0
111 }  // namespace trie
112 }  // namespace tests
113 }  // namespace hardware
114 }  // namespace android
115