GRPC Core  18.0.0
json.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPC_CORE_LIB_JSON_JSON_H
20 #define GRPC_CORE_LIB_JSON_JSON_H
21 
23 
24 #include <stdlib.h>
25 
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 #include "absl/strings/string_view.h"
31 
33 
34 namespace grpc_core {
35 
36 // A JSON value, which can be any one of object, array, string,
37 // number, true, false, or null.
38 class Json {
39  public:
40  // TODO(roth): Currently, numbers are stored internally as strings,
41  // which makes the API a bit cumbersome to use. When we have time,
42  // consider whether there's a better alternative (e.g., maybe storing
43  // each numeric type as the native C++ type and automatically converting
44  // to string as needed).
45  enum class Type {
46  JSON_NULL,
47  JSON_TRUE,
48  JSON_FALSE,
49  NUMBER,
50  STRING,
51  OBJECT,
52  ARRAY
53  };
54 
55  using Object = std::map<std::string, Json>;
56  using Array = std::vector<Json>;
57 
58  // Parses JSON string from json_str. On error, sets *error.
59  static Json Parse(absl::string_view json_str, grpc_error_handle* error);
60 
61  Json() = default;
62 
63  // Copyable.
64  Json(const Json& other) { CopyFrom(other); }
65  Json& operator=(const Json& other) {
66  CopyFrom(other);
67  return *this;
68  }
69 
70  // Moveable.
71  Json(Json&& other) noexcept { MoveFrom(std::move(other)); }
72  Json& operator=(Json&& other) noexcept {
73  MoveFrom(std::move(other));
74  return *this;
75  }
76 
77  // Construct from copying a string.
78  // If is_number is true, the type will be NUMBER instead of STRING.
79  // NOLINTNEXTLINE(google-explicit-constructor)
80  Json(const std::string& string, bool is_number = false)
81  : type_(is_number ? Type::NUMBER : Type::STRING), string_value_(string) {}
82  Json& operator=(const std::string& string) {
83  type_ = Type::STRING;
84  string_value_ = string;
85  return *this;
86  }
87 
88  // Same thing for C-style strings, both const and mutable.
89  // NOLINTNEXTLINE(google-explicit-constructor)
90  Json(const char* string, bool is_number = false)
91  : Json(std::string(string), is_number) {}
92  Json& operator=(const char* string) {
93  *this = std::string(string);
94  return *this;
95  }
96  // NOLINTNEXTLINE(google-explicit-constructor)
97  Json(char* string, bool is_number = false)
98  : Json(std::string(string), is_number) {}
99  Json& operator=(char* string) {
100  *this = std::string(string);
101  return *this;
102  }
103 
104  // Construct by moving a string.
105  // NOLINTNEXTLINE(google-explicit-constructor)
106  Json(std::string&& string)
107  : type_(Type::STRING), string_value_(std::move(string)) {}
108  Json& operator=(std::string&& string) {
109  type_ = Type::STRING;
110  string_value_ = std::move(string);
111  return *this;
112  }
113 
114  // Construct from bool.
115  // NOLINTNEXTLINE(google-explicit-constructor)
116  Json(bool b) : type_(b ? Type::JSON_TRUE : Type::JSON_FALSE) {}
117  Json& operator=(bool b) {
118  type_ = b ? Type::JSON_TRUE : Type::JSON_FALSE;
119  return *this;
120  }
121 
122  // Construct from any numeric type.
123  template <typename NumericType>
124  // NOLINTNEXTLINE(google-explicit-constructor)
125  Json(NumericType number)
126  : type_(Type::NUMBER), string_value_(std::to_string(number)) {}
127  template <typename NumericType>
128  Json& operator=(NumericType number) {
129  type_ = Type::NUMBER;
130  string_value_ = std::to_string(number);
131  return *this;
132  }
133 
134  // Construct by copying object.
135  // NOLINTNEXTLINE(google-explicit-constructor)
136  Json(const Object& object) : type_(Type::OBJECT), object_value_(object) {}
137  Json& operator=(const Object& object) {
138  type_ = Type::OBJECT;
139  object_value_ = object;
140  return *this;
141  }
142 
143  // Construct by moving object.
144  // NOLINTNEXTLINE(google-explicit-constructor)
145  Json(Object&& object)
146  : type_(Type::OBJECT), object_value_(std::move(object)) {}
147  Json& operator=(Object&& object) {
148  type_ = Type::OBJECT;
149  object_value_ = std::move(object);
150  return *this;
151  }
152 
153  // Construct by copying array.
154  // NOLINTNEXTLINE(google-explicit-constructor)
155  Json(const Array& array) : type_(Type::ARRAY), array_value_(array) {}
156  Json& operator=(const Array& array) {
157  type_ = Type::ARRAY;
158  array_value_ = array;
159  return *this;
160  }
161 
162  // Construct by moving array.
163  // NOLINTNEXTLINE(google-explicit-constructor)
164  Json(Array&& array) : type_(Type::ARRAY), array_value_(std::move(array)) {}
165  Json& operator=(Array&& array) {
166  type_ = Type::ARRAY;
167  array_value_ = std::move(array);
168  return *this;
169  }
170 
171  // Dumps JSON from value to string form.
172  std::string Dump(int indent = 0) const;
173 
174  // Accessor methods.
175  Type type() const { return type_; }
176  const std::string& string_value() const { return string_value_; }
177  std::string* mutable_string_value() { return &string_value_; }
178  const Object& object_value() const { return object_value_; }
179  Object* mutable_object() { return &object_value_; }
180  const Array& array_value() const { return array_value_; }
181  Array* mutable_array() { return &array_value_; }
182 
183  bool operator==(const Json& other) const {
184  if (type_ != other.type_) return false;
185  switch (type_) {
186  case Type::NUMBER:
187  case Type::STRING:
188  if (string_value_ != other.string_value_) return false;
189  break;
190  case Type::OBJECT:
191  if (object_value_ != other.object_value_) return false;
192  break;
193  case Type::ARRAY:
194  if (array_value_ != other.array_value_) return false;
195  break;
196  default:
197  break;
198  }
199  return true;
200  }
201 
202  bool operator!=(const Json& other) const { return !(*this == other); }
203 
204  private:
205  void CopyFrom(const Json& other) {
206  type_ = other.type_;
207  switch (type_) {
208  case Type::NUMBER:
209  case Type::STRING:
210  string_value_ = other.string_value_;
211  break;
212  case Type::OBJECT:
213  object_value_ = other.object_value_;
214  break;
215  case Type::ARRAY:
216  array_value_ = other.array_value_;
217  break;
218  default:
219  break;
220  }
221  }
222 
223  void MoveFrom(Json&& other) {
224  type_ = other.type_;
225  other.type_ = Type::JSON_NULL;
226  switch (type_) {
227  case Type::NUMBER:
228  case Type::STRING:
229  string_value_ = std::move(other.string_value_);
230  break;
231  case Type::OBJECT:
232  object_value_ = std::move(other.object_value_);
233  break;
234  case Type::ARRAY:
235  array_value_ = std::move(other.array_value_);
236  break;
237  default:
238  break;
239  }
240  }
241 
242  Type type_ = Type::JSON_NULL;
243  std::string string_value_;
244  Object object_value_;
245  Array array_value_;
246 };
247 
248 } // namespace grpc_core
249 
250 #endif /* GRPC_CORE_LIB_JSON_JSON_H */
Definition: json.h:38
Json(Json &&other) noexcept
Definition: json.h:71
Type type() const
Definition: json.h:175
std::string * mutable_string_value()
Definition: json.h:177
Array * mutable_array()
Definition: json.h:181
const std::string & string_value() const
Definition: json.h:176
const Array & array_value() const
Definition: json.h:180
std::map< std::string, Json > Object
Definition: json.h:55
const Object & object_value() const
Definition: json.h:178
bool operator==(const Json &other) const
Definition: json.h:183
Json(char *string, bool is_number=false)
Definition: json.h:97
Object * mutable_object()
Definition: json.h:179
std::string Dump(int indent=0) const
Definition: json_writer.cc:334
Type
Definition: json.h:45
Json(const Array &array)
Definition: json.h:155
Json(Array &&array)
Definition: json.h:164
Json()=default
Json & operator=(std::string &&string)
Definition: json.h:108
Json & operator=(const Object &object)
Definition: json.h:137
Json(const char *string, bool is_number=false)
Definition: json.h:90
Json & operator=(char *string)
Definition: json.h:99
Json(const std::string &string, bool is_number=false)
Definition: json.h:80
Json & operator=(Array &&array)
Definition: json.h:165
bool operator!=(const Json &other) const
Definition: json.h:202
Json & operator=(bool b)
Definition: json.h:117
static Json Parse(absl::string_view json_str, grpc_error_handle *error)
Definition: json_reader.cc:852
Json(Object &&object)
Definition: json.h:145
Json(const Json &other)
Definition: json.h:64
Json & operator=(Json &&other) noexcept
Definition: json.h:72
Json & operator=(Object &&object)
Definition: json.h:147
Json & operator=(const std::string &string)
Definition: json.h:82
std::vector< Json > Array
Definition: json.h:56
Json(NumericType number)
Definition: json.h:125
Json & operator=(NumericType number)
Definition: json.h:128
Json(const Object &object)
Definition: json.h:136
Json & operator=(const Json &other)
Definition: json.h:65
Json(std::string &&string)
Definition: json.h:106
Json & operator=(const Array &array)
Definition: json.h:156
Json & operator=(const char *string)
Definition: json.h:92
Json(bool b)
Definition: json.h:116
grpc_error_handle error
Definition: lame_client.cc:54
Round Robin Policy.
Definition: backend_metric.cc:26
Definition: error_internal.h:41