1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 
16 #ifndef RD_JSON_OBJECT_H
17 #define RD_JSON_OBJECT_H
18 
19 #include <memory>
20 #include <set>
21 #include <string>
22 #include <typeinfo>
23 #include <vector>
24 
25 #ifndef OMIT_cJSON
26 #include "cJSON.h"
27 #endif
28 
29 #ifdef OMIT_cJSON
30 typedef void cJSON;
31 #endif
32 
33 namespace DocumentDB {
34 class ValueObject {
35 public:
36     enum class ValueType {
37         VALUE_NULL = 0,
38         VALUE_BOOL,
39         VALUE_NUMBER,
40         VALUE_STRING,
41     };
42     ValueObject() = default;
43     explicit ValueObject(bool val);
44     explicit ValueObject(double val);
45     explicit ValueObject(const char *val);
46 
47     ValueType GetValueType() const;
48     bool GetBoolValue() const;
49     int64_t GetIntValue() const;
50     double GetDoubleValue() const;
51     std::string GetStringValue() const;
52 
53 private:
54     ValueType valueType = ValueType::VALUE_NULL;
55     union {
56         bool boolValue;
57         double doubleValue;
58     };
59     std::string stringValue;
60 };
61 using JsonFieldPath = std::vector<std::string>;
62 
63 using ResultValue = ValueObject;
64 using JsonFieldPath = std::vector<std::string>;
65 
66 class JsonObject {
67 public:
68     static JsonObject Parse(const std::string &jsonStr, int &errCode, bool caseSensitive = false,
69         bool isFilter = false);
70     bool operator==(const JsonObject &other) const; // If the two nodes exist with a different fieldName, then return 0.
71     ~JsonObject();
72 
73     std::string Print() const;
74 
75     JsonObject GetObjectItem(const std::string &field, int &errCode);
76 
77     JsonObject GetNext() const;
78     JsonObject GetChild() const;
79 
80     int DeleteItemFromObject(const std::string &field);
81     int AddItemToObject(const std::string &fieldName, const JsonObject &item);
82     int AddItemToObject(const std::string &fieldName);
83 
84     ValueObject GetItemValue() const;
85     void ReplaceItemInArray(const int &index, const JsonObject &newItem, int &errCode);
86     void ReplaceItemInObject(const std::string &fieldName, const JsonObject &newItem, int &errCode);
87     int InsertItemObject(int which, const JsonObject &newItem);
88 
89     std::string GetItemField() const;
90     std::string GetItemField(int &errCode) const;
91 
92     bool IsFieldExists(const JsonFieldPath &jsonPath) const;
93     bool IsFieldExistsPowerMode(const JsonFieldPath &jsonPath) const;
94     JsonObject FindItem(const JsonFieldPath &jsonPath, int &errCode) const;
95     JsonObject FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const;
96     ValueObject GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const;
97     int DeleteItemDeeplyOnTarget(const JsonFieldPath &path);
98     bool IsNull() const;
99     int GetDeep();
100     enum class Type {
101         JSON_LEAF, // Corresponds to nodes of type null, number, string, true false in CJSON
102         JSON_OBJECT,
103         JSON_ARRAY
104     };
105     Type GetType() const;
106 
107 private:
108     JsonObject();
109     int Init(const std::string &str, bool isFilter = false);
110     int CheckJsonRepeatField(cJSON *object, bool isFirstFloor);
111     int CheckSubObj(std::set<std::string> &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor);
112     int GetDeep(cJSON *cjson);
113     int CheckNumber(cJSON *cJSON);
114     cJSON *cjson_ = nullptr;
115     int jsonDeep_ = 0;
116     bool isOwner_ = false;
117     bool caseSensitive_ = false;
118 };
119 } // namespace DocumentDB
120 #endif // JSON_OBJECT_H
121