• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/base/json.h"
12 
13 #include <errno.h>
14 #include <limits.h>
15 #include <stdlib.h>
16 
17 #include <sstream>
18 
GetStringFromJson(const Json::Value & in,std::string * out)19 bool GetStringFromJson(const Json::Value& in, std::string* out) {
20   if (!in.isString()) {
21     std::ostringstream s;
22     if (in.isBool()) {
23       s << std::boolalpha << in.asBool();
24     } else if (in.isInt()) {
25       s << in.asInt();
26     } else if (in.isUInt()) {
27       s << in.asUInt();
28     } else if (in.isDouble()) {
29       s << in.asDouble();
30     } else {
31       return false;
32     }
33     *out = s.str();
34   } else {
35     *out = in.asString();
36   }
37   return true;
38 }
39 
GetIntFromJson(const Json::Value & in,int * out)40 bool GetIntFromJson(const Json::Value& in, int* out) {
41   bool ret;
42   if (!in.isString()) {
43     ret = in.isConvertibleTo(Json::intValue);
44     if (ret) {
45       *out = in.asInt();
46     }
47   } else {
48     long val;  // NOLINT
49     const char* c_str = in.asCString();
50     char* end_ptr;
51     errno = 0;
52     val = strtol(c_str, &end_ptr, 10);  // NOLINT
53     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
54            val >= INT_MIN && val <= INT_MAX);
55     *out = val;
56   }
57   return ret;
58 }
59 
GetUIntFromJson(const Json::Value & in,unsigned int * out)60 bool GetUIntFromJson(const Json::Value& in, unsigned int* out) {
61   bool ret;
62   if (!in.isString()) {
63     ret = in.isConvertibleTo(Json::uintValue);
64     if (ret) {
65       *out = in.asUInt();
66     }
67   } else {
68     unsigned long val;  // NOLINT
69     const char* c_str = in.asCString();
70     char* end_ptr;
71     errno = 0;
72     val = strtoul(c_str, &end_ptr, 10);  // NOLINT
73     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
74            val <= UINT_MAX);
75     *out = val;
76   }
77   return ret;
78 }
79 
GetBoolFromJson(const Json::Value & in,bool * out)80 bool GetBoolFromJson(const Json::Value& in, bool* out) {
81   bool ret;
82   if (!in.isString()) {
83     ret = in.isConvertibleTo(Json::booleanValue);
84     if (ret) {
85       *out = in.asBool();
86     }
87   } else {
88     if (in.asString() == "true") {
89       *out = true;
90       ret = true;
91     } else if (in.asString() == "false") {
92       *out = false;
93       ret = true;
94     } else {
95       ret = false;
96     }
97   }
98   return ret;
99 }
100 
GetDoubleFromJson(const Json::Value & in,double * out)101 bool GetDoubleFromJson(const Json::Value& in, double* out) {
102   bool ret;
103   if (!in.isString()) {
104     ret = in.isConvertibleTo(Json::realValue);
105     if (ret) {
106       *out = in.asDouble();
107     }
108   } else {
109     double val;
110     const char* c_str = in.asCString();
111     char* end_ptr;
112     errno = 0;
113     val = strtod(c_str, &end_ptr);
114     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno);
115     *out = val;
116   }
117   return ret;
118 }
119 
120 namespace {
121 template<typename T>
JsonArrayToVector(const Json::Value & value,bool (* getter)(const Json::Value & in,T * out),std::vector<T> * vec)122 bool JsonArrayToVector(const Json::Value& value,
123                        bool (*getter)(const Json::Value& in, T* out),
124                        std::vector<T> *vec) {
125   vec->clear();
126   if (!value.isArray()) {
127     return false;
128   }
129 
130   for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) {
131     T val;
132     if (!getter(value[i], &val)) {
133       return false;
134     }
135     vec->push_back(val);
136   }
137 
138   return true;
139 }
140 // Trivial getter helper
GetValueFromJson(const Json::Value & in,Json::Value * out)141 bool GetValueFromJson(const Json::Value& in, Json::Value* out) {
142   *out = in;
143   return true;
144 }
145 }  // unnamed namespace
146 
JsonArrayToValueVector(const Json::Value & in,std::vector<Json::Value> * out)147 bool JsonArrayToValueVector(const Json::Value& in,
148                             std::vector<Json::Value>* out) {
149   return JsonArrayToVector(in, GetValueFromJson, out);
150 }
151 
JsonArrayToIntVector(const Json::Value & in,std::vector<int> * out)152 bool JsonArrayToIntVector(const Json::Value& in,
153                           std::vector<int>* out) {
154   return JsonArrayToVector(in, GetIntFromJson, out);
155 }
156 
JsonArrayToUIntVector(const Json::Value & in,std::vector<unsigned int> * out)157 bool JsonArrayToUIntVector(const Json::Value& in,
158                            std::vector<unsigned int>* out) {
159   return JsonArrayToVector(in, GetUIntFromJson, out);
160 }
161 
JsonArrayToStringVector(const Json::Value & in,std::vector<std::string> * out)162 bool JsonArrayToStringVector(const Json::Value& in,
163                              std::vector<std::string>* out) {
164   return JsonArrayToVector(in, GetStringFromJson, out);
165 }
166 
JsonArrayToBoolVector(const Json::Value & in,std::vector<bool> * out)167 bool JsonArrayToBoolVector(const Json::Value& in,
168                            std::vector<bool>* out) {
169   return JsonArrayToVector(in, GetBoolFromJson, out);
170 }
171 
JsonArrayToDoubleVector(const Json::Value & in,std::vector<double> * out)172 bool JsonArrayToDoubleVector(const Json::Value& in,
173                              std::vector<double>* out) {
174   return JsonArrayToVector(in, GetDoubleFromJson, out);
175 }
176 
177 namespace {
178 template<typename T>
VectorToJsonArray(const std::vector<T> & vec)179 Json::Value VectorToJsonArray(const std::vector<T>& vec) {
180   Json::Value result(Json::arrayValue);
181   for (size_t i = 0; i < vec.size(); ++i) {
182     result.append(Json::Value(vec[i]));
183   }
184   return result;
185 }
186 }  // unnamed namespace
187 
ValueVectorToJsonArray(const std::vector<Json::Value> & in)188 Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in) {
189   return VectorToJsonArray(in);
190 }
191 
IntVectorToJsonArray(const std::vector<int> & in)192 Json::Value IntVectorToJsonArray(const std::vector<int>& in) {
193   return VectorToJsonArray(in);
194 }
195 
UIntVectorToJsonArray(const std::vector<unsigned int> & in)196 Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in) {
197   return VectorToJsonArray(in);
198 }
199 
StringVectorToJsonArray(const std::vector<std::string> & in)200 Json::Value StringVectorToJsonArray(const std::vector<std::string>& in) {
201   return VectorToJsonArray(in);
202 }
203 
BoolVectorToJsonArray(const std::vector<bool> & in)204 Json::Value BoolVectorToJsonArray(const std::vector<bool>& in) {
205   return VectorToJsonArray(in);
206 }
207 
DoubleVectorToJsonArray(const std::vector<double> & in)208 Json::Value DoubleVectorToJsonArray(const std::vector<double>& in) {
209   return VectorToJsonArray(in);
210 }
211 
GetValueFromJsonArray(const Json::Value & in,size_t n,Json::Value * out)212 bool GetValueFromJsonArray(const Json::Value& in, size_t n,
213                            Json::Value* out) {
214   if (!in.isArray() || !in.isValidIndex(static_cast<int>(n))) {
215     return false;
216   }
217 
218   *out = in[static_cast<Json::Value::ArrayIndex>(n)];
219   return true;
220 }
221 
GetIntFromJsonArray(const Json::Value & in,size_t n,int * out)222 bool GetIntFromJsonArray(const Json::Value& in, size_t n,
223                          int* out) {
224   Json::Value x;
225   return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out);
226 }
227 
GetUIntFromJsonArray(const Json::Value & in,size_t n,unsigned int * out)228 bool GetUIntFromJsonArray(const Json::Value& in, size_t n,
229                           unsigned int* out)  {
230   Json::Value x;
231   return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out);
232 }
233 
GetStringFromJsonArray(const Json::Value & in,size_t n,std::string * out)234 bool GetStringFromJsonArray(const Json::Value& in, size_t n,
235                             std::string* out) {
236   Json::Value x;
237   return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out);
238 }
239 
GetBoolFromJsonArray(const Json::Value & in,size_t n,bool * out)240 bool GetBoolFromJsonArray(const Json::Value& in, size_t n,
241                           bool* out) {
242   Json::Value x;
243   return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out);
244 }
245 
GetDoubleFromJsonArray(const Json::Value & in,size_t n,double * out)246 bool GetDoubleFromJsonArray(const Json::Value& in, size_t n,
247                             double* out) {
248   Json::Value x;
249   return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out);
250 }
251 
GetValueFromJsonObject(const Json::Value & in,const std::string & k,Json::Value * out)252 bool GetValueFromJsonObject(const Json::Value& in, const std::string& k,
253                             Json::Value* out) {
254   if (!in.isObject() || !in.isMember(k)) {
255     return false;
256   }
257 
258   *out = in[k];
259   return true;
260 }
261 
GetIntFromJsonObject(const Json::Value & in,const std::string & k,int * out)262 bool GetIntFromJsonObject(const Json::Value& in, const std::string& k,
263                           int* out) {
264   Json::Value x;
265   return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out);
266 }
267 
GetUIntFromJsonObject(const Json::Value & in,const std::string & k,unsigned int * out)268 bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k,
269                            unsigned int* out)  {
270   Json::Value x;
271   return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out);
272 }
273 
GetStringFromJsonObject(const Json::Value & in,const std::string & k,std::string * out)274 bool GetStringFromJsonObject(const Json::Value& in, const std::string& k,
275                              std::string* out)  {
276   Json::Value x;
277   return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out);
278 }
279 
GetBoolFromJsonObject(const Json::Value & in,const std::string & k,bool * out)280 bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k,
281                            bool* out) {
282   Json::Value x;
283   return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out);
284 }
285 
GetDoubleFromJsonObject(const Json::Value & in,const std::string & k,double * out)286 bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k,
287                              double* out) {
288   Json::Value x;
289   return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out);
290 }
291 
JsonValueToString(const Json::Value & json)292 std::string JsonValueToString(const Json::Value& json) {
293   Json::FastWriter w;
294   std::string value = w.write(json);
295   return value.substr(0, value.size() - 1);  // trim trailing newline
296 }
297