/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 <string> |
22 | | |
23 | | #include "gutil/ref_counted.h" |
24 | | |
25 | | namespace doris { |
26 | | |
27 | | // A wrapper around rapidjson Value objects, to simplify usage. |
28 | | // Intended solely for building json objects, not writing/parsing. |
29 | | // |
30 | | // Simplifies code like this: |
31 | | // |
32 | | // rapidjson::Document d; |
33 | | // rapidjson::Value v; |
34 | | // v.SetObject(); |
35 | | // rapidjson::Value list; |
36 | | // list.SetArray(); |
37 | | // v.AddMember("list", list, d.GetAllocator()); |
38 | | // v["list"].PushBack(rapidjson::Value().SetString("element"), d.GetAllocator()); |
39 | | // |
40 | | // To this: |
41 | | // |
42 | | // EasyJson ej; |
43 | | // ej["list"][0] = "element"; |
44 | | // |
45 | | // Client code should build objects as demonstrated above, |
46 | | // then call EasyJson::value() to obtain a reference to the |
47 | | // built rapidjson Value. |
48 | | class EasyJson { |
49 | | public: |
50 | | // Used for initializing EasyJson's with complex types. |
51 | | // For example: |
52 | | // |
53 | | // EasyJson array; |
54 | | // EasyJson nested = array.PushBack(EasyJson::kObject); |
55 | | // nested["attr"] = "val"; |
56 | | // // array = [ { "attr": "val" } ] |
57 | | enum ComplexTypeInitializer { kObject, kArray }; |
58 | | |
59 | | EasyJson(); |
60 | | // Initializes the EasyJson object with the given type. |
61 | | explicit EasyJson(ComplexTypeInitializer type); |
62 | 27 | ~EasyJson() = default; |
63 | | |
64 | | // Returns the child EasyJson associated with key. |
65 | | // |
66 | | // Note: this method can mutate the EasyJson object |
67 | | // as follows: |
68 | | // |
69 | | // If this EasyJson's underlying Value is not an object |
70 | | // (i.e. !this->value().IsObject()), then its Value is |
71 | | // coerced to an object, overwriting the old Value. |
72 | | // If the given key does not exist, a Null-valued |
73 | | // EasyJson associated with key is created. |
74 | | EasyJson Get(const std::string& key); |
75 | | |
76 | | // Returns the child EasyJson at index. |
77 | | // |
78 | | // Note: this method can mutate the EasyJson object |
79 | | // as follows: |
80 | | // |
81 | | // If this EasyJson's underlying Value is not an array |
82 | | // (i.e. !this->value().IsArray()), then its Value is |
83 | | // coerced to an array, overwriting the old Value. |
84 | | // If index >= this->value().Size(), then the underlying |
85 | | // array's size is increased to index + 1 (new indices |
86 | | // are filled with Null values). |
87 | | EasyJson Get(int index); |
88 | | |
89 | | // Same as Get(key). |
90 | | EasyJson operator[](const std::string& key); |
91 | | // Same as Get(index). |
92 | | EasyJson operator[](int index); |
93 | | |
94 | | // Sets the underlying Value equal to val. |
95 | | // Returns a reference to the object itself. |
96 | | // |
97 | | // 'val' can be a bool, int32_t, int64_t, double, |
98 | | // char*, string, or ComplexTypeInitializer. |
99 | | EasyJson& operator=(const std::string& val); |
100 | | template <typename T> |
101 | | EasyJson& operator=(T val); |
102 | | |
103 | | // Sets the underlying Value to an object. |
104 | | // Returns a reference to the object itself. |
105 | | // |
106 | | // i.e. after calling SetObject(), |
107 | | // value().IsObject() == true |
108 | | EasyJson& SetObject(); |
109 | | // Sets the underlying Value to an array. |
110 | | // Returns a reference to the object itself. |
111 | | // |
112 | | // i.e. after calling SetArray(), |
113 | | // value().IsArray() == true |
114 | | EasyJson& SetArray(); |
115 | | |
116 | | // Associates val with key. |
117 | | // Returns the child object. |
118 | | // |
119 | | // If this EasyJson's underlying Value is not an object |
120 | | // (i.e. !this->value().IsObject()), then its Value is |
121 | | // coerced to an object, overwriting the old Value. |
122 | | // If the given key does not exist, a new child entry |
123 | | // is created with the given value. |
124 | | EasyJson Set(const std::string& key, const std::string& val); |
125 | | template <typename T> |
126 | | EasyJson Set(const std::string& key, T val); |
127 | | |
128 | | // Stores val at index. |
129 | | // Returns the child object. |
130 | | // |
131 | | // If this EasyJson's underlying Value is not an array |
132 | | // (i.e. !this->value().IsArray()), then its Value is |
133 | | // coerced to an array, overwriting the old Value. |
134 | | // If index >= this->value().Size(), then the underlying |
135 | | // array's size is increased to index + 1 (new indices |
136 | | // are filled with Null values). |
137 | | EasyJson Set(int index, const std::string& val); |
138 | | template <typename T> |
139 | | EasyJson Set(int index, T val); |
140 | | |
141 | | // Appends val to the underlying array. |
142 | | // Returns a reference to the new child object. |
143 | | // |
144 | | // If this EasyJson's underlying Value is not an array |
145 | | // (i.e. !this->value().IsArray()), then its Value is |
146 | | // coerced to an array, overwriting the old Value. |
147 | | EasyJson PushBack(const std::string& val); |
148 | | template <typename T> |
149 | | EasyJson PushBack(T val); |
150 | | |
151 | | // Returns a reference to the underlying Value. |
152 | 11 | rapidjson::Value& value() const { return *value_; } |
153 | | |
154 | | // Returns a string representation of the underlying json. |
155 | | std::string ToString() const; |
156 | | |
157 | | private: |
158 | | // One instance of EasyJsonAllocator is shared among a root |
159 | | // EasyJson object and all of its descendants. The allocator |
160 | | // owns the underlying rapidjson Value, and a rapidjson |
161 | | // allocator (via a rapidjson::Document). |
162 | | class EasyJsonAllocator : public RefCounted<EasyJsonAllocator> { |
163 | | public: |
164 | 5 | rapidjson::Value& value() { return value_; } |
165 | 23 | rapidjson::Document::AllocatorType& allocator() { return value_.GetAllocator(); } |
166 | | |
167 | | private: |
168 | | friend class RefCounted<EasyJsonAllocator>; |
169 | 5 | ~EasyJsonAllocator() = default; |
170 | | |
171 | | // The underlying rapidjson::Value object (Document is |
172 | | // a subclass of Value that has its own allocator). |
173 | | rapidjson::Document value_; |
174 | | }; |
175 | | |
176 | | // Used to instantiate descendant objects. |
177 | | EasyJson(rapidjson::Value* value, scoped_refptr<EasyJsonAllocator> alloc); |
178 | | |
179 | | // One allocator is shared among an EasyJson object and |
180 | | // all of its descendants. |
181 | | scoped_refptr<EasyJsonAllocator> alloc_; |
182 | | |
183 | | // A pointer to the underlying Value in the object |
184 | | // tree owned by alloc_. |
185 | | rapidjson::Value* value_ = nullptr; |
186 | | }; |
187 | | |
188 | | } // namespace doris |