• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "encoded/raw_data_builder_json_parser.h"
17 
18 #include <cinttypes>
19 #include <functional>
20 #include <sstream>
21 #include <vector>
22 #include <unordered_map>
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace EventRaw {
27 namespace {
28 constexpr int NUM_MIN_CHAR = static_cast<int>('0');
29 constexpr int NUM_MAX_CHAR = static_cast<int>('9');
30 constexpr int DOUBLE_QUOTA_CHAR = static_cast<int>('"');
31 constexpr int COLON_CHAR = static_cast<int>(':');
32 constexpr int POINT_CHAR = static_cast<int>('.');
33 constexpr int COMMA_CHAR = static_cast<int>(',');
34 constexpr int LEFT_BRACE_CHAR = static_cast<int>('{');
35 constexpr int RIGHT_BRACE_CHAR = static_cast<int>('}');
36 constexpr int LEFT_BRACKET_CHAR = static_cast<int>('[');
37 constexpr int RIGHT_BRACKET_CHAR = static_cast<int>(']');
38 constexpr int MINUS_CHAR = static_cast<int>('-');
39 constexpr int ESCAPE_CHAR = static_cast<int>('\\');
40 constexpr int POSITIVE_CHAR = static_cast<int>('+');
41 constexpr int SICENTIFIC_NOTAITION_CHAR = static_cast<int>('e');
42 
43 template<typename T>
TransStrToType(const std::string & str,T & val)44 static void TransStrToType(const std::string& str, T& val)
45 {
46     std::stringstream ss(str);
47     ss >> val;
48 }
49 }
50 
RawDataBuilderJsonParser(const std::string & jsonStr)51 RawDataBuilderJsonParser::RawDataBuilderJsonParser(const std::string& jsonStr)
52 {
53     jsonStr_ = jsonStr;
54     builder_ = std::make_shared<RawDataBuilder>();
55     InitNoneStatus();
56     InitRunStatus();
57     InitKeyParseStatus();
58     InitValueParseStatus();
59     InitStringParseStatus();
60     InitDoubleParseStatus();
61     InitIntParseStatus();
62     InitArrayParseSatus();
63     InitStringItemParseStatus();
64     InitDoubleItemParseStatus();
65     InitIntItemParseStatus();
66     InitEscapeCharParseStatus();
67     InitEscapeCharItemParseStatus();
68 }
69 
InitNoneStatus()70 void RawDataBuilderJsonParser::InitNoneStatus()
71 {
72     for (int i = 0; i < CHAR_RANGE; ++i) {
73         statusTabs_[STATUS_NONE][i] = STATUS_NONE;
74     }
75     statusTabs_[STATUS_NONE][LEFT_BRACE_CHAR] = STATUS_RUN;
76 }
77 
InitRunStatus()78 void RawDataBuilderJsonParser::InitRunStatus()
79 {
80     for (int i = 0; i < CHAR_RANGE; ++i) {
81         statusTabs_[STATUS_RUN][i] = STATUS_RUN;
82     }
83     statusTabs_[STATUS_RUN][DOUBLE_QUOTA_CHAR] = STATUS_KEY_PARSE;
84     statusTabs_[STATUS_RUN][COLON_CHAR] = STATUS_VALUE_PARSE;
85     statusTabs_[STATUS_RUN][RIGHT_BRACE_CHAR] = STATUS_NONE;
86 }
87 
InitKeyParseStatus()88 void RawDataBuilderJsonParser::InitKeyParseStatus()
89 {
90     for (int i = 0; i < CHAR_RANGE; ++i) {
91         statusTabs_[STATUS_KEY_PARSE][i] = STATUS_KEY_PARSE;
92     }
93     statusTabs_[STATUS_KEY_PARSE][DOUBLE_QUOTA_CHAR] = STATUS_RUN;
94 }
95 
InitValueParseStatus()96 void RawDataBuilderJsonParser::InitValueParseStatus()
97 {
98     for (int i = 0; i < CHAR_RANGE; ++i) {
99         if ((i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) || (i == MINUS_CHAR)) {
100             statusTabs_[STATUS_VALUE_PARSE][i] = STATUS_INT_PARSE;
101             continue;
102         }
103         statusTabs_[STATUS_VALUE_PARSE][i] = STATUS_VALUE_PARSE;
104     }
105     statusTabs_[STATUS_VALUE_PARSE][DOUBLE_QUOTA_CHAR] = STATUS_STRING_PARSE;
106     statusTabs_[STATUS_VALUE_PARSE][POINT_CHAR] = STATUS_DOUBLE_PARSE;
107     statusTabs_[STATUS_VALUE_PARSE][LEFT_BRACKET_CHAR] = STATUS_ARRAY_PARSE;
108 }
109 
InitStringParseStatus()110 void RawDataBuilderJsonParser::InitStringParseStatus()
111 {
112     for (int i = 0; i < CHAR_RANGE; ++i) {
113         statusTabs_[STATUS_STRING_PARSE][i] = STATUS_STRING_PARSE;
114     }
115     statusTabs_[STATUS_STRING_PARSE][DOUBLE_QUOTA_CHAR] = STATUS_RUN;
116     statusTabs_[STATUS_STRING_PARSE][ESCAPE_CHAR] = STATUS_ESCAPE_CHAR_PARSE;
117 }
118 
InitDoubleParseStatus()119 void RawDataBuilderJsonParser::InitDoubleParseStatus()
120 {
121     for (int i = 0; i < CHAR_RANGE; ++i) {
122         if (i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) {
123             statusTabs_[STATUS_DOUBLE_PARSE][i] = STATUS_DOUBLE_PARSE;
124             continue;
125         }
126         statusTabs_[STATUS_DOUBLE_PARSE][i] = STATUS_NONE;
127     }
128     statusTabs_[STATUS_DOUBLE_PARSE][POSITIVE_CHAR] = STATUS_DOUBLE_PARSE;
129     statusTabs_[STATUS_DOUBLE_PARSE][SICENTIFIC_NOTAITION_CHAR] = STATUS_DOUBLE_PARSE;
130     statusTabs_[STATUS_DOUBLE_PARSE][COMMA_CHAR] = STATUS_RUN;
131 }
132 
InitIntParseStatus()133 void RawDataBuilderJsonParser::InitIntParseStatus()
134 {
135     for (int i = 0; i < CHAR_RANGE; ++i) {
136         if (i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) {
137             statusTabs_[STATUS_INT_PARSE][i] = STATUS_INT_PARSE;
138             continue;
139         }
140         statusTabs_[STATUS_INT_PARSE][i] = STATUS_NONE;
141     }
142     statusTabs_[STATUS_INT_PARSE][POINT_CHAR] = STATUS_DOUBLE_PARSE;
143     statusTabs_[STATUS_INT_PARSE][COMMA_CHAR] = STATUS_RUN;
144 }
145 
InitArrayParseSatus()146 void RawDataBuilderJsonParser::InitArrayParseSatus()
147 {
148     for (int i = 0; i < CHAR_RANGE; ++i) {
149         if ((i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) || (i == MINUS_CHAR)) {
150             statusTabs_[STATUS_ARRAY_PARSE][i] = STATUS_INT_ITEM_PARSE;
151             continue;
152         }
153         statusTabs_[STATUS_ARRAY_PARSE][i] = STATUS_ARRAY_PARSE;
154     }
155     statusTabs_[STATUS_ARRAY_PARSE][DOUBLE_QUOTA_CHAR] = STATUS_STRING_ITEM_PARSE;
156     statusTabs_[STATUS_ARRAY_PARSE][POINT_CHAR] = STATUS_DOUBLE_ITEM_PARSE;
157     statusTabs_[STATUS_ARRAY_PARSE][RIGHT_BRACKET_CHAR] = STATUS_RUN;
158     statusTabs_[STATUS_ARRAY_PARSE][COMMA_CHAR] = STATUS_ARRAY_PARSE;
159 }
160 
InitStringItemParseStatus()161 void RawDataBuilderJsonParser::InitStringItemParseStatus()
162 {
163     for (int i = 0; i < CHAR_RANGE; ++i) {
164         statusTabs_[STATUS_STRING_ITEM_PARSE][i] = STATUS_STRING_ITEM_PARSE;
165     }
166     statusTabs_[STATUS_STRING_ITEM_PARSE][DOUBLE_QUOTA_CHAR] = STATUS_ARRAY_PARSE;
167     statusTabs_[STATUS_STRING_ITEM_PARSE][COMMA_CHAR] = STATUS_ARRAY_PARSE;
168     statusTabs_[STATUS_STRING_ITEM_PARSE][ESCAPE_CHAR] = STATUS_ESCAPE_CHAR_ITEM_PARSE;
169 }
170 
InitDoubleItemParseStatus()171 void RawDataBuilderJsonParser::InitDoubleItemParseStatus()
172 {
173     for (int i = 0; i < CHAR_RANGE; ++i) {
174         if (i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) {
175             statusTabs_[STATUS_DOUBLE_ITEM_PARSE][i] = STATUS_DOUBLE_ITEM_PARSE;
176             continue;
177         }
178         statusTabs_[STATUS_DOUBLE_ITEM_PARSE][i] = STATUS_NONE;
179     }
180     statusTabs_[STATUS_DOUBLE_ITEM_PARSE][POSITIVE_CHAR] = STATUS_DOUBLE_ITEM_PARSE;
181     statusTabs_[STATUS_DOUBLE_ITEM_PARSE][SICENTIFIC_NOTAITION_CHAR] = STATUS_DOUBLE_ITEM_PARSE;
182     statusTabs_[STATUS_DOUBLE_ITEM_PARSE][COMMA_CHAR] = STATUS_ARRAY_PARSE;
183     statusTabs_[STATUS_DOUBLE_ITEM_PARSE][RIGHT_BRACKET_CHAR] = STATUS_RUN;
184 }
185 
InitIntItemParseStatus()186 void RawDataBuilderJsonParser::InitIntItemParseStatus()
187 {
188     for (int i = 0; i < CHAR_RANGE; ++i) {
189         if (i >= NUM_MIN_CHAR && i <= NUM_MAX_CHAR) {
190             statusTabs_[STATUS_INT_ITEM_PARSE][i] = STATUS_INT_ITEM_PARSE;
191             continue;
192         }
193         statusTabs_[STATUS_INT_ITEM_PARSE][i] = STATUS_NONE;
194     }
195     statusTabs_[STATUS_INT_ITEM_PARSE][COMMA_CHAR] = STATUS_ARRAY_PARSE;
196     statusTabs_[STATUS_INT_ITEM_PARSE][RIGHT_BRACKET_CHAR] = STATUS_RUN;
197     statusTabs_[STATUS_INT_ITEM_PARSE][POINT_CHAR] = STATUS_DOUBLE_ITEM_PARSE;
198 }
199 
InitEscapeCharParseStatus()200 void RawDataBuilderJsonParser::InitEscapeCharParseStatus()
201 {
202     for (int i = 0; i < CHAR_RANGE; ++i) {
203         statusTabs_[STATUS_ESCAPE_CHAR_PARSE][i] = STATUS_STRING_PARSE;
204     }
205     statusTabs_[STATUS_ESCAPE_CHAR_PARSE][ESCAPE_CHAR] = STATUS_ESCAPE_CHAR_PARSE;
206 }
207 
InitEscapeCharItemParseStatus()208 void RawDataBuilderJsonParser::InitEscapeCharItemParseStatus()
209 {
210     for (int i = 0; i < CHAR_RANGE; ++i) {
211         statusTabs_[STATUS_ESCAPE_CHAR_ITEM_PARSE][i] = STATUS_STRING_ITEM_PARSE;
212     }
213     statusTabs_[STATUS_ESCAPE_CHAR_ITEM_PARSE][ESCAPE_CHAR] = STATUS_ESCAPE_CHAR_ITEM_PARSE;
214 }
215 
HandleStatusNone()216 void RawDataBuilderJsonParser::HandleStatusNone()
217 {
218     AppendValueToBuilder();
219 }
220 
HandleStatusKeyParse()221 void RawDataBuilderJsonParser::HandleStatusKeyParse()
222 {
223     if (lastStatus_ == STATUS_KEY_PARSE) {
224         key_.append(1, charactor_);
225         return;
226     }
227     AppendValueToBuilder();
228     key_.clear();
229 }
230 
HandleStatusRun()231 void RawDataBuilderJsonParser::HandleStatusRun()
232 {
233     if (lastStatus_ == STATUS_STRING_ITEM_PARSE ||
234         lastStatus_ == STATUS_DOUBLE_ITEM_PARSE ||
235         lastStatus_ == STATUS_INT_ITEM_PARSE) {
236         values_.emplace_back(value_);
237         value_.clear();
238     }
239     if (lastStatus_ == STATUS_STRING_PARSE) { // special for parsing empty string value
240         lastValueParseStatus_ = lastStatus_;
241     }
242     if (lastStatus_ == STATUS_ARRAY_PARSE && (lastValueParseStatus_ != STATUS_STRING_ITEM_PARSE)) { // "KEY":[]
243         lastValueParseStatus_ = STATUS_INT_ITEM_PARSE;
244     }
245 }
246 
HandleStatusValueParse()247 void RawDataBuilderJsonParser::HandleStatusValueParse()
248 {
249     value_.clear();
250     if (lastStatus_ == STATUS_RUN) {
251         values_.clear();
252     }
253     if (lastStatus_ == STATUS_STRING_ITEM_PARSE ||
254         lastStatus_ == STATUS_DOUBLE_ITEM_PARSE ||
255         lastStatus_ == STATUS_INT_ITEM_PARSE) {
256         values_.emplace_back(value_);
257         value_.clear();
258     }
259 }
260 
HandleStatusArrayParse()261 void RawDataBuilderJsonParser::HandleStatusArrayParse()
262 {
263     if (lastStatus_ == STATUS_RUN) {
264         values_.clear();
265     }
266     if (lastStatus_ == STATUS_STRING_ITEM_PARSE ||
267         lastStatus_ == STATUS_DOUBLE_ITEM_PARSE ||
268         lastStatus_ == STATUS_INT_ITEM_PARSE) {
269         values_.emplace_back(value_);
270         value_.clear();
271     }
272 }
273 
HandleStatusStringParse()274 void RawDataBuilderJsonParser::HandleStatusStringParse()
275 {
276     lastValueParseStatus_ = status_;
277     if (lastStatus_ != STATUS_STRING_PARSE && lastStatus_ != STATUS_ESCAPE_CHAR_PARSE) {
278         value_.clear();
279         return;
280     }
281     value_.append(1, charactor_);
282 }
283 
HandleStatusStringItemParse()284 void RawDataBuilderJsonParser::HandleStatusStringItemParse()
285 {
286     lastValueParseStatus_ = status_;
287     if (lastStatus_ != STATUS_STRING_ITEM_PARSE && lastStatus_ != STATUS_ESCAPE_CHAR_ITEM_PARSE) {
288         value_.clear();
289         return;
290     }
291     value_.append(1, charactor_);
292 }
293 
HandleStatusValueAppend()294 void RawDataBuilderJsonParser::HandleStatusValueAppend()
295 {
296     value_.append(1, charactor_);
297     lastValueParseStatus_ = status_;
298 }
299 
BuilderAppendStringValue(const std::string & key,const std::string & value)300 void RawDataBuilderJsonParser::BuilderAppendStringValue(const std::string& key, const std::string& value)
301 {
302     if (builder_ == nullptr) {
303         return;
304     }
305     builder_->AppendValue(key, value);
306 }
307 
BuilderAppendIntValue(const std::string & key,const std::string & value)308 void RawDataBuilderJsonParser::BuilderAppendIntValue(const std::string& key, const std::string& value)
309 {
310     if (builder_ == nullptr || value.empty()) {
311         return;
312     }
313     if (value.find("-") != std::string::npos) {
314         int64_t i64Value = 0;
315         TransStrToType(value, i64Value);
316         builder_->AppendValue(key, i64Value);
317         return;
318     }
319     uint64_t u64Value = 0;
320     TransStrToType(value, u64Value);
321     builder_->AppendValue(key, u64Value);
322 }
323 
BuilderAppendFloatingValue(const std::string & key,const std::string & value)324 void RawDataBuilderJsonParser::BuilderAppendFloatingValue(const std::string& key, const std::string& value)
325 {
326     if (builder_ == nullptr) {
327         return;
328     }
329     double dlValue = 0.0;
330     TransStrToType(value, dlValue);
331     builder_->AppendValue(key, dlValue);
332 }
333 
BuilderAppendStringArrayValue(const std::string & key,const std::vector<std::string> & values)334 void RawDataBuilderJsonParser::BuilderAppendStringArrayValue(const std::string& key,
335     const std::vector<std::string>& values)
336 {
337     if (builder_ == nullptr) {
338         return;
339     }
340     builder_->AppendValue(key, values);
341 }
342 
BuilderAppendIntArrayValue(const std::string & key,const std::vector<std::string> & values)343 void RawDataBuilderJsonParser::BuilderAppendIntArrayValue(const std::string& key,
344     const std::vector<std::string>& values)
345 {
346     if (builder_ == nullptr) {
347         return;
348     }
349     if (any_of(values.begin(), values.end(), [] (auto& item) {
350         return !item.empty() && item.find(".") != std::string::npos;
351     })) {
352         BuilderAppendFloatingArrayValue(key, values);
353         return;
354     }
355     if (any_of(values.begin(), values.end(), [] (auto& item) {
356         return !item.empty() && item.find("-") != std::string::npos;
357     })) {
358         std::vector<int64_t> i64Values;
359         int64_t i64Value = 0;
360         for (auto value : values) {
361             if (value.empty()) {
362                 continue;
363             }
364             TransStrToType(value, i64Value);
365             i64Values.emplace_back(i64Value);
366         }
367         builder_->AppendValue(key, i64Values);
368         return;
369     }
370     std::vector<uint64_t> u64Values;
371     uint64_t u64Value = 0;
372     for (auto value : values) {
373         TransStrToType(value, u64Value);
374         u64Values.emplace_back(u64Value);
375     }
376     builder_->AppendValue(key, u64Values);
377 }
378 
BuilderAppendFloatingArrayValue(const std::string & key,const std::vector<std::string> & values)379 void RawDataBuilderJsonParser::BuilderAppendFloatingArrayValue(const std::string& key,
380     const std::vector<std::string>& values)
381 {
382     if (builder_ == nullptr) {
383         return;
384     }
385     std::vector<double> dlValues;
386     double dlValue = 0.0;
387     for (auto value : values) {
388         TransStrToType(value, dlValue);
389         dlValues.emplace_back(dlValue);
390     }
391     builder_->AppendValue(key, dlValues);
392 }
393 
AppendValueToBuilder()394 void RawDataBuilderJsonParser::AppendValueToBuilder()
395 {
396     if (key_.empty()) { // ignore any Key-Value with empty key directly
397         return;
398     }
399     std::unordered_map<int, std::function<void(const std::string&, const std::string&)>> valueAppendFuncs = {
400         {STATUS_STRING_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendStringValue, this,
401             std::placeholders::_1, std::placeholders::_2)},
402         {STATUS_INT_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendIntValue, this,
403             std::placeholders::_1, std::placeholders::_2)},
404         {STATUS_DOUBLE_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendFloatingValue, this,
405             std::placeholders::_1, std::placeholders::_2)},
406     };
407     auto valueIter = valueAppendFuncs.find(lastValueParseStatus_);
408     if (valueIter != valueAppendFuncs.end()) {
409         valueIter->second(key_, value_);
410         return;
411     }
412     std::unordered_map<int,
413         std::function<void(const std::string&, const std::vector<std::string>&)>> arrayValueAppendFuncs = {
414         {STATUS_STRING_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendStringArrayValue, this,
415             std::placeholders::_1, std::placeholders::_2)},
416         {STATUS_INT_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendIntArrayValue, this,
417             std::placeholders::_1, std::placeholders::_2)},
418         {STATUS_DOUBLE_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::BuilderAppendFloatingArrayValue, this,
419             std::placeholders::_1, std::placeholders::_2)},
420     };
421     auto arrayValueIter = arrayValueAppendFuncs.find(lastValueParseStatus_);
422     if (arrayValueIter != arrayValueAppendFuncs.end()) {
423         arrayValueIter->second(key_, values_);
424     }
425 }
426 
Parse()427 std::shared_ptr<RawDataBuilder> RawDataBuilderJsonParser::Parse()
428 {
429     if (jsonStr_.empty()) {
430         return builder_;
431     }
432     std::unordered_map<int, std::function<void()>> handleFuncs = {
433         {STATUS_NONE, std::bind(&RawDataBuilderJsonParser::HandleStatusNone, this)},
434         {STATUS_KEY_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusKeyParse, this)},
435         {STATUS_RUN, std::bind(&RawDataBuilderJsonParser::HandleStatusRun, this)},
436         {STATUS_VALUE_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueParse, this)},
437         {STATUS_ARRAY_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusArrayParse, this)},
438         {STATUS_STRING_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusStringParse, this)},
439         {STATUS_DOUBLE_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
440         {STATUS_INT_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
441         {STATUS_STRING_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusStringItemParse, this)},
442         {STATUS_DOUBLE_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
443         {STATUS_INT_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
444         {STATUS_ESCAPE_CHAR_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
445         {STATUS_ESCAPE_CHAR_ITEM_PARSE, std::bind(&RawDataBuilderJsonParser::HandleStatusValueAppend, this)},
446     };
447     for (auto c : jsonStr_) {
448         charactor_ = static_cast<int>(c);
449         status_ = statusTabs_[status_][charactor_];
450         auto iter = handleFuncs.find(status_);
451         if (iter != handleFuncs.end()) {
452             iter->second();
453         }
454         lastStatus_ = status_;
455     }
456     return builder_;
457 }
458 } // namespace EventRaw
459 } // namespace HiviewDFX
460 } // namespace OHOS