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#include "json_node.h" 17fb299fa2Sopenharmony_ci 18fb299fa2Sopenharmony_ci#include "log/log.h" 19fb299fa2Sopenharmony_ci#include "utils.h" 20fb299fa2Sopenharmony_ci 21fb299fa2Sopenharmony_cinamespace Updater { 22fb299fa2Sopenharmony_cinamespace { 23fb299fa2Sopenharmony_ciinline const std::unordered_map<uint16_t, NodeType> &GetJsonTypeMap() 24fb299fa2Sopenharmony_ci{ 25fb299fa2Sopenharmony_ci static const std::unordered_map<uint16_t, NodeType> jsonTypeMap { 26fb299fa2Sopenharmony_ci { cJSON_Object, NodeType::OBJECT }, { cJSON_Array, NodeType::ARRAY }, { cJSON_Number, NodeType::INT }, 27fb299fa2Sopenharmony_ci { cJSON_String, NodeType::STRING }, { cJSON_False, NodeType::BOOL }, { cJSON_True, NodeType::BOOL }, 28fb299fa2Sopenharmony_ci { cJSON_NULL, NodeType::NUL }, 29fb299fa2Sopenharmony_ci }; 30fb299fa2Sopenharmony_ci return jsonTypeMap; 31fb299fa2Sopenharmony_ci} 32fb299fa2Sopenharmony_ci} // namespace 33fb299fa2Sopenharmony_ci 34fb299fa2Sopenharmony_ciJsonNode::JsonNode() : type_ {NodeType::UNKNOWN} 35fb299fa2Sopenharmony_ci{ 36fb299fa2Sopenharmony_ci} 37fb299fa2Sopenharmony_ci 38fb299fa2Sopenharmony_ciJsonNode::JsonNode(const std::string &str, bool needDelete) : JsonNode(cJSON_Parse(str.c_str()), needDelete) 39fb299fa2Sopenharmony_ci{ 40fb299fa2Sopenharmony_ci} 41fb299fa2Sopenharmony_ci 42fb299fa2Sopenharmony_ciJsonNode::JsonNode(const Fs::path &path) 43fb299fa2Sopenharmony_ci{ 44fb299fa2Sopenharmony_ci std::string realPath {}; 45fb299fa2Sopenharmony_ci if (!Utils::PathToRealPath(path, realPath)) { 46fb299fa2Sopenharmony_ci return; 47fb299fa2Sopenharmony_ci } 48fb299fa2Sopenharmony_ci 49fb299fa2Sopenharmony_ci std::ifstream ifs(realPath); 50fb299fa2Sopenharmony_ci if (!ifs.is_open()) { 51fb299fa2Sopenharmony_ci LOG(ERROR) << realPath << " not exist"; 52fb299fa2Sopenharmony_ci return; 53fb299fa2Sopenharmony_ci } 54fb299fa2Sopenharmony_ci 55fb299fa2Sopenharmony_ci // get root node 56fb299fa2Sopenharmony_ci std::string content {std::istreambuf_iterator<char> {ifs}, {}}; 57fb299fa2Sopenharmony_ci cJSON *root = cJSON_Parse(content.c_str()); 58fb299fa2Sopenharmony_ci if (root == nullptr || cJSON_IsInvalid(root)) { 59fb299fa2Sopenharmony_ci cJSON_Delete(root); 60fb299fa2Sopenharmony_ci LOG(ERROR) << path << " contained json invalid"; 61fb299fa2Sopenharmony_ci return; 62fb299fa2Sopenharmony_ci } 63fb299fa2Sopenharmony_ci 64fb299fa2Sopenharmony_ci Init(root, true); 65fb299fa2Sopenharmony_ci} 66fb299fa2Sopenharmony_ci 67fb299fa2Sopenharmony_ciJsonNode::JsonNode(const cJSON *root, bool needDelete) 68fb299fa2Sopenharmony_ci{ 69fb299fa2Sopenharmony_ci if (root != nullptr && !cJSON_IsInvalid(root)) { 70fb299fa2Sopenharmony_ci Init(root, needDelete); 71fb299fa2Sopenharmony_ci return; 72fb299fa2Sopenharmony_ci } 73fb299fa2Sopenharmony_ci LOG(ERROR) << "root is not valid"; 74fb299fa2Sopenharmony_ci type_ = NodeType::UNKNOWN; 75fb299fa2Sopenharmony_ci} 76fb299fa2Sopenharmony_ci 77fb299fa2Sopenharmony_ci 78fb299fa2Sopenharmony_civoid JsonNode::Init(const cJSON *root, bool needDelete) 79fb299fa2Sopenharmony_ci{ 80fb299fa2Sopenharmony_ci if (auto it = GetJsonTypeMap().find(root->type); it != GetJsonTypeMap().end()) { 81fb299fa2Sopenharmony_ci type_ = it->second; 82fb299fa2Sopenharmony_ci } 83fb299fa2Sopenharmony_ci Parse(root); 84fb299fa2Sopenharmony_ci if (needDelete) { 85fb299fa2Sopenharmony_ci cJSON_Delete(const_cast<cJSON *>(root)); 86fb299fa2Sopenharmony_ci } 87fb299fa2Sopenharmony_ci} 88fb299fa2Sopenharmony_ci 89fb299fa2Sopenharmony_civoid JsonNode::Parse(const cJSON *root) 90fb299fa2Sopenharmony_ci{ 91fb299fa2Sopenharmony_ci cJSON *element {}; 92fb299fa2Sopenharmony_ci size_ = 1; 93fb299fa2Sopenharmony_ci switch (type_) { 94fb299fa2Sopenharmony_ci case NodeType::OBJECT: { 95fb299fa2Sopenharmony_ci innerObj_ = std::make_optional<NodeMap>(); 96fb299fa2Sopenharmony_ci auto &optNodeMap = std::get<std::optional<NodeMap>>(innerObj_); 97fb299fa2Sopenharmony_ci cJSON_ArrayForEach(element, root) 98fb299fa2Sopenharmony_ci { 99fb299fa2Sopenharmony_ci std::unique_ptr<JsonNode> uPtr = std::make_unique<JsonNode>(element, false); 100fb299fa2Sopenharmony_ci innerNodesList_.push_back(*uPtr); 101fb299fa2Sopenharmony_ci (*optNodeMap).emplace(element->string, std::move(uPtr)); 102fb299fa2Sopenharmony_ci } 103fb299fa2Sopenharmony_ci size_ = static_cast<int>(innerNodesList_.size()); 104fb299fa2Sopenharmony_ci break; 105fb299fa2Sopenharmony_ci } 106fb299fa2Sopenharmony_ci case NodeType::ARRAY: { 107fb299fa2Sopenharmony_ci innerObj_ = std::make_optional<NodeVec>(); 108fb299fa2Sopenharmony_ci auto &optNodeVec = std::get<std::optional<NodeVec>>(innerObj_); 109fb299fa2Sopenharmony_ci cJSON_ArrayForEach(element, root) 110fb299fa2Sopenharmony_ci { 111fb299fa2Sopenharmony_ci std::unique_ptr<JsonNode> uPtr = std::make_unique<JsonNode>(element, false); 112fb299fa2Sopenharmony_ci innerNodesList_.push_back(*uPtr); 113fb299fa2Sopenharmony_ci (*optNodeVec).push_back(std::move(uPtr)); 114fb299fa2Sopenharmony_ci } 115fb299fa2Sopenharmony_ci size_ = static_cast<int>(innerNodesList_.size()); 116fb299fa2Sopenharmony_ci break; 117fb299fa2Sopenharmony_ci } 118fb299fa2Sopenharmony_ci case NodeType::INT: 119fb299fa2Sopenharmony_ci innerObj_ = std::make_optional<int>(root->valueint); 120fb299fa2Sopenharmony_ci innerNodesList_.push_back(*this); 121fb299fa2Sopenharmony_ci break; 122fb299fa2Sopenharmony_ci case NodeType::STRING: 123fb299fa2Sopenharmony_ci innerObj_ = std::make_optional<std::string>(root->valuestring); 124fb299fa2Sopenharmony_ci innerNodesList_.push_back(*this); 125fb299fa2Sopenharmony_ci break; 126fb299fa2Sopenharmony_ci case NodeType::BOOL: 127fb299fa2Sopenharmony_ci innerObj_ = std::make_optional<bool>(root->type == cJSON_True); 128fb299fa2Sopenharmony_ci innerNodesList_.push_back(*this); 129fb299fa2Sopenharmony_ci break; 130fb299fa2Sopenharmony_ci case NodeType::NUL: 131fb299fa2Sopenharmony_ci break; 132fb299fa2Sopenharmony_ci default: 133fb299fa2Sopenharmony_ci LOG(ERROR) << "unknown node type"; 134fb299fa2Sopenharmony_ci break; 135fb299fa2Sopenharmony_ci } 136fb299fa2Sopenharmony_ci if (root->string) { 137fb299fa2Sopenharmony_ci key_ = root->string; 138fb299fa2Sopenharmony_ci } 139fb299fa2Sopenharmony_ci} 140fb299fa2Sopenharmony_ci 141fb299fa2Sopenharmony_ciJsonNode::~JsonNode() = default; 142fb299fa2Sopenharmony_ci 143fb299fa2Sopenharmony_ciJsonNode &JsonNode::operator[](int idx) 144fb299fa2Sopenharmony_ci{ 145fb299fa2Sopenharmony_ci return GetNodeByIdx(innerObj_, size_, idx); 146fb299fa2Sopenharmony_ci} 147fb299fa2Sopenharmony_ci 148fb299fa2Sopenharmony_ciJsonNode &JsonNode::operator[](const std::string &key) 149fb299fa2Sopenharmony_ci{ 150fb299fa2Sopenharmony_ci return GetNodeByKey(innerObj_, key); 151fb299fa2Sopenharmony_ci} 152fb299fa2Sopenharmony_ci 153fb299fa2Sopenharmony_ciconst JsonNode &JsonNode::operator[](int idx) const 154fb299fa2Sopenharmony_ci{ 155fb299fa2Sopenharmony_ci return GetNodeByIdx(innerObj_, size_, idx); 156fb299fa2Sopenharmony_ci} 157fb299fa2Sopenharmony_ci 158fb299fa2Sopenharmony_ciconst JsonNode &JsonNode::operator[](const std::string &key) const 159fb299fa2Sopenharmony_ci{ 160fb299fa2Sopenharmony_ci return GetNodeByKey(innerObj_, key); 161fb299fa2Sopenharmony_ci} 162fb299fa2Sopenharmony_ci 163fb299fa2Sopenharmony_cistd::list<std::reference_wrapper<JsonNode>>::const_iterator JsonNode::begin() const 164fb299fa2Sopenharmony_ci{ 165fb299fa2Sopenharmony_ci return innerNodesList_.cbegin(); 166fb299fa2Sopenharmony_ci} 167fb299fa2Sopenharmony_ci 168fb299fa2Sopenharmony_cistd::list<std::reference_wrapper<JsonNode>>::const_iterator JsonNode::end() const 169fb299fa2Sopenharmony_ci{ 170fb299fa2Sopenharmony_ci return innerNodesList_.cend(); 171fb299fa2Sopenharmony_ci} 172fb299fa2Sopenharmony_ci} // namespace Updater