/root/doris/be/src/util/easy_json.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | #pragma once |
18 | | |
19 | | #include <rapidjson/document.h> |
20 | | |
21 | | #include <memory> |
22 | | #include <string> |
23 | | |
24 | | namespace doris { |
25 | | |
26 | | // A wrapper around rapidjson Value objects, to simplify usage. |
27 | | // Intended solely for building json objects, not writing/parsing. |
28 | | // |
29 | | // Simplifies code like this: |
30 | | // |
31 | | // rapidjson::Document d; |
32 | | // rapidjson::Value v; |
33 | | // v.SetObject(); |
34 | | // rapidjson::Value list; |
35 | | // list.SetArray(); |
36 | | // v.AddMember("list", list, d.GetAllocator()); |
37 | | // v["list"].PushBack(rapidjson::Value().SetString("element"), d.GetAllocator()); |
38 | | // |
39 | | // To this: |
40 | | // |
41 | | // EasyJson ej; |
42 | | // ej["list"][0] = "element"; |
43 | | // |
44 | | // Client code should build objects as demonstrated above, |
45 | | // then call EasyJson::value() to obtain a reference to the |
46 | | // built rapidjson Value. |
47 | | class EasyJson { |
48 | | public: |
49 | | // Used for initializing EasyJson's with complex types. |
50 | | // For example: |
51 | | // |
52 | | // EasyJson array; |
53 | | // EasyJson nested = array.PushBack(EasyJson::kObject); |
54 | | // nested["attr"] = "val"; |
55 | | // // array = [ { "attr": "val" } ] |
56 | | enum ComplexTypeInitializer { kObject, kArray }; |
57 | | |
58 | | EasyJson(); |
59 | | // Initializes the EasyJson object with the given type. |
60 | | explicit EasyJson(ComplexTypeInitializer type); |
61 | 27 | ~EasyJson() = default; |
62 | | |
63 | | // Returns the child EasyJson associated with key. |
64 | | // |
65 | | // Note: this method can mutate the EasyJson object |
66 | | // as follows: |
67 | | // |
68 | | // If this EasyJson's underlying Value is not an object |
69 | | // (i.e. !this->value().IsObject()), then its Value is |
70 | | // coerced to an object, overwriting the old Value. |
71 | | // If the given key does not exist, a Null-valued |
72 | | // EasyJson associated with key is created. |
73 | | EasyJson Get(const std::string& key); |
74 | | |
75 | | // Returns the child EasyJson at index. |
76 | | // |
77 | | // Note: this method can mutate the EasyJson object |
78 | | // as follows: |
79 | | // |
80 | | // If this EasyJson's underlying Value is not an array |
81 | | // (i.e. !this->value().IsArray()), then its Value is |
82 | | // coerced to an array, overwriting the old Value. |
83 | | // If index >= this->value().Size(), then the underlying |
84 | | // array's size is increased to index + 1 (new indices |
85 | | // are filled with Null values). |
86 | | EasyJson Get(int index); |
87 | | |
88 | | // Same as Get(key). |
89 | | EasyJson operator[](const std::string& key); |
90 | | // Same as Get(index). |
91 | | EasyJson operator[](int index); |
92 | | |
93 | | // Sets the underlying Value equal to val. |
94 | | // Returns a reference to the object itself. |
95 | | // |
96 | | // 'val' can be a bool, int32_t, int64_t, double, |
97 | | // char*, string, or ComplexTypeInitializer. |
98 | | EasyJson& operator=(const std::string& val); |
99 | | template <typename T> |
100 | | EasyJson& operator=(T val); |
101 | | |
102 | | // Sets the underlying Value to an object. |
103 | | // Returns a reference to the object itself. |
104 | | // |
105 | | // i.e. after calling SetObject(), |
106 | | // value().IsObject() == true |
107 | | EasyJson& SetObject(); |
108 | | // Sets the underlying Value to an array. |
109 | | // Returns a reference to the object itself. |
110 | | // |
111 | | // i.e. after calling SetArray(), |
112 | | // value().IsArray() == true |
113 | | EasyJson& SetArray(); |
114 | | |
115 | | // Associates val with key. |
116 | | // Returns the child object. |
117 | | // |
118 | | // If this EasyJson's underlying Value is not an object |
119 | | // (i.e. !this->value().IsObject()), then its Value is |
120 | | // coerced to an object, overwriting the old Value. |
121 | | // If the given key does not exist, a new child entry |
122 | | // is created with the given value. |
123 | | EasyJson Set(const std::string& key, const std::string& val); |
124 | | template <typename T> |
125 | | EasyJson Set(const std::string& key, T val); |
126 | | |
127 | | // Stores val at index. |
128 | | // Returns the child object. |
129 | | // |
130 | | // If this EasyJson's underlying Value is not an array |
131 | | // (i.e. !this->value().IsArray()), then its Value is |
132 | | // coerced to an array, overwriting the old Value. |
133 | | // If index >= this->value().Size(), then the underlying |
134 | | // array's size is increased to index + 1 (new indices |
135 | | // are filled with Null values). |
136 | | EasyJson Set(int index, const std::string& val); |
137 | | template <typename T> |
138 | | EasyJson Set(int index, T val); |
139 | | |
140 | | // Appends val to the underlying array. |
141 | | // Returns a reference to the new child object. |
142 | | // |
143 | | // If this EasyJson's underlying Value is not an array |
144 | | // (i.e. !this->value().IsArray()), then its Value is |
145 | | // coerced to an array, overwriting the old Value. |
146 | | EasyJson PushBack(const std::string& val); |
147 | | template <typename T> |
148 | | EasyJson PushBack(T val); |
149 | | |
150 | | // Returns a reference to the underlying Value. |
151 | 11 | rapidjson::Value& value() const { return *value_; } |
152 | | |
153 | | // Returns a string representation of the underlying json. |
154 | | std::string ToString() const; |
155 | | |
156 | | private: |
157 | | // One instance of EasyJsonAllocator is shared among a root |
158 | | // EasyJson object and all of its descendants. The allocator |
159 | | // owns the underlying rapidjson Value, and a rapidjson |
160 | | // allocator (via a rapidjson::Document). |
161 | | class EasyJsonAllocator { |
162 | | public: |
163 | 5 | rapidjson::Value& value() { return value_; } |
164 | 23 | rapidjson::Document::AllocatorType& allocator() { return value_.GetAllocator(); } |
165 | | |
166 | | private: |
167 | | // The underlying rapidjson::Value object (Document is |
168 | | // a subclass of Value that has its own allocator). |
169 | | rapidjson::Document value_; |
170 | | }; |
171 | | |
172 | | // Used to instantiate descendant objects. |
173 | | EasyJson(rapidjson::Value* value, std::shared_ptr<EasyJsonAllocator> alloc); |
174 | | |
175 | | // One allocator is shared among an EasyJson object and |
176 | | // all of its descendants. |
177 | | std::shared_ptr<EasyJsonAllocator> alloc_; |
178 | | |
179 | | // A pointer to the underlying Value in the object |
180 | | // tree owned by alloc_. |
181 | | rapidjson::Value* value_ = nullptr; |
182 | | }; |
183 | | |
184 | | } // namespace doris |