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.h 19KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /*
  2. SuperEasyJSON
  3. http://www.sourceforge.net/p/supereasyjson
  4. The MIT License (MIT)
  5. Copyright (c) 2013 Jeff Weinstein (jeff.weinstein at gmail)
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. CHANGELOG:
  22. ==========
  23. 2/8/2014:
  24. ---------
  25. MAJOR BUG FIXES, all courtesy of Per Rovegård, Ph.D.
  26. * Feature request: HasKey and HasKeys added to Value for convenience and
  27. to avoid having to make a temporary object.
  28. * Strings should now be properly unescaped. Previously, as an example, the
  29. string "\/Date(1390431949211+0100)\/\" would be parsed as
  30. \/Date(1390431949211+0100)\/. The string is now properly parsed as
  31. /Date(1390431949211+0100)/.
  32. As per http://www.json.org the other escape characters including
  33. \u+4 hex digits will now be properly unescaped. So for example,
  34. \u0061 now becomes "A".
  35. * Serialize now supports serializing a toplevel array (which is valid JSON).
  36. The parameter it takes is now a Value, but existing code doesn't
  37. need to be changed.
  38. * Fixed bug with checking for proper opening/closing sequence for braces/brackets.
  39. Previously, this code:
  40. const char *json = "{\"arr\":[{ }}]}";
  41. auto val = json::Deserialize(json);
  42. worked fine with no errors. That's a bug. I did a major overhaul so that
  43. now improperly formatted pairs will now correctly result in an error.
  44. * Made internal deserialize methods static
  45. 1/30/2014:
  46. ----------
  47. * Changed #pragma once to the standard #ifndef header guard style for
  48. better compatibility.
  49. * Added a [] operator for Value that takes a const char* as an argument
  50. to avoid having to explicitly (and annoyingly) cast to std::string.
  51. Thus, my_value["asdf"] = "a string" should now work fine.
  52. The same has been added to the Object class.
  53. * Added non-operator methods of casting a Value to int/string/bool/etc.
  54. Implicitly casting a Value to a std::string doesn't work as per C++
  55. rules. As such, previously to assign a Value to a std::string you
  56. had to do:
  57. my_std_string = (std::string)my_value;
  58. You can now instead do:
  59. my_std_string = my_value.ToString();
  60. If you want more information on why this can't be done, please read
  61. this topic for more details:
  62. http://stackoverflow.com/questions/3518145/c-overloading-conversion-operator-for-custom-type-to-stdstring
  63. 1/27/2014
  64. ----------
  65. * Deserialize will now return a nullptrType Value instance if there was an
  66. error instead of asserting. This way you can handle however you want to
  67. invalid JSON being passed in. As a top level object must be either an
  68. array or an object, a nullptr value return indicates an invalid result.
  69. 1/11/2014
  70. ---------
  71. * Major bug fix: Strings containing []{ } characters could cause
  72. parsing errors under certain conditions. I've just tested
  73. the class parsing a 300KB JSON file with all manner of bizarre
  74. characters and permutations and it worked, so hopefully this should
  75. be the end of "major bug" fixes.
  76. 1/10/2014
  77. ---------
  78. Bug fixes courtesy of Gerry Beauregard:
  79. * Pretty big bug: was using wrong string paramter in ::Deserialize
  80. and furthermore it wasn't being trimmed.
  81. * Object::HasKeys now casts the return value to avoid compiler warnings.
  82. * Slight optimization to the Trim function
  83. * Made asserts in ::Deserialize easier to read
  84. 1/9/2014
  85. --------
  86. * Major bug fix: for JSON strings containing \" (as in, two characters,
  87. not the escaped " character), the lib would mess up and not parse
  88. correctly.
  89. * Major bug fix: I erroneously was assuming that all root JSON types
  90. had to be an object. This was an oversight, as a root JSON
  91. object can be an array. I have therefore changed the Deserialize
  92. method to return a json::Value rather than a json::Object. This
  93. will NOT impact any existing code you have, as a json::Value will
  94. cast to a json::Object (if it is indeed an object). But for
  95. correctness, you should be using json::Value = Deserialize...
  96. The Value type can be checked if it's an array (or any other type),
  97. and furthermore can even be accessed with the [] operator for
  98. convenience.
  99. * I've made the nullptr value type set numeric fields to 0 and bool to false.
  100. This is for convenience for using the nullptr type as a default return
  101. value in your code.
  102. * asserts added to casting (Gerry Beauregard)
  103. * Added method HasKeys to json::Object which will check if all the keys
  104. specified are in the object, returning the index of the first key
  105. not found or -1 if all found (hoppe).
  106. 1/4/2014
  107. --------
  108. * Fixed bug where bools were being parsed as doubles (Gerry Beauregard).
  109. 1/2/2014 v3
  110. ------------
  111. * More missing headers added for VisualStudio 2012
  112. * Switched to snprintf instead of sprintf (or sprintf_s in MSVC)
  113. 1/2/2014 v2
  114. -----------
  115. * Added yet more missing headers for compiling on GNU and Linux systems
  116. * Made Deserialize copy the passed in string so it won't mangle it
  117. 1/2/2014
  118. --------
  119. * Fixed previous changelog years. Got ahead of myself and marked them
  120. as 2014 when they were in fact done in 2013.
  121. * Added const version of [] to Array/Object/Value
  122. * Removed C++11 requirements, should work with older compilers
  123. (thanks to Meng Wang for pointing that out)
  124. * Made ValueMap and ValueVector typedefs in Object/Value public
  125. so you can actually iterate over the class
  126. * Added HasKey and HasValue to Object/Array for convenience
  127. (note this could have been done comparing .find to .end)
  128. 12/29/2013 v2
  129. -------------
  130. * Added .size() field to Value. Returns 1 for non Array/Object types,
  131. otherwise the number of elements contained.
  132. * Added .find() to Object to search for a key. Returns Object::end()
  133. if not found, otherwise the Value.
  134. Example: bool found = my_obj.find("some key") != my_obj.end();
  135. * Added .find() to Array to search for a value. Just a convenience
  136. wrapper for std::find(Array::begin(), Array::end(), Value)
  137. * Added ==, !=, <, >, <=, >= operators to Object/Array/Value.
  138. For Objects/Arrays, the operators function just like they do for a
  139. std::map and std::vector, respectively.
  140. * Added IsNumeric to Value to indicate if it's an int/float/double type.
  141. 12/29/2013
  142. ----------
  143. * Added the DoubleVal type which stores, you guessed it, double values.
  144. * Bug fix for floats with an exact integer value. Now, setting any numerical
  145. field will also set the fields for the other numerical types. So if you
  146. have obj["value"] = 12, then the int/float/double cast methods will
  147. return 12/12.0f/12.0. Previously, in the example above, only the int
  148. value was set, making a cast to float return 0.
  149. * Bug fix for deserializing JSON strings that contained large integer values.
  150. Now if the numerical value of a key in a JSON string contains a number
  151. less than INT_MIN or greater than INT_MAX it will be stored as a double.
  152. Note that as mentioned above, all numerical fields are set.
  153. * Should work fine with scientific notation values now.
  154. 12/28/2013
  155. ----------
  156. * Fixed a bug where if there were spaces around values or key names in a JSON
  157. string passed in to Deserialize, invalid results or asserts would occur.
  158. (Fix courtesy of Gerry Beauregard)
  159. * Added method named "Clear()" to Object/Array/Value to reset state
  160. * Added license to header file for easyness (totally valid word).
  161. */
  162. #pragma once
  163. #include <vector>
  164. #include <map>
  165. #include <string>
  166. #include <cassert>
  167. namespace json {
  168. enum ValueType { nullptrVal, StringVal, IntVal, FloatVal, DoubleVal, ObjectVal, ArrayVal, BoolVal };
  169. class Value;
  170. class Object
  171. {
  172. public:
  173. typedef std::map<std::string, Value> ValueMap;
  174. protected:
  175. ValueMap mValues;
  176. public:
  177. Object() = default;
  178. Object(const Object& obj) : mValues(obj.mValues) {}
  179. Object& operator =(const Object& obj);
  180. friend bool operator ==(const Object& lhs, const Object& rhs);
  181. friend bool operator !=(const Object& lhs, const Object& rhs) { return !(lhs == rhs); }
  182. friend bool operator <(const Object& lhs, const Object& rhs);
  183. friend bool operator >(const Object& lhs, const Object& rhs) { return operator<(rhs, lhs); }
  184. friend bool operator <=(const Object& lhs, const Object& rhs) { return !operator>(lhs, rhs); }
  185. friend bool operator >=(const Object& lhs, const Object& rhs) { return !operator<(lhs, rhs); }
  186. Value& operator [](const std::string& key);
  187. const Value& operator [](const std::string& key) const;
  188. Value& operator [](const char* key);
  189. const Value& operator [](const char* key) const;
  190. ValueMap::const_iterator begin() const;
  191. ValueMap::const_iterator end() const;
  192. ValueMap::iterator begin();
  193. ValueMap::iterator end();
  194. // Find will return end() if the key can't be found, just like std::map does.
  195. ValueMap::iterator find(const std::string& key);
  196. ValueMap::const_iterator find(const std::string& key) const;
  197. // Convenience wrapper to find to search for a key
  198. bool HasKey(const std::string& key) const;
  199. // Checks if the object contains all the keys in the array. If it does, returns -1.
  200. // If it doesn't, returns the index of the first key it couldn't find.
  201. int HasKeys(const std::vector<std::string>& keys) const;
  202. int HasKeys(const char** keys, int key_count) const;
  203. // Removes all values and resets the state back to default
  204. void Clear() { mValues.clear(); }
  205. size_t size() const { return mValues.size(); }
  206. };
  207. class Array
  208. {
  209. public:
  210. typedef std::vector<Value> ValueVector;
  211. protected:
  212. ValueVector mValues;
  213. public:
  214. Array() = default;
  215. Array(const Array& a) : mValues(a.mValues) { }
  216. Array& operator =(const Array& a);
  217. friend bool operator ==(const Array& lhs, const Array& rhs);
  218. friend bool operator !=(const Array& lhs, const Array& rhs) { return !(lhs == rhs); }
  219. friend bool operator <(const Array& lhs, const Array& rhs);
  220. friend bool operator >(const Array& lhs, const Array& rhs) { return operator<(rhs, lhs); }
  221. friend bool operator <=(const Array& lhs, const Array& rhs) { return !operator>(lhs, rhs); }
  222. friend bool operator >=(const Array& lhs, const Array& rhs) { return !operator<(lhs, rhs); }
  223. Value& operator[](size_t i);
  224. const Value& operator[](size_t i) const;
  225. ValueVector::const_iterator begin() const;
  226. ValueVector::const_iterator end() const;
  227. ValueVector::iterator begin();
  228. ValueVector::iterator end();
  229. // Just a convenience wrapper for doing a std::find(Array::begin(), Array::end(), Value)
  230. ValueVector::iterator find(const Value& v);
  231. ValueVector::const_iterator find(const Value& v) const;
  232. // Convenience wrapper to check if a value is in the array
  233. bool HasValue(const Value& v) const;
  234. // Removes all values and resets the state back to default
  235. void Clear() { mValues.clear(); }
  236. void push_back(const Value& v);
  237. void insert(size_t index, const Value& v);
  238. size_t size() const { return mValues.size(); }
  239. };
  240. class Value
  241. {
  242. protected:
  243. ValueType mValueType = nullptrVal;
  244. int mIntVal = 0;
  245. float mFloatVal = 0;
  246. double mDoubleVal = 0;
  247. std::string mStringVal;
  248. Object mObjectVal;
  249. Array mArrayVal;
  250. bool mBoolVal = false;
  251. public:
  252. const std::string& getStringImplementation() const { return mStringVal; }
  253. Value() = default;
  254. Value(const int v) : mValueType(IntVal), mIntVal(v), mFloatVal(float(v)), mDoubleVal(double(v)) { }
  255. Value(const float v) : mValueType(FloatVal), mIntVal(int(v)), mFloatVal(v), mDoubleVal(double(v)) { }
  256. Value(const double v) : mValueType(DoubleVal), mIntVal(int(v)), mFloatVal(float(v)), mDoubleVal(v) { }
  257. Value(const std::string& v) : mValueType(StringVal), mStringVal(v) { }
  258. Value(const char* v) : mValueType(StringVal), mStringVal(v) { }
  259. Value(const Object& v) : mValueType(ObjectVal), mObjectVal(v) { }
  260. Value(const Array& v) : mValueType(ArrayVal), mArrayVal(v) { }
  261. Value(const bool v) : mValueType(BoolVal), mBoolVal(v) { }
  262. Value(const Value& v);
  263. ValueType GetType() const { return mValueType; }
  264. Value& operator =(const Value& v);
  265. friend bool operator ==(const Value& lhs, const Value& rhs);
  266. friend bool operator !=(const Value& lhs, const Value& rhs) { return !(lhs == rhs); }
  267. friend bool operator <(const Value& lhs, const Value& rhs);
  268. friend bool operator >(const Value& lhs, const Value& rhs) { return operator<(rhs, lhs); }
  269. friend bool operator <=(const Value& lhs, const Value& rhs) { return !operator>(lhs, rhs); }
  270. friend bool operator >=(const Value& lhs, const Value& rhs) { return !operator<(lhs, rhs); }
  271. // For use with Array/ObjectVal types, respectively
  272. Value& operator [](size_t idx);
  273. const Value& operator [](size_t idx) const;
  274. Value& operator [](const std::string& key);
  275. const Value& operator [](const std::string& key) const;
  276. Value& operator [](const char* key);
  277. const Value& operator [](const char* key) const;
  278. bool HasKey(const std::string& key) const;
  279. int HasKeys(const std::vector<std::string>& keys) const;
  280. int HasKeys(const char** keys, int key_count) const;
  281. // non-operator versions
  282. int ToInt() const
  283. {
  284. assert(IsNumeric());
  285. return mIntVal;
  286. }
  287. float ToFloat() const
  288. {
  289. assert(IsNumeric());
  290. return mFloatVal;
  291. }
  292. double ToDouble() const
  293. {
  294. assert(IsNumeric());
  295. return mDoubleVal;
  296. }
  297. bool ToBool() const
  298. {
  299. assert(mValueType == BoolVal);
  300. return mBoolVal;
  301. }
  302. std::string ToString() const
  303. {
  304. assert(mValueType == StringVal);
  305. return mStringVal;
  306. }
  307. Object ToObject() const
  308. {
  309. assert(mValueType == ObjectVal);
  310. return mObjectVal;
  311. }
  312. Array ToArray() const
  313. {
  314. assert(mValueType == ArrayVal);
  315. return mArrayVal;
  316. }
  317. // mutable non-operator versions
  318. Array& ToMutableArray()
  319. {
  320. assert(mValueType == ArrayVal);
  321. return mArrayVal;
  322. }
  323. // Please note that as per C++ rules, implicitly casting a Value to a std::string won't work.
  324. // This is because it could use the int/float/double/bool operators as well. So to assign a
  325. // Value to a std::string you can either do:
  326. // my_string = (std::string)my_value
  327. // Or you can now do:
  328. // my_string = my_value.ToString();
  329. //
  330. operator int() const
  331. {
  332. assert(IsNumeric());
  333. return mIntVal;
  334. }
  335. operator float() const
  336. {
  337. assert(IsNumeric());
  338. return mFloatVal;
  339. }
  340. operator double() const
  341. {
  342. assert(IsNumeric());
  343. return mDoubleVal;
  344. }
  345. operator bool() const
  346. {
  347. assert(mValueType == BoolVal);
  348. return mBoolVal;
  349. }
  350. operator std::string const() const
  351. {
  352. assert(mValueType == StringVal);
  353. return mStringVal;
  354. }
  355. operator std::string() const
  356. {
  357. assert(mValueType == StringVal);
  358. return mStringVal;
  359. }
  360. operator const char*() const
  361. {
  362. assert(mValueType == StringVal);
  363. return mStringVal.c_str();
  364. }
  365. operator Object() const
  366. {
  367. assert(mValueType == ObjectVal);
  368. return mObjectVal;
  369. }
  370. operator Array() const
  371. {
  372. assert(mValueType == ArrayVal);
  373. return mArrayVal;
  374. }
  375. bool IsNumeric() const { return (mValueType == IntVal) || (mValueType == DoubleVal) || (mValueType == FloatVal); }
  376. // Returns 1 for anything not an Array/ObjectVal
  377. size_t size() const;
  378. // Resets the state back to default, aka nullptrVal
  379. void Clear() { mValueType = nullptrVal; }
  380. };
  381. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  382. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  383. // Converts a JSON Object or Array instance into a JSON string representing it.
  384. std::string Serialize(const Value& v);
  385. // If there is an error, Value will be nullptrType
  386. Value Deserialize(const std::string& str);
  387. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  388. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  389. inline bool operator ==(const Object& lhs, const Object& rhs) { return lhs.mValues == rhs.mValues; }
  390. inline bool operator <(const Object& lhs, const Object& rhs) { return lhs.mValues < rhs.mValues; }
  391. inline bool operator ==(const Array& lhs, const Array& rhs) { return lhs.mValues == rhs.mValues; }
  392. inline bool operator <(const Array& lhs, const Array& rhs) { return lhs.mValues < rhs.mValues; }
  393. /* When comparing different numeric types, this method works the same as if you compared different numeric types
  394. on your own. Thus it performs the same as if you, for example, did this:
  395. int a = 1;
  396. float b = 1.1f;
  397. bool equivalent = a == b;
  398. The same logic applies to the other comparison operators.
  399. */
  400. inline bool operator ==(const Value& lhs, const Value& rhs)
  401. {
  402. if ((lhs.mValueType != rhs.mValueType) && !lhs.IsNumeric() && !rhs.IsNumeric()) { return false; }
  403. switch (lhs.mValueType)
  404. {
  405. case StringVal: return lhs.mStringVal == rhs.mStringVal;
  406. case IntVal:
  407. if (rhs.GetType() == FloatVal) { return float(lhs.mIntVal) == rhs.mFloatVal; }
  408. if (rhs.GetType() == DoubleVal) { return double(lhs.mIntVal) == rhs.mDoubleVal; }
  409. if (rhs.GetType() == IntVal) { return lhs.mIntVal == rhs.mIntVal; }
  410. return false;
  411. case FloatVal:
  412. if (rhs.GetType() == FloatVal) { return lhs.mFloatVal == rhs.mFloatVal; }
  413. if (rhs.GetType() == DoubleVal) { return double(lhs.mFloatVal) == rhs.mDoubleVal; }
  414. if (rhs.GetType() == IntVal) { return lhs.mFloatVal == float(rhs.mIntVal); }
  415. return false;
  416. case DoubleVal:
  417. if (rhs.GetType() == FloatVal) { return lhs.mDoubleVal == double(rhs.mFloatVal); }
  418. if (rhs.GetType() == DoubleVal) { return lhs.mDoubleVal == rhs.mDoubleVal; }
  419. if (rhs.GetType() == IntVal) { return lhs.mDoubleVal == double(rhs.mIntVal); }
  420. return false;
  421. case BoolVal: return lhs.mBoolVal == rhs.mBoolVal;
  422. case ObjectVal: return lhs.mObjectVal == rhs.mObjectVal;
  423. case ArrayVal: return lhs.mArrayVal == rhs.mArrayVal;
  424. default: return true;
  425. }
  426. }
  427. inline bool operator <(const Value& lhs, const Value& rhs)
  428. {
  429. if ((lhs.mValueType != rhs.mValueType) && !lhs.IsNumeric() && !rhs.IsNumeric()) { return false; }
  430. switch (lhs.mValueType)
  431. {
  432. case StringVal: return lhs.mStringVal < rhs.mStringVal;
  433. case IntVal:
  434. if (rhs.GetType() == FloatVal) { return float(lhs.mIntVal) < rhs.mFloatVal; }
  435. if (rhs.GetType() == DoubleVal) { return double(lhs.mIntVal) < rhs.mDoubleVal; }
  436. if (rhs.GetType() == IntVal) { return lhs.mIntVal < rhs.mIntVal; }
  437. return false;
  438. case FloatVal:
  439. if (rhs.GetType() == FloatVal) { return lhs.mFloatVal < rhs.mFloatVal; }
  440. if (rhs.GetType() == DoubleVal) { return double(lhs.mFloatVal) < rhs.mDoubleVal; }
  441. if (rhs.GetType() == IntVal) { return lhs.mFloatVal < float(rhs.mIntVal); }
  442. return false;
  443. case DoubleVal:
  444. if (rhs.GetType() == FloatVal) { return lhs.mDoubleVal < double(rhs.mFloatVal); }
  445. if (rhs.GetType() == DoubleVal) { return lhs.mDoubleVal < rhs.mDoubleVal; }
  446. if (rhs.GetType() == IntVal) { return lhs.mDoubleVal < double(rhs.mIntVal); }
  447. return false;
  448. case BoolVal: return int(lhs.mBoolVal) < int(rhs.mBoolVal);
  449. case ObjectVal: return lhs.mObjectVal < rhs.mObjectVal;
  450. case ArrayVal: return lhs.mArrayVal < rhs.mArrayVal;
  451. default: return true;
  452. }
  453. }
  454. }