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