00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "Json.h"
00032 #include <sstream>
00033 #include "Utility.h"
00034 #include <cstdio>
00035
00036 #ifdef _WIN32
00037 #ifdef GetObject
00038 #undef GetObject
00039 #endif
00040 #endif
00041
00042 #define C buffer[index]
00043
00044 #ifdef SOCKETS_NAMESPACE
00045 namespace SOCKETS_NAMESPACE {
00046 #endif
00047
00048
00049
00050 Json::Json() : m_type(TYPE_UNKNOWN)
00051 {
00052 }
00053
00054
00055
00056 Json::Json(char value) : m_type(TYPE_INTEGER), m_i_value(value)
00057 {
00058 }
00059
00060
00061
00062 Json::Json(short value) : m_type(TYPE_INTEGER), m_i_value(value)
00063 {
00064 }
00065
00066
00067
00068 Json::Json(long value) : m_type(TYPE_INTEGER), m_i_value(value)
00069 {
00070 }
00071
00072
00073
00074 Json::Json(double value) : m_type(TYPE_REAL), m_d_value(value)
00075 {
00076 }
00077
00078
00079
00080 Json::Json(const char *value) : m_type(TYPE_STRING), m_str_value(value)
00081 {
00082 }
00083
00084
00085
00086 Json::Json(const std::string& value) : m_type(TYPE_STRING), m_str_value(value)
00087 {
00088 }
00089
00090
00091
00092 Json::Json(bool value) : m_type(TYPE_BOOLEAN), m_b_value(value)
00093 {
00094 }
00095
00096
00097
00098 Json::Json(json_type_t t) : m_type(t)
00099 {
00100 if (t != TYPE_ARRAY && t != TYPE_OBJECT)
00101 throw Exception("Must be type: Array or type: Object");
00102 }
00103
00104
00105
00106 Json::~Json()
00107 {
00108 }
00109
00110
00111
00112 Json::json_type_t Json::Type() const { return m_type; }
00113
00114
00115
00116 bool Json::HasValue(const std::string& name) const
00117 {
00118 if (m_type != TYPE_OBJECT)
00119 return false;
00120 return m_object.find(name) != m_object.end();
00121 }
00122
00123
00124
00125 Json::operator char() const
00126 {
00127 return (char)m_i_value;
00128 }
00129
00130
00131
00132 Json::operator short() const
00133 {
00134 return (short)m_i_value;
00135 }
00136
00137
00138
00139 Json::operator long() const
00140 {
00141 return m_i_value;
00142 }
00143
00144
00145
00146 Json::operator double() const
00147 {
00148 return m_d_value;
00149 }
00150
00151
00152
00153 Json::operator std::string() const
00154 {
00155 return m_str_value;
00156 }
00157
00158
00159
00160 Json::operator bool() const
00161 {
00162 return m_b_value;
00163 }
00164
00165
00166
00167 const Json& Json::operator[](const char *name) const
00168 {
00169 if (m_type != TYPE_OBJECT)
00170 throw Exception("Must be type: Object");
00171 json_map_t::const_iterator it = m_object.find(name);
00172 if (it != m_object.end())
00173 return it -> second;
00174 throw Exception("Key not found: " + std::string(name));
00175 }
00176
00177
00178 Json& Json::operator[](const char *name)
00179 {
00180 if (m_type == TYPE_UNKNOWN)
00181 m_type = TYPE_OBJECT;
00182 if (m_type != TYPE_OBJECT)
00183 throw Exception("Must be type: Object");
00184 return m_object[name];
00185 }
00186
00187
00188
00189 const Json& Json::operator[](const std::string& name) const
00190 {
00191 if (m_type != TYPE_OBJECT)
00192 throw Exception("Must be type: Object");
00193 json_map_t::const_iterator it = m_object.find(name);
00194 if (it != m_object.end())
00195 return it -> second;
00196 throw Exception("Key not found: " + name);
00197 }
00198
00199
00200 Json& Json::operator[](const std::string& name)
00201 {
00202 if (m_type == TYPE_UNKNOWN)
00203 m_type = TYPE_OBJECT;
00204 if (m_type != TYPE_OBJECT)
00205 throw Exception("Must be type: Object");
00206 return m_object[name];
00207 }
00208
00209
00210
00211 void Json::Add(Json data)
00212 {
00213 if (m_type == TYPE_UNKNOWN)
00214 m_type = TYPE_ARRAY;
00215 if (m_type != TYPE_ARRAY)
00216 throw Exception("trying to add array data in non-array");
00217 m_array.push_back(data);
00218 }
00219
00220
00221
00222 const std::string& Json::GetString() const
00223 {
00224 return m_str_value;
00225 }
00226
00227
00228
00229 Json::json_list_t& Json::GetArray()
00230 {
00231 if (m_type == TYPE_UNKNOWN)
00232 m_type = TYPE_ARRAY;
00233 if (m_type != TYPE_ARRAY)
00234 throw Exception("Json instance not of type: Array");
00235 return m_array;
00236 }
00237
00238
00239
00240 Json::json_map_t& Json::GetObject()
00241 {
00242 if (m_type == TYPE_UNKNOWN)
00243 m_type = TYPE_OBJECT;
00244 if (m_type != TYPE_OBJECT)
00245 throw Exception("Json instance not of type: Array");
00246 return m_object;
00247 }
00248
00249
00250
00251 const Json::json_list_t& Json::GetArray() const
00252 {
00253 if (m_type != TYPE_ARRAY)
00254 throw Exception("Json instance not of type: Array");
00255 return m_array;
00256 }
00257
00258
00259
00260 const Json::json_map_t& Json::GetObject() const
00261 {
00262 if (m_type != TYPE_OBJECT)
00263 throw Exception("Json instance not of type: Array");
00264 return m_object;
00265 }
00266
00267
00268
00269 Json Json::Parse(const std::string& data)
00270 {
00271 size_t i = 0;
00272 Json obj;
00273 obj.Parse(data.c_str(), i);
00274 return obj;
00275 }
00276
00277
00278
00279 int Json::Token(const char *buffer, size_t& index, std::string& ord)
00280 {
00281 while (C == ' ' || C == 9 || C == 13 || C == 10)
00282 ++index;
00283 size_t x = index;
00284 if (C == '-' || isdigit(C))
00285 {
00286 bool dot = false;
00287 if (C == '-')
00288 {
00289 ++index;
00290 }
00291 while (isdigit(C) || C == '.')
00292 {
00293 if (C == '.')
00294 dot = true;
00295 ++index;
00296 }
00297 size_t sz = index - x;
00298 ord = std::string(buffer + x, sz);
00299 if (dot)
00300 {
00301 m_type = TYPE_REAL;
00302 }
00303 else
00304 {
00305 m_type = TYPE_INTEGER;
00306 }
00307 return -m_type;
00308 }
00309 else
00310 if (C == 34)
00311 {
00312 bool ign = false;
00313 x = ++index;
00314 while (C && (ign || C != 34))
00315 {
00316 if (ign)
00317 {
00318 ign = false;
00319 }
00320 else
00321 if (C == '\\')
00322 {
00323 ign = true;
00324 }
00325 ++index;
00326 }
00327 size_t sz = index - x;
00328 ord = std::string(buffer + x, sz);
00329 decode(ord);
00330 ++index;
00331 m_type = TYPE_STRING;
00332 return -m_type;
00333 }
00334 else
00335 if (!strncmp(&buffer[index], "null", 4))
00336 {
00337 m_type = TYPE_UNKNOWN;
00338 ord = std::string(buffer + x, 4);
00339 index += 4;
00340 return -m_type;
00341 }
00342 else
00343 if (!strncmp(&buffer[index], "true", 4))
00344 {
00345 m_type = TYPE_BOOLEAN;
00346 ord = std::string(buffer + x, 4);
00347 m_b_value = true;
00348 index += 4;
00349 return -m_type;
00350 }
00351 else
00352 if (!strncmp(&buffer[index], "false", 5))
00353 {
00354 m_type = TYPE_BOOLEAN;
00355 ord = std::string(buffer + x, 5);
00356 m_b_value = false;
00357 index += 5;
00358 return -m_type;
00359 }
00360 return buffer[index++];
00361 }
00362
00363
00364
00365 char Json::Parse(const char *buffer, size_t& index)
00366 {
00367 std::string ord;
00368 int token = Token(buffer, index, ord);
00369 if (token == -TYPE_REAL || token == -TYPE_INTEGER)
00370 {
00371 if (token == -TYPE_REAL)
00372 {
00373 m_d_value = atof(ord.c_str());
00374 }
00375 else
00376 {
00377 m_i_value = atoi(ord.c_str());
00378 }
00379 }
00380 else
00381 if (token == -TYPE_STRING)
00382 {
00383 m_str_value = ord;
00384 }
00385 else
00386 if (token == -TYPE_UNKNOWN)
00387 {
00388 }
00389 else
00390 if (token == -TYPE_BOOLEAN)
00391 {
00392 }
00393 else
00394 if (token == '[')
00395 {
00396 m_type = TYPE_ARRAY;
00397 while (true)
00398 {
00399 char res;
00400 Json o;
00401 if ((res = o.Parse(buffer, index)) == 0)
00402 {
00403 m_array.push_back(o);
00404 }
00405 else
00406 if (res == ']')
00407 {
00408 break;
00409 }
00410 else
00411 if (res == ',')
00412 {
00413 }
00414 else
00415 {
00416 throw Exception(std::string("Unexpected end of Array: ") + res);
00417 }
00418 }
00419 }
00420 else
00421 if (token == ']')
00422 {
00423 return ']';
00424 }
00425 else
00426 if (token == '{')
00427 {
00428 m_type = TYPE_OBJECT;
00429 int state = 0;
00430 std::string element_name;
00431 bool quit = false;
00432 while (!quit)
00433 {
00434 Json o;
00435 char res = o.Parse(buffer, index);
00436 switch (state)
00437 {
00438 case 0:
00439 if (res == ',')
00440 break;
00441 if (res == '}')
00442 {
00443 quit = true;
00444 break;
00445 }
00446 if (res || o.Type() != TYPE_STRING)
00447 throw Exception("Object element name missing");
00448 element_name = o.GetString();
00449 state = 1;
00450 break;
00451 case 1:
00452 if (res != ':')
00453 throw Exception("Object element separator missing");
00454 state = 2;
00455 break;
00456 case 2:
00457 if (res)
00458 throw Exception(std::string("Unexpected character when parsing anytype: ") + res);
00459 m_object[element_name] = o;
00460 state = 0;
00461 break;
00462 }
00463 }
00464 }
00465 else
00466 if (token == '}')
00467 {
00468 return '}';
00469 }
00470 else
00471 if (token == ',')
00472 {
00473 return ',';
00474 }
00475 else
00476 if (token == ':')
00477 {
00478 return ':';
00479 }
00480 else
00481 {
00482 throw Exception("Can't parse Json representation: " + std::string(&buffer[index]));
00483 }
00484 return 0;
00485 }
00486
00487
00488
00489 std::string Json::ToString(bool quote) const
00490 {
00491 switch (m_type)
00492 {
00493 case TYPE_UNKNOWN:
00494 break;
00495 case TYPE_INTEGER:
00496 return Utility::l2string(m_i_value);
00497 case TYPE_REAL:
00498 {
00499 char slask[100];
00500 sprintf(slask, "%f", m_d_value);
00501 return slask;
00502 }
00503 case TYPE_STRING:
00504 {
00505 std::ostringstream tmp;
00506 tmp << "\"" << encode(m_str_value) << "\"";
00507 return tmp.str();
00508 }
00509 case TYPE_BOOLEAN:
00510 return m_b_value ? "true" : "false";
00511 case TYPE_ARRAY:
00512 {
00513 std::ostringstream tmp;
00514 bool first = true;
00515 tmp << "[";
00516 for (json_list_t::const_iterator it = m_array.begin(); it != m_array.end(); it++)
00517 {
00518 const Json& ref = *it;
00519 if (!first)
00520 tmp << ",";
00521 tmp << ref.ToString(quote);
00522 first = false;
00523 }
00524 tmp << "]";
00525 return tmp.str();
00526 }
00527 case TYPE_OBJECT:
00528 {
00529 std::ostringstream tmp;
00530 bool first = true;
00531 tmp << "{";
00532 for (json_map_t::const_iterator it = m_object.begin(); it != m_object.end(); it++)
00533 {
00534 const std::pair<std::string, Json>& ref = *it;
00535 if (!first)
00536 tmp << ",";
00537 if (quote)
00538 tmp << "\"" << encode(ref.first) << "\":" << ref.second.ToString(quote);
00539 else
00540 tmp << ref.first << ":" << ref.second.ToString(quote);
00541 first = false;
00542 }
00543 tmp << "}";
00544 return tmp.str();
00545 }
00546 }
00547 return "null";
00548 }
00549
00550
00551
00552 void Json::encode(std::string& src) const
00553 {
00554 size_t pos = src.find("\\");
00555 while (pos != std::string::npos)
00556 {
00557 src.replace(pos, 1, "\\\\");
00558 pos = src.find("\\", pos + 2);
00559 }
00560 pos = src.find("\r");
00561 while (pos != std::string::npos)
00562 {
00563 src.replace(pos, 1, "\\r");
00564 pos = src.find("\r", pos + 2);
00565 }
00566 pos = src.find("\n");
00567 while (pos != std::string::npos)
00568 {
00569 src.replace(pos, 1, "\\n");
00570 pos = src.find("\n", pos + 2);
00571 }
00572 pos = src.find("\"");
00573 while (pos != std::string::npos)
00574 {
00575 src.replace(pos, 1, "\\\"");
00576 pos = src.find("\"", pos + 2);
00577 }
00578 }
00579
00580
00581
00582 void Json::decode(std::string& src) const
00583 {
00584 size_t pos = src.find("\\\"");
00585 while (pos != std::string::npos)
00586 {
00587 src.replace(pos, 2, "\"");
00588 pos = src.find("\\\"", pos + 1);
00589 }
00590 pos = src.find("\\r");
00591 while (pos != std::string::npos)
00592 {
00593 src.replace(pos, 2, "\r");
00594 pos = src.find("\\r", pos + 1);
00595 }
00596 pos = src.find("\\n");
00597 while (pos != std::string::npos)
00598 {
00599 src.replace(pos, 2, "\n");
00600 pos = src.find("\\n", pos + 1);
00601 }
00602 pos = src.find("\\\\");
00603 while (pos != std::string::npos)
00604 {
00605 src.replace(pos, 2, "\\");
00606 pos = src.find("\\\\", pos + 1);
00607 }
00608 }
00609
00610
00611
00612 std::string Json::encode(const std::string& src) const
00613 {
00614 std::string tmp(src);
00615 encode(tmp);
00616 return tmp;
00617 }
00618
00619
00620 #ifdef SOCKETS_NAMESPACE
00621 }
00622 #endif
00623