• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &paraName, 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 &paramPrefix, 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 &paraName, 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