1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <deque>
17 #include <vector>
18 #include "callbacks.h"
19 #include "contexts_trie.h"
20
StringSplit(std::string paraName,std::string split=".")21 static std::vector<std::string> StringSplit(std::string paraName, std::string split = ".")
22 {
23 size_t pos;
24 std::vector<std::string> result;
25 while ((pos = paraName.find(split)) != std::string::npos) {
26 std::string element = paraName.substr(0, pos);
27 if (!element.empty()) {
28 result.push_back(element);
29 }
30 paraName.erase(0, pos + split.length());
31 }
32 if (!paraName.empty()) {
33 result.push_back(paraName);
34 }
35 return result;
36 }
37
GetFirstElement(std::string & paraName,std::string split=".")38 static std::string GetFirstElement(std::string ¶Name, std::string split = ".")
39 {
40 size_t pos;
41 if ((pos = paraName.find(split)) != std::string::npos) {
42 std::string element = paraName.substr(0, pos);
43 paraName.erase(0, pos + split.length());
44 if (!element.empty()) {
45 return element;
46 }
47 }
48 std::string result = paraName;
49 paraName = "";
50 return result;
51 }
52
FindChild(std::string element)53 ParamContextsTrie *ParamContextsTrie::FindChild(std::string element)
54 {
55 ParamContextsTrie *root = this;
56 auto iter = root->childen.find(element);
57 if (iter != root->childen.end()) {
58 return iter->second;
59 }
60 return nullptr;
61 }
62
Insert(const std::string & paramPrefix,const std::string & contexts)63 bool ParamContextsTrie::Insert(const std::string ¶mPrefix, const std::string &contexts)
64 {
65 ParamContextsTrie *root = this;
66 std::vector<std::string> elements = StringSplit(paramPrefix);
67 for (const auto &element : elements) {
68 if (root->childen[element] == nullptr) {
69 root->childen[element] = new (std::nothrow) ParamContextsTrie();
70 if (root->childen[element] == nullptr) {
71 return false;
72 }
73 }
74 root = root->childen[element];
75 }
76 if (paramPrefix.back() == '.') {
77 root->prefixLabel = contexts;
78 } else {
79 root->matchLabel = contexts;
80 }
81 return true;
82 }
83
Search(const std::string & paraName,char ** context)84 bool ParamContextsTrie::Search(const std::string ¶Name, char **context)
85 {
86 ParamContextsTrie *root = this;
87 std::string tmpString = paraName;
88 std::string element = GetFirstElement(tmpString);
89 const char *updataCurLabel = "";
90 while (!element.empty()) {
91 auto child = root->FindChild(element);
92 if (child == nullptr) {
93 if (!root->prefixLabel.empty()) {
94 *context = strdup(root->prefixLabel.c_str());
95 return true;
96 } else if (strcmp(updataCurLabel, "")) {
97 *context = strdup(updataCurLabel);
98 return true;
99 } else {
100 return false;
101 }
102 }
103 if (!root->prefixLabel.empty())
104 updataCurLabel = root->prefixLabel.c_str();
105 root = child;
106 element = GetFirstElement(tmpString);
107 }
108
109 if (!root->matchLabel.empty()) {
110 *context = strdup(root->matchLabel.c_str());
111 return true;
112 } else if (strcmp(updataCurLabel, "")) {
113 *context = strdup(updataCurLabel);
114 return true;
115 } else {
116 return false;
117 }
118 }
119
Clear()120 void ParamContextsTrie::Clear()
121 {
122 ParamContextsTrie *root = this;
123 std::deque<ParamContextsTrie *> nodeDeque;
124 for (auto child : root->childen) {
125 nodeDeque.emplace_back(child.second);
126 }
127 while (!nodeDeque.empty()) {
128 root = nodeDeque.front();
129 nodeDeque.pop_front();
130 if (root != nullptr) {
131 for (auto child : root->childen) {
132 nodeDeque.emplace_back(child.second);
133 }
134 delete root;
135 }
136 }
137 }
138