Home | History | Annotate | Download | only in base
      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 
     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 
     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 
     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 
     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 
    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>
    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
    141 bool GetValueFromJson(const Json::Value& in, Json::Value* out) {
    142   *out = in;
    143   return true;
    144 }
    145 }  // unnamed namespace
    146 
    147 bool JsonArrayToValueVector(const Json::Value& in,
    148                             std::vector<Json::Value>* out) {
    149   return JsonArrayToVector(in, GetValueFromJson, out);
    150 }
    151 
    152 bool JsonArrayToIntVector(const Json::Value& in,
    153                           std::vector<int>* out) {
    154   return JsonArrayToVector(in, GetIntFromJson, out);
    155 }
    156 
    157 bool JsonArrayToUIntVector(const Json::Value& in,
    158                            std::vector<unsigned int>* out) {
    159   return JsonArrayToVector(in, GetUIntFromJson, out);
    160 }
    161 
    162 bool JsonArrayToStringVector(const Json::Value& in,
    163                              std::vector<std::string>* out) {
    164   return JsonArrayToVector(in, GetStringFromJson, out);
    165 }
    166 
    167 bool JsonArrayToBoolVector(const Json::Value& in,
    168                            std::vector<bool>* out) {
    169   return JsonArrayToVector(in, GetBoolFromJson, out);
    170 }
    171 
    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>
    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 
    188 Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in) {
    189   return VectorToJsonArray(in);
    190 }
    191 
    192 Json::Value IntVectorToJsonArray(const std::vector<int>& in) {
    193   return VectorToJsonArray(in);
    194 }
    195 
    196 Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in) {
    197   return VectorToJsonArray(in);
    198 }
    199 
    200 Json::Value StringVectorToJsonArray(const std::vector<std::string>& in) {
    201   return VectorToJsonArray(in);
    202 }
    203 
    204 Json::Value BoolVectorToJsonArray(const std::vector<bool>& in) {
    205   return VectorToJsonArray(in);
    206 }
    207 
    208 Json::Value DoubleVectorToJsonArray(const std::vector<double>& in) {
    209   return VectorToJsonArray(in);
    210 }
    211 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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