You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

json.cpp 18KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. #include "json.h"
  2. #include <cstdlib>
  3. #include <string>
  4. #include <algorithm>
  5. #include <cstdlib>
  6. #include <cstdio>
  7. #include <climits>
  8. #include <cstring>
  9. #include <functional>
  10. #include <cctype>
  11. #include <stack>
  12. #ifndef WIN32
  13. # define _stricmp strcasecmp
  14. #endif
  15. #ifdef _MSC_VER
  16. # define snprintf sprintf_s
  17. #endif
  18. using namespace json;
  19. namespace json {
  20. enum StackDepthType
  21. {
  22. InObject,
  23. InArray
  24. };
  25. }
  26. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. // Helper functions
  28. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  29. static std::string Trim(const std::string& str)
  30. {
  31. std::string s = str;
  32. // remove white space in front
  33. s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
  34. // remove trailing white space
  35. s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
  36. return s;
  37. }
  38. // Finds the position of the first " character that is NOT preceeded immediately by a \ character.
  39. // In JSON, \" is valid and has a different meaning than the escaped " character.
  40. static size_t GetQuotePos(const std::string& str, const size_t start_pos = 0)
  41. {
  42. bool found_slash = false;
  43. for (size_t i = start_pos; i < str.length(); ++i)
  44. {
  45. const char c = str[i];
  46. if ((c == '\\') && !found_slash)
  47. {
  48. found_slash = true;
  49. continue;
  50. }
  51. if ((c == '\"') && !found_slash) { return i; }
  52. found_slash = false;
  53. }
  54. return std::string::npos;
  55. }
  56. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. Value::Value(const Value& v) : mValueType(v.mValueType)
  59. {
  60. switch (mValueType)
  61. {
  62. case StringVal: mStringVal = v.mStringVal;
  63. break;
  64. case IntVal: mIntVal = v.mIntVal;
  65. mFloatVal = float(v.mIntVal);
  66. mDoubleVal = double(v.mIntVal);
  67. break;
  68. case FloatVal: mFloatVal = v.mFloatVal;
  69. mIntVal = int(v.mFloatVal);
  70. mDoubleVal = double(v.mDoubleVal);
  71. break;
  72. case DoubleVal: mDoubleVal = v.mDoubleVal;
  73. mIntVal = int(v.mDoubleVal);
  74. mFloatVal = float(v.mDoubleVal);
  75. break;
  76. case BoolVal: mBoolVal = v.mBoolVal;
  77. break;
  78. case ObjectVal: mObjectVal = v.mObjectVal;
  79. break;
  80. case ArrayVal: mArrayVal = v.mArrayVal;
  81. break;
  82. default: break;
  83. }
  84. }
  85. Value& Value::operator =(const Value& v)
  86. {
  87. if (&v == this) { return *this; }
  88. mValueType = v.mValueType;
  89. switch (mValueType)
  90. {
  91. case StringVal: mStringVal = v.mStringVal;
  92. break;
  93. case IntVal: mIntVal = v.mIntVal;
  94. mFloatVal = float(v.mIntVal);
  95. mDoubleVal = double(v.mIntVal);
  96. break;
  97. case FloatVal: mFloatVal = v.mFloatVal;
  98. mIntVal = int(v.mFloatVal);
  99. mDoubleVal = double(v.mDoubleVal);
  100. break;
  101. case DoubleVal: mDoubleVal = v.mDoubleVal;
  102. mIntVal = int(v.mDoubleVal);
  103. mFloatVal = float(v.mDoubleVal);
  104. break;
  105. case BoolVal: mBoolVal = v.mBoolVal;
  106. break;
  107. case ObjectVal: mObjectVal = v.mObjectVal;
  108. break;
  109. case ArrayVal: mArrayVal = v.mArrayVal;
  110. break;
  111. default: break;
  112. }
  113. return *this;
  114. }
  115. Value& Value::operator [](const size_t idx)
  116. {
  117. assert(mValueType == ArrayVal);
  118. return mArrayVal[idx];
  119. }
  120. const Value& Value::operator [](const size_t idx) const
  121. {
  122. assert(mValueType == ArrayVal);
  123. return mArrayVal[idx];
  124. }
  125. Value& Value::operator [](const std::string& key)
  126. {
  127. assert(mValueType == ObjectVal);
  128. return mObjectVal[key];
  129. }
  130. Value& Value::operator [](const char* key)
  131. {
  132. assert(mValueType == ObjectVal);
  133. return mObjectVal[key];
  134. }
  135. const Value& Value::operator [](const char* key) const
  136. {
  137. assert(mValueType == ObjectVal);
  138. return mObjectVal[key];
  139. }
  140. const Value& Value::operator [](const std::string& key) const
  141. {
  142. assert(mValueType == ObjectVal);
  143. return mObjectVal[key];
  144. }
  145. size_t Value::size() const
  146. {
  147. if ((mValueType != ObjectVal) && (mValueType != ArrayVal)) { return 1; }
  148. return mValueType == ObjectVal ? mObjectVal.size() : mArrayVal.size();
  149. }
  150. bool Value::HasKey(const std::string& key) const
  151. {
  152. assert(mValueType == ObjectVal);
  153. return mObjectVal.HasKey(key);
  154. }
  155. int Value::HasKeys(const std::vector<std::string>& keys) const
  156. {
  157. assert(mValueType == ObjectVal);
  158. return mObjectVal.HasKeys(keys);
  159. }
  160. int Value::HasKeys(const char** keys, const int key_count) const
  161. {
  162. assert(mValueType == ObjectVal);
  163. return mObjectVal.HasKeys(keys, key_count);
  164. }
  165. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  166. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  167. Array& Array::operator =(const Array& a)
  168. {
  169. if (&a == this) { return *this; }
  170. Clear();
  171. mValues = a.mValues;
  172. return *this;
  173. }
  174. Value& Array::operator [](const size_t i) { return mValues[i]; }
  175. const Value& Array::operator [](const size_t i) const { return mValues[i]; }
  176. Array::ValueVector::const_iterator Array::begin() const { return mValues.begin(); }
  177. Array::ValueVector::const_iterator Array::end() const { return mValues.end(); }
  178. Array::ValueVector::iterator Array::begin() { return mValues.begin(); }
  179. Array::ValueVector::iterator Array::end() { return mValues.end(); }
  180. void Array::push_back(const Value& v) { mValues.push_back(v); }
  181. void Array::insert(const size_t index, const Value& v) { mValues.insert(mValues.begin() + index, v); }
  182. Array::ValueVector::iterator Array::find(const Value& v) { return std::find(mValues.begin(), mValues.end(), v); }
  183. Array::ValueVector::const_iterator Array::find(const Value& v) const { return std::find(mValues.begin(), mValues.end(), v); }
  184. bool Array::HasValue(const Value& v) const { return find(v) != end(); }
  185. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  186. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  187. Object& Object::operator =(const Object& obj)
  188. {
  189. if (&obj == this) { return *this; }
  190. Clear();
  191. mValues = obj.mValues;
  192. return *this;
  193. }
  194. Value& Object::operator [](const std::string& key) { return mValues[key]; }
  195. const Value& Object::operator [](const std::string& key) const { return mValues.find(key)->second; }
  196. Value& Object::operator [](const char* key) { return mValues[key]; }
  197. const Value& Object::operator [](const char* key) const { return mValues.find(key)->second; }
  198. Object::ValueMap::const_iterator Object::begin() const { return mValues.begin(); }
  199. Object::ValueMap::const_iterator Object::end() const { return mValues.end(); }
  200. Object::ValueMap::iterator Object::begin() { return mValues.begin(); }
  201. Object::ValueMap::iterator Object::end() { return mValues.end(); }
  202. Object::ValueMap::iterator Object::find(const std::string& key) { return mValues.find(key); }
  203. Object::ValueMap::const_iterator Object::find(const std::string& key) const { return mValues.find(key); }
  204. bool Object::HasKey(const std::string& key) const { return find(key) != end(); }
  205. int Object::HasKeys(const std::vector<std::string>& keys) const
  206. {
  207. for (size_t i = 0; i < keys.size(); ++i) { if (!HasKey(keys[i])) { return int(i); } }
  208. return -1;
  209. }
  210. int Object::HasKeys(const char** keys, const int key_count) const
  211. {
  212. for (int i = 0; i < key_count; ++i) { if (!HasKey(keys[i])) { return i; } }
  213. return -1;
  214. }
  215. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  216. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. std::string SerializeArray(const Array& a);
  218. std::string SerializeValue(const Value& v)
  219. {
  220. std::string str;
  221. static const int BUFF_SZ = 500;
  222. char buff[BUFF_SZ];
  223. switch (v.GetType())
  224. {
  225. case IntVal: snprintf(buff, BUFF_SZ, "%d", int(v));
  226. str = buff;
  227. break;
  228. case FloatVal: snprintf(buff, BUFF_SZ, "%f", float(v));
  229. str = buff;
  230. break;
  231. case DoubleVal: snprintf(buff, BUFF_SZ, "%f", double(v));
  232. str = buff;
  233. break;
  234. case BoolVal: str = v ? "true" : "false";
  235. break;
  236. case nullptrVal: str = "null";
  237. break;
  238. case ObjectVal: str = Serialize(v);
  239. break;
  240. case ArrayVal: str = SerializeArray(v);
  241. break;
  242. case StringVal: str = std::string("\"") + v.ToString() + std::string("\"");
  243. break;
  244. }
  245. return str;
  246. }
  247. std::string SerializeArray(const Array& a)
  248. {
  249. std::string str = "[";
  250. bool first = true;
  251. for (const auto& v : a)
  252. {
  253. if (!first) { str += std::string(","); }
  254. str += SerializeValue(v);
  255. first = false;
  256. }
  257. str += "]";
  258. return str;
  259. }
  260. std::string json::Serialize(const Value& v)
  261. {
  262. std::string str;
  263. bool first = true;
  264. if (v.GetType() == ObjectVal)
  265. {
  266. str = "{";
  267. Object obj = v.ToObject();
  268. for (auto it = obj.begin(); it != obj.end(); ++it)
  269. {
  270. if (!first) { str += std::string(","); }
  271. str += std::string("\"") + it->first + std::string("\":") + SerializeValue(it->second);
  272. first = false;
  273. }
  274. str += "}";
  275. }
  276. else if (v.GetType() == ArrayVal)
  277. {
  278. str = "[";
  279. Array a = v.ToArray();
  280. for (auto it = a.begin(); it != a.end(); ++it)
  281. {
  282. if (!first) { str += std::string(","); }
  283. str += SerializeValue(*it);
  284. first = false;
  285. }
  286. str += "]";
  287. }
  288. //else error
  289. return str;
  290. }
  291. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  292. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  293. static Value DeserializeArray(std::string& str, std::stack<StackDepthType>& depth_stack);
  294. static Value DeserializeObj(const std::string& _str, std::stack<StackDepthType>& depth_stack);
  295. static Value DeserializeInternal(const std::string& _str, std::stack<StackDepthType>& depth_stack)
  296. {
  297. Value v;
  298. if (_str.length() == 0) { return v; }
  299. std::string str = Trim(_str);
  300. if (str[0] == '{')
  301. {
  302. // Error: Began with a { but doesn't end with one
  303. if (str[str.length() - 1] != '}') { return Value(); }
  304. depth_stack.push(InObject);
  305. v = DeserializeObj(str, depth_stack);
  306. if ((v.GetType() == nullptrVal) || (depth_stack.top() != InObject)) { return v; }
  307. depth_stack.pop();
  308. }
  309. else if (str[0] == '[')
  310. {
  311. // Error: Began with a [ but doesn't end with one
  312. if (str[str.length() - 1] != ']') { return Value(); }
  313. depth_stack.push(InArray);
  314. v = DeserializeArray(str, depth_stack);
  315. if ((v.GetType() == nullptrVal) || (depth_stack.top() != InArray)) { return v; }
  316. depth_stack.pop();
  317. }
  318. else { return Value(); } // Will never get here unless _str is not valid JSON
  319. return v;
  320. }
  321. static size_t GetEndOfArrayOrObj(const std::string& str, std::stack<StackDepthType>& depth_stack)
  322. {
  323. size_t i = 1;
  324. bool in_quote = false;
  325. const size_t original_count = depth_stack.size();
  326. for (; i < str.length(); ++i)
  327. {
  328. if (str[i] == '\"') { if (str[i - 1] != '\\') { in_quote = !in_quote; } }
  329. else if (!in_quote)
  330. {
  331. if (str[i] == '[') { depth_stack.push(InArray); }
  332. else if (str[i] == '{') { depth_stack.push(InObject); }
  333. else if (str[i] == ']')
  334. {
  335. const StackDepthType t = depth_stack.top();
  336. // expected to be closing an array but instead we're inside an object block.
  337. // Example problem: {]}
  338. if (t != InArray) { return std::string::npos; }
  339. const size_t count = depth_stack.size();
  340. depth_stack.pop();
  341. if (count == original_count) { break; }
  342. }
  343. else if (str[i] == '}')
  344. {
  345. const StackDepthType t = depth_stack.top();
  346. // expected to be closing an object but instead we're inside an array.
  347. // Example problem: [}]
  348. if (t != InObject) { return std::string::npos; }
  349. const size_t count = depth_stack.size();
  350. depth_stack.pop();
  351. if (count == original_count) { break; }
  352. }
  353. }
  354. }
  355. return i;
  356. }
  357. static std::string UnescapeJSONString(const std::string& str)
  358. {
  359. std::string s;
  360. for (size_t i = 0; i < str.length(); ++i)
  361. {
  362. const char c = str[i];
  363. if ((c == '\\') && (i + 1 < str.length()))
  364. {
  365. int skip_ahead = 1;
  366. unsigned int hex;
  367. std::string hex_str;
  368. switch (str[i + 1])
  369. {
  370. case '"': s.push_back('\"');
  371. break;
  372. case '\\': s.push_back('\\');
  373. break;
  374. case '/': s.push_back('/');
  375. break;
  376. case 't': s.push_back('\t');
  377. break;
  378. case 'n': s.push_back('\n');
  379. break;
  380. case 'r': s.push_back('\r');
  381. break;
  382. case 'b': s.push_back('\b');
  383. break;
  384. case 'f': s.push_back('\f');
  385. break;
  386. case 'u': skip_ahead = 5;
  387. hex_str = str.substr(i + 4, 2);
  388. hex = static_cast<unsigned int>(std::strtoul(hex_str.c_str(), nullptr, 16));
  389. s.push_back(char(hex));
  390. break;
  391. default: break;
  392. }
  393. i += skip_ahead;
  394. }
  395. else { s.push_back(c); }
  396. }
  397. return Trim(s);
  398. }
  399. static Value DeserializeValue(std::string& str, bool* had_error, std::stack<StackDepthType>& depth_stack)
  400. {
  401. Value v;
  402. *had_error = false;
  403. str = Trim(str);
  404. if (str.length() == 0) { return v; }
  405. if (str[0] == '[')
  406. {
  407. depth_stack.push(InArray);
  408. size_t i = GetEndOfArrayOrObj(str, depth_stack);
  409. if (i == std::string::npos)
  410. {
  411. *had_error = true;
  412. return Value();
  413. }
  414. std::string array_str = str.substr(0, i + 1);
  415. v = Value(DeserializeArray(array_str, depth_stack));
  416. str = str.substr(i + 1, str.length());
  417. }
  418. else if (str[0] == '{')
  419. {
  420. depth_stack.push(InObject);
  421. size_t i = GetEndOfArrayOrObj(str, depth_stack);
  422. if (i == std::string::npos)
  423. {
  424. *had_error = true;
  425. return Value();
  426. }
  427. std::string obj_str = str.substr(0, i + 1);
  428. v = Value(DeserializeInternal(obj_str, depth_stack));
  429. str = str.substr(i + 1, str.length());
  430. }
  431. else if (str[0] == '\"')
  432. {
  433. size_t end_quote = GetQuotePos(str, 1);
  434. if (end_quote == std::string::npos)
  435. {
  436. *had_error = true;
  437. return Value();
  438. }
  439. v = Value(UnescapeJSONString(str.substr(1, end_quote - 1)));
  440. str = str.substr(end_quote + 1, str.length());
  441. }
  442. else
  443. {
  444. bool has_dot = false;
  445. bool has_e = false;
  446. std::string temp_val;
  447. size_t i = 0;
  448. for (; i < str.length(); ++i)
  449. {
  450. if (str[i] == '.') { has_dot = true; }
  451. else if (str[i] == 'e') { has_e = true; }
  452. else if (str[i] == ']')
  453. {
  454. if (depth_stack.top() != InArray)
  455. {
  456. *had_error = true;
  457. return Value();
  458. }
  459. depth_stack.pop();
  460. }
  461. else if (str[i] == '}')
  462. {
  463. if (depth_stack.top() != InObject)
  464. {
  465. *had_error = true;
  466. return Value();
  467. }
  468. depth_stack.pop();
  469. }
  470. else if (str[i] == ',') { break; }
  471. if (std::isspace(str[i]) == 0) { temp_val += str[i]; }
  472. }
  473. // store all floating point as doubles. This will also set the float and int values as well.
  474. if (_stricmp(temp_val.c_str(), "true") == 0) { v = Value(true); }
  475. else if (_stricmp(temp_val.c_str(), "false") == 0) { v = Value(false); }
  476. else if (has_e || has_dot) { v = Value(strtod(temp_val.c_str(), nullptr)); }
  477. else if (_stricmp(temp_val.c_str(), "null") == 0) { v = Value(); }
  478. else
  479. {
  480. // Check if the value is beyond the size of an int and if so, store it as a double
  481. double tmp_val = strtod(temp_val.c_str(), nullptr);
  482. if ((tmp_val >= double(INT_MIN)) && (tmp_val <= double(INT_MAX))) { v = Value(int(strtol(temp_val.c_str(), nullptr, 10))); }
  483. else { v = Value(tmp_val); }
  484. }
  485. str = str.substr(i, str.length());
  486. }
  487. return v;
  488. }
  489. static Value DeserializeArray(std::string& str, std::stack<StackDepthType>& depth_stack)
  490. {
  491. Array a;
  492. bool had_error = false;
  493. str = Trim(str);
  494. if ((str[0] == '[') && (str[str.length() - 1] == ']')) { str = str.substr(1, str.length() - 2); }
  495. else { return Value(); }
  496. while (str.length() > 0)
  497. {
  498. std::string tmp;
  499. size_t i = 0;
  500. for (; i < str.length(); ++i)
  501. {
  502. // If we get to an object or array, parse it:
  503. if ((str[i] == '{') || (str[i] == '['))
  504. {
  505. Value v = DeserializeValue(str, &had_error, depth_stack);
  506. if (had_error) { return Value(); }
  507. if (v.GetType() != nullptrVal) { a.push_back(v); }
  508. break;
  509. }
  510. bool terminate_parsing = false;
  511. if ((str[i] == ',') || (str[i] == ']'))
  512. {
  513. terminate_parsing = true; // hit the end of a value, parse it in the next block
  514. }
  515. else
  516. {
  517. // keep grabbing chars to build up the value
  518. tmp += str[i];
  519. if (i == str.length() - 1) { terminate_parsing = true; } // end of string, finish parsing
  520. }
  521. if (terminate_parsing)
  522. {
  523. Value v = DeserializeValue(tmp, &had_error, depth_stack);
  524. if (had_error) { return Value(); }
  525. if (v.GetType() != nullptrVal) { a.push_back(v); }
  526. str = str.substr(i + 1, str.length());
  527. break;
  528. }
  529. }
  530. }
  531. return a;
  532. }
  533. static Value DeserializeObj(const std::string& _str, std::stack<StackDepthType>& depth_stack)
  534. {
  535. Object obj;
  536. std::string str = Trim(_str);
  537. if ((str[0] != '{') && (str[str.length() - 1] != '}')) { return Value(); }
  538. str = str.substr(1, str.length() - 2);
  539. while (str.length() > 0)
  540. {
  541. // Get the key name
  542. const size_t start_quote_idx = GetQuotePos(str);
  543. const size_t end_quote_idx = GetQuotePos(str, start_quote_idx + 1);
  544. const size_t colon_idx = str.find(':', end_quote_idx);
  545. if ((start_quote_idx == std::string::npos) || (end_quote_idx == std::string::npos) || (colon_idx == std::string::npos))
  546. {
  547. return Value(); // can't find key name
  548. }
  549. std::string key = str.substr(start_quote_idx + 1, end_quote_idx - start_quote_idx - 1);
  550. if (key.length() == 0) { return Value(); }
  551. bool had_error = false;
  552. str = str.substr(colon_idx + 1, str.length());
  553. obj[key] = DeserializeValue(str, &had_error, depth_stack);
  554. if (had_error) { return Value(); }
  555. }
  556. return obj;
  557. }
  558. Value json::Deserialize(const std::string& str)
  559. {
  560. std::stack<StackDepthType> depth_stack;
  561. return DeserializeInternal(str, depth_stack);
  562. }