- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / json.cc
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "talk/base/json.h"
29
30 #include <errno.h>
31
32 #include <climits>
33 #include <cstdlib>
34 #include <sstream>
35
36 bool GetStringFromJson(const Json::Value& in, std::string* out) {
37   if (!in.isString()) {
38     std::ostringstream s;
39     if (in.isBool()) {
40       s << std::boolalpha << in.asBool();
41     } else if (in.isInt()) {
42       s << in.asInt();
43     } else if (in.isUInt()) {
44       s << in.asUInt();
45     } else if (in.isDouble()) {
46       s << in.asDouble();
47     } else {
48       return false;
49     }
50     *out = s.str();
51   } else {
52     *out = in.asString();
53   }
54   return true;
55 }
56
57 bool GetIntFromJson(const Json::Value& in, int* out) {
58   bool ret;
59   if (!in.isString()) {
60     ret = in.isConvertibleTo(Json::intValue);
61     if (ret) {
62       *out = in.asInt();
63     }
64   } else {
65     long val;  // NOLINT
66     const char* c_str = in.asCString();
67     char* end_ptr;
68     errno = 0;
69     val = strtol(c_str, &end_ptr, 10);  // NOLINT
70     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
71            val >= INT_MIN && val <= INT_MAX);
72     *out = val;
73   }
74   return ret;
75 }
76
77 bool GetUIntFromJson(const Json::Value& in, unsigned int* out) {
78   bool ret;
79   if (!in.isString()) {
80     ret = in.isConvertibleTo(Json::uintValue);
81     if (ret) {
82       *out = in.asUInt();
83     }
84   } else {
85     unsigned long val;  // NOLINT
86     const char* c_str = in.asCString();
87     char* end_ptr;
88     errno = 0;
89     val = strtoul(c_str, &end_ptr, 10);  // NOLINT
90     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
91            val <= UINT_MAX);
92     *out = val;
93   }
94   return ret;
95 }
96
97 bool GetBoolFromJson(const Json::Value& in, bool* out) {
98   bool ret;
99   if (!in.isString()) {
100     ret = in.isConvertibleTo(Json::booleanValue);
101     if (ret) {
102       *out = in.asBool();
103     }
104   } else {
105     if (in.asString() == "true") {
106       *out = true;
107       ret = true;
108     } else if (in.asString() == "false") {
109       *out = false;
110       ret = true;
111     } else {
112       ret = false;
113     }
114   }
115   return ret;
116 }
117
118 bool GetDoubleFromJson(const Json::Value& in, double* out) {
119   bool ret;
120   if (!in.isString()) {
121     ret = in.isConvertibleTo(Json::realValue);
122     if (ret) {
123       *out = in.asDouble();
124     }
125   } else {
126     double val;
127     const char* c_str = in.asCString();
128     char* end_ptr;
129     errno = 0;
130     val = strtod(c_str, &end_ptr);
131     ret = (end_ptr != c_str && *end_ptr == '\0' && !errno);
132     *out = val;
133   }
134   return ret;
135 }
136
137 namespace {
138 template<typename T>
139 bool JsonArrayToVector(const Json::Value& value,
140                        bool (*getter)(const Json::Value& in, T* out),
141                        std::vector<T> *vec) {
142   vec->clear();
143   if (!value.isArray()) {
144     return false;
145   }
146
147   for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) {
148     T val;
149     if (!getter(value[i], &val)) {
150       return false;
151     }
152     vec->push_back(val);
153   }
154
155   return true;
156 }
157 // Trivial getter helper
158 bool GetValueFromJson(const Json::Value& in, Json::Value* out) {
159   *out = in;
160   return true;
161 }
162 }  // unnamed namespace
163
164 bool JsonArrayToValueVector(const Json::Value& in,
165                             std::vector<Json::Value>* out) {
166   return JsonArrayToVector(in, GetValueFromJson, out);
167 }
168
169 bool JsonArrayToIntVector(const Json::Value& in,
170                           std::vector<int>* out) {
171   return JsonArrayToVector(in, GetIntFromJson, out);
172 }
173
174 bool JsonArrayToUIntVector(const Json::Value& in,
175                            std::vector<unsigned int>* out) {
176   return JsonArrayToVector(in, GetUIntFromJson, out);
177 }
178
179 bool JsonArrayToStringVector(const Json::Value& in,
180                              std::vector<std::string>* out) {
181   return JsonArrayToVector(in, GetStringFromJson, out);
182 }
183
184 bool JsonArrayToBoolVector(const Json::Value& in,
185                            std::vector<bool>* out) {
186   return JsonArrayToVector(in, GetBoolFromJson, out);
187 }
188
189 bool JsonArrayToDoubleVector(const Json::Value& in,
190                              std::vector<double>* out) {
191   return JsonArrayToVector(in, GetDoubleFromJson, out);
192 }
193
194 namespace {
195 template<typename T>
196 Json::Value VectorToJsonArray(const std::vector<T>& vec) {
197   Json::Value result(Json::arrayValue);
198   for (size_t i = 0; i < vec.size(); ++i) {
199     result.append(Json::Value(vec[i]));
200   }
201   return result;
202 }
203 }  // unnamed namespace
204
205 Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in) {
206   return VectorToJsonArray(in);
207 }
208
209 Json::Value IntVectorToJsonArray(const std::vector<int>& in) {
210   return VectorToJsonArray(in);
211 }
212
213 Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in) {
214   return VectorToJsonArray(in);
215 }
216
217 Json::Value StringVectorToJsonArray(const std::vector<std::string>& in) {
218   return VectorToJsonArray(in);
219 }
220
221 Json::Value BoolVectorToJsonArray(const std::vector<bool>& in) {
222   return VectorToJsonArray(in);
223 }
224
225 Json::Value DoubleVectorToJsonArray(const std::vector<double>& in) {
226   return VectorToJsonArray(in);
227 }
228
229 bool GetValueFromJsonArray(const Json::Value& in, size_t n,
230                            Json::Value* out) {
231   if (!in.isArray() || !in.isValidIndex(static_cast<int>(n))) {
232     return false;
233   }
234
235   *out = in[static_cast<Json::Value::ArrayIndex>(n)];
236   return true;
237 }
238
239 bool GetIntFromJsonArray(const Json::Value& in, size_t n,
240                          int* out) {
241   Json::Value x;
242   return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out);
243 }
244
245 bool GetUIntFromJsonArray(const Json::Value& in, size_t n,
246                           unsigned int* out)  {
247   Json::Value x;
248   return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out);
249 }
250
251 bool GetStringFromJsonArray(const Json::Value& in, size_t n,
252                             std::string* out) {
253   Json::Value x;
254   return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out);
255 }
256
257 bool GetBoolFromJsonArray(const Json::Value& in, size_t n,
258                           bool* out) {
259   Json::Value x;
260   return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out);
261 }
262
263 bool GetDoubleFromJsonArray(const Json::Value& in, size_t n,
264                             double* out) {
265   Json::Value x;
266   return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out);
267 }
268
269 bool GetValueFromJsonObject(const Json::Value& in, const std::string& k,
270                             Json::Value* out) {
271   if (!in.isObject() || !in.isMember(k)) {
272     return false;
273   }
274
275   *out = in[k];
276   return true;
277 }
278
279 bool GetIntFromJsonObject(const Json::Value& in, const std::string& k,
280                           int* out) {
281   Json::Value x;
282   return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out);
283 }
284
285 bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k,
286                            unsigned int* out)  {
287   Json::Value x;
288   return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out);
289 }
290
291 bool GetStringFromJsonObject(const Json::Value& in, const std::string& k,
292                              std::string* out)  {
293   Json::Value x;
294   return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out);
295 }
296
297 bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k,
298                            bool* out) {
299   Json::Value x;
300   return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out);
301 }
302
303 bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k,
304                              double* out) {
305   Json::Value x;
306   return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out);
307 }
308
309 std::string JsonValueToString(const Json::Value& json) {
310   Json::FastWriter w;
311   std::string value = w.write(json);
312   return value.substr(0, value.size() - 1);  // trim trailing newline
313 }