• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "flat_json_parser.h"
17 
18 #include <algorithm>
19 #include <sstream>
20 
21 namespace OHOS {
22 namespace HiviewDFX {
23 namespace {
24     struct Initializer {
InitializerOHOS::HiviewDFX::__anon78d3ba1f0111::Initializer25         Initializer()
26         {
27             FlatJsonParser::Initialize();
28         }
29     };
30 }
31 
32 uint8_t FlatJsonParser::charFilter_[FlatJsonParser::CHAR_RANGE] { 0 };
33 
AppendStringValue(const std::string & key,const std::string & value)34 void FlatJsonParser::AppendStringValue(const std::string& key, const std::string& value)
35 {
36     if (std::any_of(kvList_.begin(), kvList_.end(), [&key] (auto& item) {
37         return item.first == key;
38     })) {
39         return;
40     }
41     kvList_.emplace_back(key, "\"" + value + "\"");
42 }
43 
AppendUInt64Value(const std::string & key,const uint64_t value)44 void FlatJsonParser::AppendUInt64Value(const std::string& key, const uint64_t value)
45 {
46     if (std::any_of(kvList_.begin(), kvList_.end(), [&key] (auto& item) {
47         return item.first == key;
48     })) {
49         return;
50     }
51     std::ostringstream os;
52     os << value;
53     kvList_.emplace_back(key, os.str());
54     os.clear();
55 }
56 
Initialize()57 void FlatJsonParser::Initialize()
58 {
59     for (char c = '0'; c <= '9'; c++) {
60         charFilter_[static_cast<uint8_t>(c)] = NUMBER_FLAG;
61     }
62     charFilter_[static_cast<uint8_t>('-')] = NUMBER_FLAG;
63     charFilter_[static_cast<uint8_t>('+')] = NUMBER_FLAG;
64     charFilter_[static_cast<uint8_t>('.')] = NUMBER_FLAG;
65     charFilter_[static_cast<uint8_t>('"')] = STRING_FLAG;
66     charFilter_[static_cast<uint8_t>('{')] = BRACKET_FLAG;
67     charFilter_[static_cast<uint8_t>('[')] = BRACKET_FLAG;
68 }
69 
FlatJsonParser(const std::string & jsonStr)70 FlatJsonParser::FlatJsonParser(const std::string& jsonStr)
71 {
72     static Initializer initialize;
73     Parse(jsonStr);
74 }
75 
Parse(const std::string & jsonStr)76 void FlatJsonParser::Parse(const std::string& jsonStr)
77 {
78     index_ = 0;
79     kvList_.clear();
80     while (index_ < jsonStr.length()) {
81         if (charFilter_[static_cast<uint8_t>(jsonStr[index_])] != STRING_FLAG) {
82             ++index_;
83             continue;
84         }
85         std::string key = ParseKey(jsonStr);
86         std::string val = ParseValue(jsonStr);
87         kvList_.emplace_back(key, val);
88     }
89 }
90 
Print()91 std::string FlatJsonParser::Print()
92 {
93     std::string jsonStr = "{";
94     if (!kvList_.empty()) {
95         for (size_t i = 0; i < kvList_.size() - 1; i++) {
96             jsonStr += "\"" + kvList_[i].first + "\":" + kvList_[i].second + ",";
97         }
98         jsonStr += "\"" + kvList_.back().first + "\":" + kvList_.back().second;
99     }
100     jsonStr += "}";
101     return jsonStr;
102 }
103 
ParseKey(const std::string & jsonStr)104 std::string FlatJsonParser::ParseKey(const std::string& jsonStr)
105 {
106     std::string key;
107     ++index_; // eat left quotation
108     while (index_ < jsonStr.length()) {
109         if (charFilter_[static_cast<uint8_t>(jsonStr[index_])] == STRING_FLAG) {
110             break;
111         }
112         key.push_back(jsonStr[index_]);
113         ++index_;
114     }
115     ++index_; // eat right quotation
116     return key;
117 }
118 
ParseValue(const std::string & jsonStr)119 std::string FlatJsonParser::ParseValue(const std::string& jsonStr)
120 {
121     std::string value;
122     bool valueParsed = false;
123     while (index_ < jsonStr.length()) {
124         int charCode = static_cast<uint8_t>(jsonStr[index_]);
125         switch (charFilter_[charCode]) {
126             case BRACKET_FLAG:
127                 value = ParseBrackets(jsonStr, jsonStr[index_]);
128                 valueParsed = true;
129                 break;
130             case NUMBER_FLAG:
131                 value = ParseNumer(jsonStr);
132                 valueParsed = true;
133                 break;
134             case STRING_FLAG:
135                 value = ParseString(jsonStr);
136                 valueParsed = true;
137                 break;
138             default:
139                 ++index_;
140                 valueParsed = false;
141                 break;
142         }
143         if (valueParsed) {
144             break;
145         }
146     }
147     return value;
148 }
149 
ParseNumer(const std::string & jsonStr)150 std::string FlatJsonParser::ParseNumer(const std::string& jsonStr)
151 {
152     std::string number;
153     while (index_ < jsonStr.length()) {
154         if (charFilter_[static_cast<uint8_t>(jsonStr[index_])] != NUMBER_FLAG) {
155             break;
156         }
157         number.push_back(jsonStr[index_]);
158         ++index_;
159     }
160     return number;
161 }
162 
ParseString(const std::string & jsonStr)163 std::string FlatJsonParser::ParseString(const std::string& jsonStr)
164 {
165     std::string txt;
166     txt.push_back(jsonStr[index_++]);
167     while (index_ < jsonStr.length()) {
168         if (charFilter_[static_cast<uint8_t>(jsonStr[index_])] == STRING_FLAG &&
169             jsonStr[index_ - 1] != '\\') {
170             break;
171         }
172         txt.push_back(jsonStr[index_]);
173         ++index_;
174     }
175     txt.push_back(jsonStr[index_++]);
176     return txt;
177 }
178 
ParseBrackets(const std::string & jsonStr,char leftBracket)179 std::string FlatJsonParser::ParseBrackets(const std::string& jsonStr, char leftBracket)
180 {
181     std::string val;
182     char rightBracket = leftBracket + 2; // 2: '[' + 2 = ']', '{' + 2 = '}'
183     int counter = 1;
184     val.push_back(jsonStr[index_++]);
185     while (index_ < jsonStr.length()) {
186         if (jsonStr[index_] == leftBracket) {
187             ++counter;
188         } else if (jsonStr[index_] == rightBracket) {
189             --counter;
190             if (counter == 0) {
191                 break;
192             }
193         }
194         val.push_back(jsonStr[index_++]);
195     }
196     val.push_back(jsonStr[index_++]);
197     return val;
198 }
199 } // namespace HiviewDFX
200 } // namespace OHOS
201