/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef JSON_NODE_H #define JSON_NODE_H #include #include #include #include #include #include #include #include #include #include "cJSON.h" #include "macros.h" #include "traits_util.h" namespace Updater { class JsonNode; enum class NodeType { OBJECT, INT, STRING, ARRAY, BOOL, NUL, UNKNOWN }; using NodeMap = std::unordered_map>; using NodeVec = std::vector>; using cJSONPtr = std::unique_ptr; template using optionalVariant = std::variant ...>; namespace Fs = std::filesystem; class JsonNode { DISALLOW_COPY_MOVE(JsonNode); public: JsonNode(); explicit JsonNode(const Fs::path &path); explicit JsonNode(const std::string &str, bool needDelete = true); explicit JsonNode(const cJSON *root, bool needDelete = true); ~JsonNode(); const JsonNode &operator[](int idx) const; const JsonNode &operator[](const std::string &key) const; template std::optional As() const { if (auto optPtr = std::get_if>>(&innerObj_); optPtr) { return *optPtr; } return std::nullopt; } template bool operator==(T rhs) const { if (auto optPtr = std::get_if>>(&innerObj_); optPtr) { return *optPtr == rhs; } return false; } int Size() const { return size_; } NodeType Type() const { return type_; } std::optional Key() const { return key_; } std::list>::const_iterator begin() const; std::list>::const_iterator end() const; private: void Parse(const cJSON *root); void Init(const cJSON *root, bool needDelete); template void Assign(T rhs) const { if (innerObj_.valueless_by_exception()) { innerObj_ = std::optional(rhs); } if (auto optPtr = std::get_if>(&innerObj_); optPtr) { *optPtr = std::optional(rhs); } } int size_ {1}; NodeType type_ {NodeType::UNKNOWN}; /* json node type */ std::optional key_ {std::nullopt}; /* key for object items */ optionalVariant innerObj_ {}; std::list> innerNodesList_ {}; }; inline const JsonNode &GetInvalidNode() { static JsonNode emptyNode; // used for invalid json node return emptyNode; } } #endif // NODE_H