* Copyright (c) 2023 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.
*/
#include "JsonReader.h"
#include <fstream>
#include <sstream>
#include <limits>
#include <cstdint>
#include "PreviewerEngineLog.h"
#include "cJSON.h"
namespace Json2 {
Value::Value(cJSON* object) : jsonPtr(object), rootNode(true) {}
Value::Value(cJSON* object, bool isRoot) : jsonPtr(object), rootNode(isRoot) {}
Value::~Value()
{
if (!jsonPtr) {
return;
}
if (rootNode) {
cJSON_Delete(jsonPtr);
}
jsonPtr = nullptr;
}
Value Value::operator[](const char* key)
{
if (!cJSON_HasObjectItem(jsonPtr, key)) {
return Value();
}
return Value(cJSON_GetObjectItemCaseSensitive(jsonPtr, key), false);
}
const Value Value::operator[](const char* key) const
{
if (!cJSON_HasObjectItem(jsonPtr, key)) {
return Value();
}
return Value(cJSON_GetObjectItemCaseSensitive(jsonPtr, key), false);
}
Value Value::operator[](const std::string& key)
{
if (!cJSON_HasObjectItem(jsonPtr, key.c_str())) {
return Value();
}
return Value(cJSON_GetObjectItemCaseSensitive(jsonPtr, key.c_str()), false);
}
const Value Value::operator[](const std::string& key) const
{
if (!cJSON_HasObjectItem(jsonPtr, key.c_str())) {
return Value();
}
return Value(cJSON_GetObjectItemCaseSensitive(jsonPtr, key.c_str()), false);
}
Value::Members Value::GetMemberNames() const
{
Members names;
if (jsonPtr) {
cJSON* item = jsonPtr->child;
while (item != nullptr) {
if (item->string != nullptr) {
names.push_back(item->string);
}
item = item->next;
}
}
return names;
}
std::string Value::ToString() const
{
std::string ret;
if (!jsonPtr) {
return ret;
}
char* jsonData = cJSON_PrintUnformatted(jsonPtr);
if (jsonData) {
ret = jsonData;
cJSON_free(jsonData);
}
return ret;
}
std::string Value::ToStyledString() const
{
std::string ret;
if (!jsonPtr) {
return ret;
}
char* jsonData = cJSON_Print(jsonPtr);
if (jsonData) {
ret = jsonData;
cJSON_free(jsonData);
}
return ret;
}
const cJSON* Value::GetJsonPtr() const
{
return jsonPtr;
}
bool Value::IsNull() const
{
return !jsonPtr || cJSON_IsNull(jsonPtr);
}
bool Value::IsValid() const
{
return jsonPtr && !cJSON_IsInvalid(jsonPtr);
}
bool Value::IsNumber() const
{
return cJSON_IsNumber(jsonPtr);
}
bool Value::IsInt() const
{
if (!IsNumber()) {
return false;
}
double num = cJSON_GetNumberValue(jsonPtr);
return (num >= static_cast<double>(std::numeric_limits<int32_t>::min())) &&
(num <= static_cast<double>(std::numeric_limits<int32_t>::max()));
}
bool Value::IsUInt() const
{
if (!IsNumber()) {
return false;
}
double num = cJSON_GetNumberValue(jsonPtr);
return (num >= static_cast<double>(std::numeric_limits<uint32_t>::min())) &&
(num <= static_cast<double>(std::numeric_limits<uint32_t>::max()));
}
bool Value::IsInt64() const
{
if (!IsNumber()) {
return false;
}
double num = cJSON_GetNumberValue(jsonPtr);
return (num >= static_cast<double>(std::numeric_limits<int64_t>::min())) &&
(num <= static_cast<double>(std::numeric_limits<int64_t>::max()));
}
bool Value::IsUInt64() const
{
if (!IsNumber()) {
return false;
}
double num = cJSON_GetNumberValue(jsonPtr);
return (num >= static_cast<double>(std::numeric_limits<uint64_t>::min())) &&
(num <= static_cast<double>(std::numeric_limits<uint64_t>::max()));
}
bool Value::IsDouble() const
{
if (!IsNumber()) {
return false;
}
double num = cJSON_GetNumberValue(jsonPtr);
return (num >= std::numeric_limits<double>::lowest()) && (num <= std::numeric_limits<double>::max());
}
bool Value::IsBool() const
{
return cJSON_IsBool(jsonPtr);
}
bool Value::IsString() const
{
return cJSON_IsString(jsonPtr);
}
bool Value::IsObject() const
{
return cJSON_IsObject(jsonPtr);
}
bool Value::IsArray() const
{
return cJSON_IsArray(jsonPtr);
}
bool Value::IsMember(const char* key) const
{
return cJSON_HasObjectItem(jsonPtr, key);
}
int32_t Value::GetInt(const char* key, int32_t defaultVal) const
{
return static_cast<int32_t>(GetDouble(key, defaultVal));
}
uint32_t Value::GetUInt(const char* key, int32_t defaultVal) const
{
return static_cast<uint32_t>(GetDouble(key, defaultVal));
}
int64_t Value::GetInt64(const char* key, int32_t defaultVal) const
{
return static_cast<int64_t>(GetDouble(key, defaultVal));
}
float Value::GetFloat(const char* key, float defaultVal) const
{
return static_cast<float>(GetDouble(key, defaultVal));
}
double Value::GetDouble(const char* key, double defaultVal) const
{
Value val = GetValue(key);
if (!val.IsNull() && val.IsNumber()) {
return val.AsDouble();
}
return defaultVal;
}
bool Value::GetBool(const char* key, bool defaultVal) const
{
Value val = GetValue(key);
if (!val.IsNull() && val.IsBool()) {
return val.AsBool();
}
return defaultVal;
}
std::string Value::GetString(const char* key, const std::string defaultVal) const
{
Value val = GetValue(key);
if (!val.IsNull() && val.IsString()) {
return val.AsString();
}
return defaultVal;
}
Value Value::GetValue(const char* key) const
{
return Value(cJSON_GetObjectItemCaseSensitive(jsonPtr, key), false);
}
int32_t Value::AsInt() const
{
return static_cast<int32_t>(AsDouble());
}
uint32_t Value::AsUInt() const
{
return static_cast<uint32_t>(AsDouble());
}
int64_t Value::AsInt64() const
{
return static_cast<int64_t>(AsDouble());
}
float Value::AsFloat() const
{
return static_cast<float>(AsDouble());
}
double Value::AsDouble() const
{
if (jsonPtr && cJSON_IsNumber(jsonPtr)) {
return cJSON_GetNumberValue(jsonPtr);
}
return 0.0;
}
bool Value::AsBool() const
{
if (jsonPtr && cJSON_IsBool(jsonPtr)) {
return cJSON_IsTrue(jsonPtr);
}
return false;
}
std::string Value::AsString() const
{
if (jsonPtr && cJSON_IsString(jsonPtr)) {
return std::string(cJSON_GetStringValue(jsonPtr));
}
return "";
}
bool Value::Add(const char* key, const char* value)
{
if (!key || !cJSON_IsObject(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateString(value);
if (child == nullptr) {
return false;
}
cJSON_AddItemToObject(jsonPtr, key, child);
return true;
}
bool Value::Add(const char* key, bool value)
{
if (!key || !cJSON_IsObject(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateBool(static_cast<int>(value));
if (child == nullptr) {
return false;
}
cJSON_AddItemToObject(jsonPtr, key, child);
return true;
}
bool Value::Add(const char* key, int32_t value)
{
return Add(key, static_cast<double>(value));
}
bool Value::Add(const char* key, uint32_t value)
{
return Add(key, static_cast<double>(value));
}
bool Value::Add(const char* key, int64_t value)
{
return Add(key, static_cast<double>(value));
}
bool Value::Add(const char* key, double value)
{
if (!key || !cJSON_IsObject(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateNumber(value);
if (child == nullptr) {
return false;
}
cJSON_AddItemToObject(jsonPtr, key, child);
return true;
}
bool Value::Add(const char* key, const Value& value)
{
if (!key || value.IsNull() || !value.IsValid()) {
return false;
}
cJSON* jsonObject = cJSON_Duplicate(const_cast<cJSON*>(value.GetJsonPtr()), true);
if (jsonObject == nullptr) {
return false;
}
cJSON_AddItemToObject(jsonPtr, key, jsonObject);
return true;
}
bool Value::Add(const char* value)
{
if (!cJSON_IsArray(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateString(value);
if (child == nullptr) {
return false;
}
cJSON_AddItemToArray(jsonPtr, child);
return true;
}
bool Value::Add(bool value)
{
if (!cJSON_IsArray(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateBool(static_cast<int>(value));
if (child == nullptr) {
return false;
}
cJSON_AddItemToArray(jsonPtr, child);
return true;
}
bool Value::Add(int32_t value)
{
return Add(static_cast<double>(value));
}
bool Value::Add(uint32_t value)
{
return Add(static_cast<double>(value));
}
bool Value::Add(int64_t value)
{
return Add(static_cast<double>(value));
}
bool Value::Add(double value)
{
if (!cJSON_IsArray(jsonPtr)) {
return false;
}
cJSON* child = cJSON_CreateNumber(value);
if (child == nullptr) {
return false;
}
cJSON_AddItemToArray(jsonPtr, child);
return true;
}
bool Value::Add(const Value& value)
{
if (value.IsNull() || !value.IsValid()) {
return false;
}
cJSON* jsonObject = cJSON_Duplicate(const_cast<cJSON*>(value.GetJsonPtr()), true);
if (jsonObject == nullptr) {
return false;
}
cJSON_AddItemToArray(jsonPtr, jsonObject);
return true;
}
bool Value::Replace(const char* key, bool value)
{
if (!key) {
return false;
}
cJSON* child = cJSON_CreateBool(static_cast<int>(value));
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonPtr, key, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(const char* key, int32_t value)
{
return Replace(key, static_cast<double>(value));
}
bool Value::Replace(const char* key, uint32_t value)
{
return Replace(key, static_cast<double>(value));
}
bool Value::Replace(const char* key, int64_t value)
{
return Replace(key, static_cast<double>(value));
}
bool Value::Replace(const char* key, double value)
{
if (!key) {
return false;
}
cJSON* child = cJSON_CreateNumber(value);
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonPtr, key, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(const char* key, const char* value)
{
if (!key) {
return false;
}
cJSON* child = cJSON_CreateString(value);
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonPtr, key, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(const char* key, const Value& value)
{
if (!key) {
return false;
}
cJSON* jsonObject = cJSON_Duplicate(const_cast<cJSON*>(value.GetJsonPtr()), true);
if (jsonObject == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInObjectCaseSensitive(jsonPtr, key, jsonObject)) {
cJSON_Delete(jsonObject);
return false;
}
return true;
}
bool Value::Replace(int index, bool value)
{
if (index < 0 || index >= GetArraySize()) {
return false;
}
cJSON* child = cJSON_CreateBool(static_cast<int>(value));
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInArray(jsonPtr, index, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(int index, int32_t value)
{
return Replace(index, static_cast<double>(value));
}
bool Value::Replace(int index, uint32_t value)
{
return Replace(index, static_cast<double>(value));
}
bool Value::Replace(int index, int64_t value)
{
return Replace(index, static_cast<double>(value));
}
bool Value::Replace(int index, double value)
{
if (index < 0 || index >= GetArraySize()) {
return false;
}
cJSON* child = cJSON_CreateNumber(value);
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInArray(jsonPtr, index, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(int index, const char* value)
{
if (index < 0 || index >= GetArraySize()) {
return false;
}
cJSON* child = cJSON_CreateString(value);
if (child == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInArray(jsonPtr, index, child)) {
cJSON_Delete(child);
return false;
}
return true;
}
bool Value::Replace(int index, const Value& value)
{
if (index < 0 || index >= GetArraySize()) {
return false;
}
cJSON* jsonObject = cJSON_Duplicate(const_cast<cJSON*>(value.GetJsonPtr()), true);
if (jsonObject == nullptr) {
return false;
}
if (!cJSON_ReplaceItemInArray(jsonPtr, index, jsonObject)) {
cJSON_Delete(jsonObject);
return false;
}
return true;
}
uint32_t Value::GetArraySize() const
{
return cJSON_GetArraySize(jsonPtr);
}
Value Value::GetArrayItem(int32_t index) const
{
return Value(cJSON_GetArrayItem(jsonPtr, index), false);
}
void Value::Clear()
{
cJSON_Delete(jsonPtr);
jsonPtr = cJSON_CreateObject();
}
std::string Value::GetKey()
{
if (jsonPtr && jsonPtr->string) {
return std::string(jsonPtr->string);
}
return std::string();
}
}
std::string JsonReader::ReadFile(const std::string& path)
{
std::ifstream inFile(path);
if (!inFile.is_open()) {
ELOG("JsonReader: Open json file failed.");
return std::string();
}
std::string jsonStr((std::istreambuf_iterator<char>(inFile)), std::istreambuf_iterator<char>());
inFile.close();
return jsonStr;
}
Json2::Value JsonReader::ParseJsonData2(const std::string& jsonStr)
{
return Json2::Value(cJSON_Parse(jsonStr.c_str()));
}
std::string JsonReader::GetErrorPtr()
{
const char* err = cJSON_GetErrorPtr();
if (err) {
return std::string(err);
}
return std::string();
}
Json2::Value JsonReader::CreateObject()
{
return Json2::Value(cJSON_CreateObject());
}
Json2::Value JsonReader::CreateArray()
{
return Json2::Value(cJSON_CreateArray());
}
Json2::Value JsonReader::CreateBool(const bool value)
{
return Json2::Value(cJSON_CreateBool(value));
}
Json2::Value JsonReader::CreateString(const std::string& value)
{
return Json2::Value(cJSON_CreateString(value.c_str()));
}
Json2::Value JsonReader::DepthCopy(const Json2::Value& value)
{
return Json2::Value(cJSON_Duplicate(const_cast<cJSON*>(value.GetJsonPtr()), true));
}
Json2::Value JsonReader::CreateNull()
{
return Json2::Value(cJSON_CreateNull());
}