11401458bSopenharmony_ci/* 21401458bSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 31401458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 41401458bSopenharmony_ci * you may not use this file except in compliance with the License. 51401458bSopenharmony_ci * You may obtain a copy of the License at 61401458bSopenharmony_ci * 71401458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 81401458bSopenharmony_ci * 91401458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 101401458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 111401458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121401458bSopenharmony_ci * See the License for the specific language governing permissions and 131401458bSopenharmony_ci * limitations under the License. 141401458bSopenharmony_ci */ 151401458bSopenharmony_ci 161401458bSopenharmony_ci#include "json_flatten_parser.h" 171401458bSopenharmony_ci 181401458bSopenharmony_ci#include <cstddef> 191401458bSopenharmony_ci#include <cstdint> 201401458bSopenharmony_ci#include <functional> 211401458bSopenharmony_ci#include <iosfwd> 221401458bSopenharmony_ci#include <string> 231401458bSopenharmony_ci#include <vector> 241401458bSopenharmony_ci 251401458bSopenharmony_cinamespace OHOS { 261401458bSopenharmony_cinamespace HiviewDFX { 271401458bSopenharmony_cinamespace { 281401458bSopenharmony_ci struct Initializer { 291401458bSopenharmony_ci Initializer() 301401458bSopenharmony_ci { 311401458bSopenharmony_ci JsonFlattenParser::Initialize(); 321401458bSopenharmony_ci } 331401458bSopenharmony_ci }; 341401458bSopenharmony_ci} 351401458bSopenharmony_ci 361401458bSopenharmony_ciuint8_t JsonFlattenParser::charFilter[JsonFlattenParser::CHAR_RANGE] { 0 }; 371401458bSopenharmony_ci 381401458bSopenharmony_civoid JsonFlattenParser::Initialize() 391401458bSopenharmony_ci{ 401401458bSopenharmony_ci for (char c = '0'; c <= '9'; c++) { 411401458bSopenharmony_ci charFilter[static_cast<uint8_t>(c)] = NUMBER_FLAG; 421401458bSopenharmony_ci } 431401458bSopenharmony_ci charFilter[static_cast<uint8_t>('-')] = NUMBER_FLAG; 441401458bSopenharmony_ci charFilter[static_cast<uint8_t>('+')] = NUMBER_FLAG; 451401458bSopenharmony_ci charFilter[static_cast<uint8_t>('.')] = NUMBER_FLAG; 461401458bSopenharmony_ci charFilter[static_cast<uint8_t>('"')] = STRING_FLAG; 471401458bSopenharmony_ci charFilter[static_cast<uint8_t>('{')] = BRACKET_FLAG; 481401458bSopenharmony_ci charFilter[static_cast<uint8_t>('[')] = BRACKET_FLAG; 491401458bSopenharmony_ci} 501401458bSopenharmony_ci 511401458bSopenharmony_ciJsonFlattenParser::JsonFlattenParser(const std::string& json) 521401458bSopenharmony_ci{ 531401458bSopenharmony_ci static Initializer initialize; 541401458bSopenharmony_ci Parse(json); 551401458bSopenharmony_ci} 561401458bSopenharmony_ci 571401458bSopenharmony_civoid JsonFlattenParser::Parse(const std::string& json) 581401458bSopenharmony_ci{ 591401458bSopenharmony_ci curPos = 0; 601401458bSopenharmony_ci kvList.clear(); 611401458bSopenharmony_ci while (curPos < json.length()) { 621401458bSopenharmony_ci if (charFilter[static_cast<uint8_t>(json[curPos])] != STRING_FLAG) { 631401458bSopenharmony_ci ++curPos; 641401458bSopenharmony_ci continue; 651401458bSopenharmony_ci } 661401458bSopenharmony_ci std::string key = ParseKey(json); 671401458bSopenharmony_ci std::string val = ParseValue(json); 681401458bSopenharmony_ci kvList.emplace_back(key, val); 691401458bSopenharmony_ci } 701401458bSopenharmony_ci} 711401458bSopenharmony_ci 721401458bSopenharmony_cistd::string JsonFlattenParser::Print(PrintKvHandler handler) 731401458bSopenharmony_ci{ 741401458bSopenharmony_ci std::string json = "{"; 751401458bSopenharmony_ci if (!kvList.empty()) { 761401458bSopenharmony_ci for (size_t i = 0; i < kvList.size() - 1; i++) { 771401458bSopenharmony_ci json += (handler(kvList[i]) + ","); 781401458bSopenharmony_ci } 791401458bSopenharmony_ci json += handler(kvList.back()); 801401458bSopenharmony_ci } 811401458bSopenharmony_ci json += "}"; 821401458bSopenharmony_ci return json; 831401458bSopenharmony_ci} 841401458bSopenharmony_ci 851401458bSopenharmony_cistd::string JsonFlattenParser::ParseKey(const std::string& json) 861401458bSopenharmony_ci{ 871401458bSopenharmony_ci std::string key; 881401458bSopenharmony_ci ++curPos; // eat left quotation 891401458bSopenharmony_ci while (curPos < json.length()) { 901401458bSopenharmony_ci if (charFilter[static_cast<uint8_t>(json[curPos])] == STRING_FLAG) { 911401458bSopenharmony_ci break; 921401458bSopenharmony_ci } 931401458bSopenharmony_ci key.push_back(json[curPos]); 941401458bSopenharmony_ci ++curPos; 951401458bSopenharmony_ci } 961401458bSopenharmony_ci ++curPos; // eat right quotation 971401458bSopenharmony_ci return key; 981401458bSopenharmony_ci} 991401458bSopenharmony_ci 1001401458bSopenharmony_cistd::string JsonFlattenParser::ParseValue(const std::string& json) 1011401458bSopenharmony_ci{ 1021401458bSopenharmony_ci std::string value; 1031401458bSopenharmony_ci bool valueParsed = false; 1041401458bSopenharmony_ci while (curPos < json.length()) { 1051401458bSopenharmony_ci int charCode = static_cast<uint8_t>(json[curPos]); 1061401458bSopenharmony_ci switch (charFilter[charCode]) { 1071401458bSopenharmony_ci case BRACKET_FLAG: 1081401458bSopenharmony_ci value = ParseBrackets(json, json[curPos]); 1091401458bSopenharmony_ci valueParsed = true; 1101401458bSopenharmony_ci break; 1111401458bSopenharmony_ci case NUMBER_FLAG: 1121401458bSopenharmony_ci value = ParseNumer(json); 1131401458bSopenharmony_ci valueParsed = true; 1141401458bSopenharmony_ci break; 1151401458bSopenharmony_ci case STRING_FLAG: 1161401458bSopenharmony_ci value = ParseString(json); 1171401458bSopenharmony_ci valueParsed = true; 1181401458bSopenharmony_ci break; 1191401458bSopenharmony_ci default: 1201401458bSopenharmony_ci ++curPos; 1211401458bSopenharmony_ci valueParsed = false; 1221401458bSopenharmony_ci break; 1231401458bSopenharmony_ci } 1241401458bSopenharmony_ci if (valueParsed) { 1251401458bSopenharmony_ci break; 1261401458bSopenharmony_ci } 1271401458bSopenharmony_ci } 1281401458bSopenharmony_ci return value; 1291401458bSopenharmony_ci} 1301401458bSopenharmony_ci 1311401458bSopenharmony_cistd::string JsonFlattenParser::ParseNumer(const std::string& json) 1321401458bSopenharmony_ci{ 1331401458bSopenharmony_ci std::string number; 1341401458bSopenharmony_ci while (curPos < json.length()) { 1351401458bSopenharmony_ci if (charFilter[static_cast<uint8_t>(json[curPos])] != NUMBER_FLAG) { 1361401458bSopenharmony_ci break; 1371401458bSopenharmony_ci } 1381401458bSopenharmony_ci number.push_back(json[curPos]); 1391401458bSopenharmony_ci ++curPos; 1401401458bSopenharmony_ci } 1411401458bSopenharmony_ci return number; 1421401458bSopenharmony_ci} 1431401458bSopenharmony_ci 1441401458bSopenharmony_cistd::string JsonFlattenParser::ParseString(const std::string& json) 1451401458bSopenharmony_ci{ 1461401458bSopenharmony_ci std::string txt; 1471401458bSopenharmony_ci txt.push_back(json[curPos++]); 1481401458bSopenharmony_ci while (curPos < json.length()) { 1491401458bSopenharmony_ci if (charFilter[static_cast<uint8_t>(json[curPos])] == STRING_FLAG && 1501401458bSopenharmony_ci json[curPos - 1] != '\\') { 1511401458bSopenharmony_ci break; 1521401458bSopenharmony_ci } 1531401458bSopenharmony_ci txt.push_back(json[curPos]); 1541401458bSopenharmony_ci ++curPos; 1551401458bSopenharmony_ci } 1561401458bSopenharmony_ci txt.push_back(json[curPos++]); 1571401458bSopenharmony_ci return txt; 1581401458bSopenharmony_ci} 1591401458bSopenharmony_ci 1601401458bSopenharmony_cistd::string JsonFlattenParser::ParseBrackets(const std::string& json, char leftBracket) 1611401458bSopenharmony_ci{ 1621401458bSopenharmony_ci std::string val; 1631401458bSopenharmony_ci char rightBracket = leftBracket + 2; // 2: '[' + 2 = ']', '{' + 2 = '}' 1641401458bSopenharmony_ci int counter = 1; 1651401458bSopenharmony_ci val.push_back(json[curPos++]); 1661401458bSopenharmony_ci while (curPos < json.length()) { 1671401458bSopenharmony_ci if (json[curPos] == leftBracket) { 1681401458bSopenharmony_ci ++counter; 1691401458bSopenharmony_ci } else if (json[curPos] == rightBracket) { 1701401458bSopenharmony_ci --counter; 1711401458bSopenharmony_ci if (counter == 0) { 1721401458bSopenharmony_ci break; 1731401458bSopenharmony_ci } 1741401458bSopenharmony_ci } 1751401458bSopenharmony_ci val.push_back(json[curPos++]); 1761401458bSopenharmony_ci } 1771401458bSopenharmony_ci val.push_back(json[curPos++]); 1781401458bSopenharmony_ci return val; 1791401458bSopenharmony_ci} 1801401458bSopenharmony_ci} // namespace HiviewDFX 1811401458bSopenharmony_ci} // namespace OHOS 182