1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci 16fb299fa2Sopenharmony_ci#ifndef JSON_NODE_H 17fb299fa2Sopenharmony_ci#define JSON_NODE_H 18fb299fa2Sopenharmony_ci 19fb299fa2Sopenharmony_ci#include <filesystem> 20fb299fa2Sopenharmony_ci#include <list> 21fb299fa2Sopenharmony_ci#include <memory> 22fb299fa2Sopenharmony_ci#include <optional> 23fb299fa2Sopenharmony_ci#include <string> 24fb299fa2Sopenharmony_ci#include <type_traits> 25fb299fa2Sopenharmony_ci#include <unordered_map> 26fb299fa2Sopenharmony_ci#include <variant> 27fb299fa2Sopenharmony_ci#include <vector> 28fb299fa2Sopenharmony_ci 29fb299fa2Sopenharmony_ci#include "cJSON.h" 30fb299fa2Sopenharmony_ci#include "log/log.h" 31fb299fa2Sopenharmony_ci#include "macros_updater.h" 32fb299fa2Sopenharmony_ci#include "traits_util.h" 33fb299fa2Sopenharmony_ci 34fb299fa2Sopenharmony_cinamespace Updater { 35fb299fa2Sopenharmony_ciclass JsonNode; 36fb299fa2Sopenharmony_ci 37fb299fa2Sopenharmony_cienum class NodeType { OBJECT, INT, STRING, ARRAY, BOOL, NUL, UNKNOWN }; 38fb299fa2Sopenharmony_ci 39fb299fa2Sopenharmony_ciusing NodeMap = std::unordered_map<std::string, std::unique_ptr<JsonNode>>; 40fb299fa2Sopenharmony_ciusing NodeVec = std::vector<std::unique_ptr<JsonNode>>; 41fb299fa2Sopenharmony_ciusing cJSONPtr = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>; 42fb299fa2Sopenharmony_citemplate<typename...T> 43fb299fa2Sopenharmony_ciusing optionalVariant = std::variant<std::optional<T> ...>; 44fb299fa2Sopenharmony_ci 45fb299fa2Sopenharmony_cinamespace Fs = std::filesystem; 46fb299fa2Sopenharmony_ciclass JsonNode { 47fb299fa2Sopenharmony_ci DISALLOW_COPY_MOVE(JsonNode); 48fb299fa2Sopenharmony_cipublic: 49fb299fa2Sopenharmony_ci JsonNode(); 50fb299fa2Sopenharmony_ci explicit JsonNode(const Fs::path &path); 51fb299fa2Sopenharmony_ci explicit JsonNode(const std::string &str, bool needDelete = true); 52fb299fa2Sopenharmony_ci explicit JsonNode(const cJSON *root, bool needDelete = true); 53fb299fa2Sopenharmony_ci ~JsonNode(); 54fb299fa2Sopenharmony_ci 55fb299fa2Sopenharmony_ci const JsonNode &operator[](int idx) const; 56fb299fa2Sopenharmony_ci const JsonNode &operator[](const std::string &key) const; 57fb299fa2Sopenharmony_ci JsonNode &operator[](int idx); 58fb299fa2Sopenharmony_ci JsonNode &operator[](const std::string &key); 59fb299fa2Sopenharmony_ci 60fb299fa2Sopenharmony_ci template<typename T> 61fb299fa2Sopenharmony_ci std::optional<T> As() const 62fb299fa2Sopenharmony_ci { 63fb299fa2Sopenharmony_ci if (auto optPtr = std::get_if<std::optional<Detail::StandardType<T>>>(&innerObj_); optPtr) { 64fb299fa2Sopenharmony_ci return *optPtr; 65fb299fa2Sopenharmony_ci } 66fb299fa2Sopenharmony_ci return std::nullopt; 67fb299fa2Sopenharmony_ci } 68fb299fa2Sopenharmony_ci 69fb299fa2Sopenharmony_ci template<typename T> 70fb299fa2Sopenharmony_ci bool operator==(T rhs) const 71fb299fa2Sopenharmony_ci { 72fb299fa2Sopenharmony_ci if (auto optPtr = std::get_if<std::optional<Detail::StandardType<T>>>(&innerObj_); optPtr) { 73fb299fa2Sopenharmony_ci return *optPtr == rhs; 74fb299fa2Sopenharmony_ci } 75fb299fa2Sopenharmony_ci return false; 76fb299fa2Sopenharmony_ci } 77fb299fa2Sopenharmony_ci 78fb299fa2Sopenharmony_ci int Size() const 79fb299fa2Sopenharmony_ci { 80fb299fa2Sopenharmony_ci return size_; 81fb299fa2Sopenharmony_ci } 82fb299fa2Sopenharmony_ci NodeType Type() const 83fb299fa2Sopenharmony_ci { 84fb299fa2Sopenharmony_ci return type_; 85fb299fa2Sopenharmony_ci } 86fb299fa2Sopenharmony_ci std::optional<std::string> Key() const 87fb299fa2Sopenharmony_ci { 88fb299fa2Sopenharmony_ci return key_; 89fb299fa2Sopenharmony_ci } 90fb299fa2Sopenharmony_ci std::list<std::reference_wrapper<JsonNode>>::const_iterator begin() const; 91fb299fa2Sopenharmony_ci std::list<std::reference_wrapper<JsonNode>>::const_iterator end() const; 92fb299fa2Sopenharmony_ci template<typename T> 93fb299fa2Sopenharmony_ci void operator=(T &&rhs) 94fb299fa2Sopenharmony_ci { 95fb299fa2Sopenharmony_ci static_assert(Detail::G_IS_BASE_TYPE<Detail::RemoveCvRef<T>>, "only allow change int, string, bool value"); 96fb299fa2Sopenharmony_ci if (innerObj_.valueless_by_exception()) { 97fb299fa2Sopenharmony_ci innerObj_ = Detail::OptStandardType<T>(rhs); 98fb299fa2Sopenharmony_ci } 99fb299fa2Sopenharmony_ci if (auto optPtr = std::get_if<Detail::OptStandardType<T>>(&innerObj_); optPtr) { 100fb299fa2Sopenharmony_ci *optPtr = Detail::OptStandardType<T>(rhs); 101fb299fa2Sopenharmony_ci } else { 102fb299fa2Sopenharmony_ci LOG(ERROR) << "assign json node failed, key is " << key_.value_or("null") << ", type is " 103fb299fa2Sopenharmony_ci << static_cast<int>(type_) << ", rhs is " << rhs; 104fb299fa2Sopenharmony_ci } 105fb299fa2Sopenharmony_ci } 106fb299fa2Sopenharmony_ciprivate: 107fb299fa2Sopenharmony_ci void Parse(const cJSON *root); 108fb299fa2Sopenharmony_ci void Init(const cJSON *root, bool needDelete); 109fb299fa2Sopenharmony_ci int size_ {1}; 110fb299fa2Sopenharmony_ci NodeType type_ {NodeType::UNKNOWN}; /* json node type */ 111fb299fa2Sopenharmony_ci std::optional<std::string> key_ {std::nullopt}; /* key for object items */ 112fb299fa2Sopenharmony_ci optionalVariant<bool, int, std::string, NodeVec, NodeMap> innerObj_ {}; 113fb299fa2Sopenharmony_ci std::list<std::reference_wrapper<JsonNode>> innerNodesList_ {}; 114fb299fa2Sopenharmony_ci}; 115fb299fa2Sopenharmony_ci 116fb299fa2Sopenharmony_ciinline JsonNode &GetInvalidNode() 117fb299fa2Sopenharmony_ci{ 118fb299fa2Sopenharmony_ci static JsonNode emptyNode; // used for invalid json node 119fb299fa2Sopenharmony_ci return emptyNode; 120fb299fa2Sopenharmony_ci} 121fb299fa2Sopenharmony_ci 122fb299fa2Sopenharmony_citemplate<typename T> 123fb299fa2Sopenharmony_ciinline JsonNode &GetNodeByIdx(T &innerObj, int size, int idx) 124fb299fa2Sopenharmony_ci{ 125fb299fa2Sopenharmony_ci auto optVec = std::get_if<std::optional<NodeVec>>(&innerObj); 126fb299fa2Sopenharmony_ci if (optVec == nullptr || *optVec == std::nullopt) { 127fb299fa2Sopenharmony_ci return GetInvalidNode(); // type not matched 128fb299fa2Sopenharmony_ci } 129fb299fa2Sopenharmony_ci auto &nodeVec = **optVec; 130fb299fa2Sopenharmony_ci if (idx < 0 || idx >= size) { 131fb299fa2Sopenharmony_ci return GetInvalidNode(); 132fb299fa2Sopenharmony_ci } 133fb299fa2Sopenharmony_ci return *nodeVec[idx]; 134fb299fa2Sopenharmony_ci} 135fb299fa2Sopenharmony_ci 136fb299fa2Sopenharmony_citemplate<typename T> 137fb299fa2Sopenharmony_ciinline JsonNode &GetNodeByKey(T &innerObj, const std::string &key) 138fb299fa2Sopenharmony_ci{ 139fb299fa2Sopenharmony_ci auto optMap = std::get_if<std::optional<NodeMap>>(&innerObj); 140fb299fa2Sopenharmony_ci if (optMap == nullptr || *optMap == std::nullopt) { 141fb299fa2Sopenharmony_ci return GetInvalidNode(); // type not matched 142fb299fa2Sopenharmony_ci } 143fb299fa2Sopenharmony_ci auto &nodeMap = **optMap; 144fb299fa2Sopenharmony_ci if (auto it = nodeMap.find(key); it != nodeMap.end()) { 145fb299fa2Sopenharmony_ci return *(it->second); 146fb299fa2Sopenharmony_ci } 147fb299fa2Sopenharmony_ci return GetInvalidNode(); 148fb299fa2Sopenharmony_ci} 149fb299fa2Sopenharmony_ci} 150fb299fa2Sopenharmony_ci#endif // NODE_H 151