picojson.h 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172
  1. /*
  2. * Copyright 2009-2010 Cybozu Labs, Inc.
  3. * Copyright 2011-2014 Kazuho Oku
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright notice,
  13. * this list of conditions and the following disclaimer in the documentation
  14. * and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  20. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. * POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifndef picojson_h
  29. #define picojson_h
  30. #include <algorithm>
  31. #include <cstdio>
  32. #include <cstdlib>
  33. #include <cstring>
  34. #include <cstddef>
  35. #include <iostream>
  36. #include <iterator>
  37. #include <limits>
  38. #include <map>
  39. #include <stdexcept>
  40. #include <string>
  41. #include <vector>
  42. #include <utility>
  43. // for isnan/isinf
  44. #if __cplusplus >= 201103L
  45. #include <cmath>
  46. #else
  47. extern "C" {
  48. #ifdef _MSC_VER
  49. #include <float.h>
  50. #elif defined(__INTEL_COMPILER)
  51. #include <mathimf.h>
  52. #else
  53. #include <math.h>
  54. #endif
  55. }
  56. #endif
  57. #ifndef PICOJSON_USE_RVALUE_REFERENCE
  58. #if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
  59. #define PICOJSON_USE_RVALUE_REFERENCE 1
  60. #else
  61. #define PICOJSON_USE_RVALUE_REFERENCE 0
  62. #endif
  63. #endif // PICOJSON_USE_RVALUE_REFERENCE
  64. #ifndef PICOJSON_NOEXCEPT
  65. #if PICOJSON_USE_RVALUE_REFERENCE
  66. #define PICOJSON_NOEXCEPT noexcept
  67. #else
  68. #define PICOJSON_NOEXCEPT throw()
  69. #endif
  70. #endif
  71. // experimental support for int64_t (see README.mkdn for detail)
  72. #ifdef PICOJSON_USE_INT64
  73. #ifndef __STDC_FORMAT_MACROS
  74. #define __STDC_FORMAT_MACROS
  75. #endif
  76. #include <errno.h>
  77. #include <inttypes.h>
  78. #endif
  79. // to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
  80. #ifndef PICOJSON_USE_LOCALE
  81. #define PICOJSON_USE_LOCALE 1
  82. #endif
  83. #if PICOJSON_USE_LOCALE
  84. extern "C" {
  85. #include <locale.h>
  86. }
  87. #endif
  88. #ifndef PICOJSON_ASSERT
  89. #define PICOJSON_ASSERT(e) \
  90. do { \
  91. if (!(e)) \
  92. throw std::runtime_error(#e); \
  93. } while (0)
  94. #endif
  95. #ifdef _MSC_VER
  96. #define SNPRINTF _snprintf_s
  97. #pragma warning(push)
  98. #pragma warning(disable : 4244) // conversion from int to char
  99. #pragma warning(disable : 4127) // conditional expression is constant
  100. #pragma warning(disable : 4702) // unreachable code
  101. #else
  102. #define SNPRINTF snprintf
  103. #endif
  104. namespace picojson {
  105. enum {
  106. null_type,
  107. boolean_type,
  108. number_type,
  109. string_type,
  110. array_type,
  111. object_type
  112. #ifdef PICOJSON_USE_INT64
  113. ,
  114. int64_type
  115. #endif
  116. };
  117. enum { INDENT_WIDTH = 2 };
  118. struct null {};
  119. class value {
  120. public:
  121. typedef std::vector<value> array;
  122. typedef std::map<std::string, value> object;
  123. union _storage {
  124. bool boolean_;
  125. double number_;
  126. #ifdef PICOJSON_USE_INT64
  127. int64_t int64_;
  128. #endif
  129. std::string *string_;
  130. array *array_;
  131. object *object_;
  132. };
  133. protected:
  134. int type_;
  135. _storage u_;
  136. public:
  137. value();
  138. value(int type, bool);
  139. explicit value(bool b);
  140. #ifdef PICOJSON_USE_INT64
  141. explicit value(int64_t i);
  142. #endif
  143. explicit value(double n);
  144. explicit value(const std::string &s);
  145. explicit value(const array &a);
  146. explicit value(const object &o);
  147. #if PICOJSON_USE_RVALUE_REFERENCE
  148. explicit value(std::string &&s);
  149. explicit value(array &&a);
  150. explicit value(object &&o);
  151. #endif
  152. explicit value(const char *s);
  153. value(const char *s, size_t len);
  154. ~value();
  155. value(const value &x);
  156. value &operator=(const value &x);
  157. #if PICOJSON_USE_RVALUE_REFERENCE
  158. value(value &&x) PICOJSON_NOEXCEPT;
  159. value &operator=(value &&x) PICOJSON_NOEXCEPT;
  160. #endif
  161. void swap(value &x) PICOJSON_NOEXCEPT;
  162. template <typename T> bool is() const;
  163. template <typename T> const T &get() const;
  164. template <typename T> T &get();
  165. template <typename T> void set(const T &);
  166. #if PICOJSON_USE_RVALUE_REFERENCE
  167. template <typename T> void set(T &&);
  168. #endif
  169. bool evaluate_as_boolean() const;
  170. const value &get(const size_t idx) const;
  171. const value &get(const std::string &key) const;
  172. value &get(const size_t idx);
  173. value &get(const std::string &key);
  174. bool contains(const size_t idx) const;
  175. bool contains(const std::string &key) const;
  176. std::string to_str() const;
  177. template <typename Iter> void serialize(Iter os, bool prettify = false) const;
  178. std::string serialize(bool prettify = false) const;
  179. private:
  180. template <typename T> value(const T *); // intentionally defined to block implicit conversion of pointer to bool
  181. template <typename Iter> static void _indent(Iter os, int indent);
  182. template <typename Iter> void _serialize(Iter os, int indent) const;
  183. std::string _serialize(int indent) const;
  184. void clear();
  185. };
  186. typedef value::array array;
  187. typedef value::object object;
  188. inline value::value() : type_(null_type), u_() {
  189. }
  190. inline value::value(int type, bool) : type_(type), u_() {
  191. switch (type) {
  192. #define INIT(p, v) \
  193. case p##type: \
  194. u_.p = v; \
  195. break
  196. INIT(boolean_, false);
  197. INIT(number_, 0.0);
  198. #ifdef PICOJSON_USE_INT64
  199. INIT(int64_, 0);
  200. #endif
  201. INIT(string_, new std::string());
  202. INIT(array_, new array());
  203. INIT(object_, new object());
  204. #undef INIT
  205. default:
  206. break;
  207. }
  208. }
  209. inline value::value(bool b) : type_(boolean_type), u_() {
  210. u_.boolean_ = b;
  211. }
  212. #ifdef PICOJSON_USE_INT64
  213. inline value::value(int64_t i) : type_(int64_type), u_() {
  214. u_.int64_ = i;
  215. }
  216. #endif
  217. inline value::value(double n) : type_(number_type), u_() {
  218. if (
  219. #if defined(_MSC_VER) && !defined(__clang__)
  220. !_finite(n)
  221. #elif __cplusplus >= 201103L
  222. std::isnan(n) || std::isinf(n)
  223. #else
  224. isnan(n) || isinf(n)
  225. #endif
  226. ) {
  227. throw std::overflow_error("");
  228. }
  229. u_.number_ = n;
  230. }
  231. inline value::value(const std::string &s) : type_(string_type), u_() {
  232. u_.string_ = new std::string(s);
  233. }
  234. inline value::value(const array &a) : type_(array_type), u_() {
  235. u_.array_ = new array(a);
  236. }
  237. inline value::value(const object &o) : type_(object_type), u_() {
  238. u_.object_ = new object(o);
  239. }
  240. #if PICOJSON_USE_RVALUE_REFERENCE
  241. inline value::value(std::string &&s) : type_(string_type), u_() {
  242. u_.string_ = new std::string(std::move(s));
  243. }
  244. inline value::value(array &&a) : type_(array_type), u_() {
  245. u_.array_ = new array(std::move(a));
  246. }
  247. inline value::value(object &&o) : type_(object_type), u_() {
  248. u_.object_ = new object(std::move(o));
  249. }
  250. #endif
  251. inline value::value(const char *s) : type_(string_type), u_() {
  252. u_.string_ = new std::string(s);
  253. }
  254. inline value::value(const char *s, size_t len) : type_(string_type), u_() {
  255. u_.string_ = new std::string(s, len);
  256. }
  257. inline void value::clear() {
  258. switch (type_) {
  259. #define DEINIT(p) \
  260. case p##type: \
  261. delete u_.p; \
  262. break
  263. DEINIT(string_);
  264. DEINIT(array_);
  265. DEINIT(object_);
  266. #undef DEINIT
  267. default:
  268. break;
  269. }
  270. }
  271. inline value::~value() {
  272. clear();
  273. }
  274. inline value::value(const value &x) : type_(x.type_), u_() {
  275. switch (type_) {
  276. #define INIT(p, v) \
  277. case p##type: \
  278. u_.p = v; \
  279. break
  280. INIT(string_, new std::string(*x.u_.string_));
  281. INIT(array_, new array(*x.u_.array_));
  282. INIT(object_, new object(*x.u_.object_));
  283. #undef INIT
  284. default:
  285. u_ = x.u_;
  286. break;
  287. }
  288. }
  289. inline value &value::operator=(const value &x) {
  290. if (this != &x) {
  291. value t(x);
  292. swap(t);
  293. }
  294. return *this;
  295. }
  296. #if PICOJSON_USE_RVALUE_REFERENCE
  297. inline value::value(value &&x) PICOJSON_NOEXCEPT : type_(null_type), u_() {
  298. swap(x);
  299. }
  300. inline value &value::operator=(value &&x) PICOJSON_NOEXCEPT {
  301. swap(x);
  302. return *this;
  303. }
  304. #endif
  305. inline void value::swap(value &x) PICOJSON_NOEXCEPT {
  306. std::swap(type_, x.type_);
  307. std::swap(u_, x.u_);
  308. }
  309. #define IS(ctype, jtype) \
  310. template <> inline bool value::is<ctype>() const { \
  311. return type_ == jtype##_type; \
  312. }
  313. IS(null, null)
  314. IS(bool, boolean)
  315. #ifdef PICOJSON_USE_INT64
  316. IS(int64_t, int64)
  317. #endif
  318. IS(std::string, string)
  319. IS(array, array)
  320. IS(object, object)
  321. #undef IS
  322. template <> inline bool value::is<double>() const {
  323. return type_ == number_type
  324. #ifdef PICOJSON_USE_INT64
  325. || type_ == int64_type
  326. #endif
  327. ;
  328. }
  329. #define GET(ctype, var) \
  330. template <> inline const ctype &value::get<ctype>() const { \
  331. PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
  332. return var; \
  333. } \
  334. template <> inline ctype &value::get<ctype>() { \
  335. PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
  336. return var; \
  337. }
  338. GET(bool, u_.boolean_)
  339. GET(std::string, *u_.string_)
  340. GET(array, *u_.array_)
  341. GET(object, *u_.object_)
  342. #ifdef PICOJSON_USE_INT64
  343. GET(double,
  344. (type_ == int64_type && (const_cast<value *>(this)->type_ = number_type, const_cast<value *>(this)->u_.number_ = u_.int64_),
  345. u_.number_))
  346. GET(int64_t, u_.int64_)
  347. #else
  348. GET(double, u_.number_)
  349. #endif
  350. #undef GET
  351. #define SET(ctype, jtype, setter) \
  352. template <> inline void value::set<ctype>(const ctype &_val) { \
  353. clear(); \
  354. type_ = jtype##_type; \
  355. setter \
  356. }
  357. SET(bool, boolean, u_.boolean_ = _val;)
  358. SET(std::string, string, u_.string_ = new std::string(_val);)
  359. SET(array, array, u_.array_ = new array(_val);)
  360. SET(object, object, u_.object_ = new object(_val);)
  361. SET(double, number, u_.number_ = _val;)
  362. #ifdef PICOJSON_USE_INT64
  363. SET(int64_t, int64, u_.int64_ = _val;)
  364. #endif
  365. #undef SET
  366. #if PICOJSON_USE_RVALUE_REFERENCE
  367. #define MOVESET(ctype, jtype, setter) \
  368. template <> inline void value::set<ctype>(ctype && _val) { \
  369. clear(); \
  370. type_ = jtype##_type; \
  371. setter \
  372. }
  373. MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));)
  374. MOVESET(array, array, u_.array_ = new array(std::move(_val));)
  375. MOVESET(object, object, u_.object_ = new object(std::move(_val));)
  376. #undef MOVESET
  377. #endif
  378. inline bool value::evaluate_as_boolean() const {
  379. switch (type_) {
  380. case null_type:
  381. return false;
  382. case boolean_type:
  383. return u_.boolean_;
  384. case number_type:
  385. return u_.number_ != 0;
  386. #ifdef PICOJSON_USE_INT64
  387. case int64_type:
  388. return u_.int64_ != 0;
  389. #endif
  390. case string_type:
  391. return !u_.string_->empty();
  392. default:
  393. return true;
  394. }
  395. }
  396. inline const value &value::get(const size_t idx) const {
  397. static value s_null;
  398. PICOJSON_ASSERT(is<array>());
  399. return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
  400. }
  401. inline value &value::get(const size_t idx) {
  402. static value s_null;
  403. PICOJSON_ASSERT(is<array>());
  404. return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
  405. }
  406. inline const value &value::get(const std::string &key) const {
  407. static value s_null;
  408. PICOJSON_ASSERT(is<object>());
  409. object::const_iterator i = u_.object_->find(key);
  410. return i != u_.object_->end() ? i->second : s_null;
  411. }
  412. inline value &value::get(const std::string &key) {
  413. static value s_null;
  414. PICOJSON_ASSERT(is<object>());
  415. object::iterator i = u_.object_->find(key);
  416. return i != u_.object_->end() ? i->second : s_null;
  417. }
  418. inline bool value::contains(const size_t idx) const {
  419. PICOJSON_ASSERT(is<array>());
  420. return idx < u_.array_->size();
  421. }
  422. inline bool value::contains(const std::string &key) const {
  423. PICOJSON_ASSERT(is<object>());
  424. object::const_iterator i = u_.object_->find(key);
  425. return i != u_.object_->end();
  426. }
  427. inline std::string value::to_str() const {
  428. switch (type_) {
  429. case null_type:
  430. return "null";
  431. case boolean_type:
  432. return u_.boolean_ ? "true" : "false";
  433. #ifdef PICOJSON_USE_INT64
  434. case int64_type: {
  435. char buf[sizeof("-9223372036854775808")];
  436. SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
  437. return buf;
  438. }
  439. #endif
  440. case number_type: {
  441. char buf[256];
  442. double tmp;
  443. SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
  444. #if PICOJSON_USE_LOCALE
  445. char *decimal_point = localeconv()->decimal_point;
  446. if (strcmp(decimal_point, ".") != 0) {
  447. size_t decimal_point_len = strlen(decimal_point);
  448. for (char *p = buf; *p != '\0'; ++p) {
  449. if (strncmp(p, decimal_point, decimal_point_len) == 0) {
  450. return std::string(buf, p) + "." + (p + decimal_point_len);
  451. }
  452. }
  453. }
  454. #endif
  455. return buf;
  456. }
  457. case string_type:
  458. return *u_.string_;
  459. case array_type:
  460. return "array";
  461. case object_type:
  462. return "object";
  463. default:
  464. PICOJSON_ASSERT(0);
  465. #ifdef _MSC_VER
  466. __assume(0);
  467. #endif
  468. }
  469. return std::string();
  470. }
  471. template <typename Iter> void copy(const std::string &s, Iter oi) {
  472. std::copy(s.begin(), s.end(), oi);
  473. }
  474. template <typename Iter> struct serialize_str_char {
  475. Iter oi;
  476. void operator()(char c) {
  477. switch (c) {
  478. #define MAP(val, sym) \
  479. case val: \
  480. copy(sym, oi); \
  481. break
  482. MAP('"', "\\\"");
  483. MAP('\\', "\\\\");
  484. MAP('/', "\\/");
  485. MAP('\b', "\\b");
  486. MAP('\f', "\\f");
  487. MAP('\n', "\\n");
  488. MAP('\r', "\\r");
  489. MAP('\t', "\\t");
  490. #undef MAP
  491. default:
  492. if (static_cast<unsigned char>(c) < 0x20 || c == 0x7f) {
  493. char buf[7];
  494. SNPRINTF(buf, sizeof(buf), "\\u%04x", c & 0xff);
  495. copy(buf, buf + 6, oi);
  496. } else {
  497. *oi++ = c;
  498. }
  499. break;
  500. }
  501. }
  502. };
  503. template <typename Iter> void serialize_str(const std::string &s, Iter oi) {
  504. *oi++ = '"';
  505. serialize_str_char<Iter> process_char = {oi};
  506. std::for_each(s.begin(), s.end(), process_char);
  507. *oi++ = '"';
  508. }
  509. template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
  510. return _serialize(oi, prettify ? 0 : -1);
  511. }
  512. inline std::string value::serialize(bool prettify) const {
  513. return _serialize(prettify ? 0 : -1);
  514. }
  515. template <typename Iter> void value::_indent(Iter oi, int indent) {
  516. *oi++ = '\n';
  517. for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
  518. *oi++ = ' ';
  519. }
  520. }
  521. template <typename Iter> void value::_serialize(Iter oi, int indent) const {
  522. switch (type_) {
  523. case string_type:
  524. serialize_str(*u_.string_, oi);
  525. break;
  526. case array_type: {
  527. *oi++ = '[';
  528. if (indent != -1) {
  529. ++indent;
  530. }
  531. for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end(); ++i) {
  532. if (i != u_.array_->begin()) {
  533. *oi++ = ',';
  534. }
  535. if (indent != -1) {
  536. _indent(oi, indent);
  537. }
  538. i->_serialize(oi, indent);
  539. }
  540. if (indent != -1) {
  541. --indent;
  542. if (!u_.array_->empty()) {
  543. _indent(oi, indent);
  544. }
  545. }
  546. *oi++ = ']';
  547. break;
  548. }
  549. case object_type: {
  550. *oi++ = '{';
  551. if (indent != -1) {
  552. ++indent;
  553. }
  554. for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) {
  555. if (i != u_.object_->begin()) {
  556. *oi++ = ',';
  557. }
  558. if (indent != -1) {
  559. _indent(oi, indent);
  560. }
  561. serialize_str(i->first, oi);
  562. *oi++ = ':';
  563. if (indent != -1) {
  564. *oi++ = ' ';
  565. }
  566. i->second._serialize(oi, indent);
  567. }
  568. if (indent != -1) {
  569. --indent;
  570. if (!u_.object_->empty()) {
  571. _indent(oi, indent);
  572. }
  573. }
  574. *oi++ = '}';
  575. break;
  576. }
  577. default:
  578. copy(to_str(), oi);
  579. break;
  580. }
  581. if (indent == 0) {
  582. *oi++ = '\n';
  583. }
  584. }
  585. inline std::string value::_serialize(int indent) const {
  586. std::string s;
  587. _serialize(std::back_inserter(s), indent);
  588. return s;
  589. }
  590. template <typename Iter> class input {
  591. protected:
  592. Iter cur_, end_;
  593. bool consumed_;
  594. int line_;
  595. public:
  596. input(const Iter &first, const Iter &last) : cur_(first), end_(last), consumed_(false), line_(1) {
  597. }
  598. int getc() {
  599. if (consumed_) {
  600. if (*cur_ == '\n') {
  601. ++line_;
  602. }
  603. ++cur_;
  604. }
  605. if (cur_ == end_) {
  606. consumed_ = false;
  607. return -1;
  608. }
  609. consumed_ = true;
  610. return *cur_ & 0xff;
  611. }
  612. void ungetc() {
  613. consumed_ = false;
  614. }
  615. Iter cur() const {
  616. if (consumed_) {
  617. input<Iter> *self = const_cast<input<Iter> *>(this);
  618. self->consumed_ = false;
  619. ++self->cur_;
  620. }
  621. return cur_;
  622. }
  623. int line() const {
  624. return line_;
  625. }
  626. void skip_ws() {
  627. while (1) {
  628. int ch = getc();
  629. if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
  630. ungetc();
  631. break;
  632. }
  633. }
  634. }
  635. bool expect(const int expected) {
  636. skip_ws();
  637. if (getc() != expected) {
  638. ungetc();
  639. return false;
  640. }
  641. return true;
  642. }
  643. bool match(const std::string &pattern) {
  644. for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
  645. if (getc() != *pi) {
  646. ungetc();
  647. return false;
  648. }
  649. }
  650. return true;
  651. }
  652. };
  653. template <typename Iter> inline int _parse_quadhex(input<Iter> &in) {
  654. int uni_ch = 0, hex;
  655. for (int i = 0; i < 4; i++) {
  656. if ((hex = in.getc()) == -1) {
  657. return -1;
  658. }
  659. if ('0' <= hex && hex <= '9') {
  660. hex -= '0';
  661. } else if ('A' <= hex && hex <= 'F') {
  662. hex -= 'A' - 0xa;
  663. } else if ('a' <= hex && hex <= 'f') {
  664. hex -= 'a' - 0xa;
  665. } else {
  666. in.ungetc();
  667. return -1;
  668. }
  669. uni_ch = uni_ch * 16 + hex;
  670. }
  671. return uni_ch;
  672. }
  673. template <typename String, typename Iter> inline bool _parse_codepoint(String &out, input<Iter> &in) {
  674. int uni_ch;
  675. if ((uni_ch = _parse_quadhex(in)) == -1) {
  676. return false;
  677. }
  678. if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
  679. if (0xdc00 <= uni_ch) {
  680. // a second 16-bit of a surrogate pair appeared
  681. return false;
  682. }
  683. // first 16-bit of surrogate pair, get the next one
  684. if (in.getc() != '\\' || in.getc() != 'u') {
  685. in.ungetc();
  686. return false;
  687. }
  688. int second = _parse_quadhex(in);
  689. if (!(0xdc00 <= second && second <= 0xdfff)) {
  690. return false;
  691. }
  692. uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
  693. uni_ch += 0x10000;
  694. }
  695. if (uni_ch < 0x80) {
  696. out.push_back(static_cast<char>(uni_ch));
  697. } else {
  698. if (uni_ch < 0x800) {
  699. out.push_back(static_cast<char>(0xc0 | (uni_ch >> 6)));
  700. } else {
  701. if (uni_ch < 0x10000) {
  702. out.push_back(static_cast<char>(0xe0 | (uni_ch >> 12)));
  703. } else {
  704. out.push_back(static_cast<char>(0xf0 | (uni_ch >> 18)));
  705. out.push_back(static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
  706. }
  707. out.push_back(static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
  708. }
  709. out.push_back(static_cast<char>(0x80 | (uni_ch & 0x3f)));
  710. }
  711. return true;
  712. }
  713. template <typename String, typename Iter> inline bool _parse_string(String &out, input<Iter> &in) {
  714. while (1) {
  715. int ch = in.getc();
  716. if (ch < ' ') {
  717. in.ungetc();
  718. return false;
  719. } else if (ch == '"') {
  720. return true;
  721. } else if (ch == '\\') {
  722. if ((ch = in.getc()) == -1) {
  723. return false;
  724. }
  725. switch (ch) {
  726. #define MAP(sym, val) \
  727. case sym: \
  728. out.push_back(val); \
  729. break
  730. MAP('"', '\"');
  731. MAP('\\', '\\');
  732. MAP('/', '/');
  733. MAP('b', '\b');
  734. MAP('f', '\f');
  735. MAP('n', '\n');
  736. MAP('r', '\r');
  737. MAP('t', '\t');
  738. #undef MAP
  739. case 'u':
  740. if (!_parse_codepoint(out, in)) {
  741. return false;
  742. }
  743. break;
  744. default:
  745. return false;
  746. }
  747. } else {
  748. out.push_back(static_cast<char>(ch));
  749. }
  750. }
  751. return false;
  752. }
  753. template <typename Context, typename Iter> inline bool _parse_array(Context &ctx, input<Iter> &in) {
  754. if (!ctx.parse_array_start()) {
  755. return false;
  756. }
  757. size_t idx = 0;
  758. if (in.expect(']')) {
  759. return ctx.parse_array_stop(idx);
  760. }
  761. do {
  762. if (!ctx.parse_array_item(in, idx)) {
  763. return false;
  764. }
  765. idx++;
  766. } while (in.expect(','));
  767. return in.expect(']') && ctx.parse_array_stop(idx);
  768. }
  769. template <typename Context, typename Iter> inline bool _parse_object(Context &ctx, input<Iter> &in) {
  770. if (!ctx.parse_object_start()) {
  771. return false;
  772. }
  773. if (in.expect('}')) {
  774. return true;
  775. }
  776. do {
  777. std::string key;
  778. if (!in.expect('"') || !_parse_string(key, in) || !in.expect(':')) {
  779. return false;
  780. }
  781. if (!ctx.parse_object_item(in, key)) {
  782. return false;
  783. }
  784. } while (in.expect(','));
  785. return in.expect('}');
  786. }
  787. template <typename Iter> inline std::string _parse_number(input<Iter> &in) {
  788. std::string num_str;
  789. while (1) {
  790. int ch = in.getc();
  791. if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E') {
  792. num_str.push_back(static_cast<char>(ch));
  793. } else if (ch == '.') {
  794. #if PICOJSON_USE_LOCALE
  795. num_str += localeconv()->decimal_point;
  796. #else
  797. num_str.push_back('.');
  798. #endif
  799. } else {
  800. in.ungetc();
  801. break;
  802. }
  803. }
  804. return num_str;
  805. }
  806. template <typename Context, typename Iter> inline bool _parse(Context &ctx, input<Iter> &in) {
  807. in.skip_ws();
  808. int ch = in.getc();
  809. switch (ch) {
  810. #define IS(ch, text, op) \
  811. case ch: \
  812. if (in.match(text) && op) { \
  813. return true; \
  814. } else { \
  815. return false; \
  816. }
  817. IS('n', "ull", ctx.set_null());
  818. IS('f', "alse", ctx.set_bool(false));
  819. IS('t', "rue", ctx.set_bool(true));
  820. #undef IS
  821. case '"':
  822. return ctx.parse_string(in);
  823. case '[':
  824. return _parse_array(ctx, in);
  825. case '{':
  826. return _parse_object(ctx, in);
  827. default:
  828. if (('0' <= ch && ch <= '9') || ch == '-') {
  829. double f;
  830. char *endp;
  831. in.ungetc();
  832. std::string num_str(_parse_number(in));
  833. if (num_str.empty()) {
  834. return false;
  835. }
  836. #ifdef PICOJSON_USE_INT64
  837. {
  838. errno = 0;
  839. intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
  840. if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival && ival <= std::numeric_limits<int64_t>::max() &&
  841. endp == num_str.c_str() + num_str.size()) {
  842. ctx.set_int64(ival);
  843. return true;
  844. }
  845. }
  846. #endif
  847. f = strtod(num_str.c_str(), &endp);
  848. if (endp == num_str.c_str() + num_str.size()) {
  849. ctx.set_number(f);
  850. return true;
  851. }
  852. return false;
  853. }
  854. break;
  855. }
  856. in.ungetc();
  857. return false;
  858. }
  859. class deny_parse_context {
  860. public:
  861. bool set_null() {
  862. return false;
  863. }
  864. bool set_bool(bool) {
  865. return false;
  866. }
  867. #ifdef PICOJSON_USE_INT64
  868. bool set_int64(int64_t) {
  869. return false;
  870. }
  871. #endif
  872. bool set_number(double) {
  873. return false;
  874. }
  875. template <typename Iter> bool parse_string(input<Iter> &) {
  876. return false;
  877. }
  878. bool parse_array_start() {
  879. return false;
  880. }
  881. template <typename Iter> bool parse_array_item(input<Iter> &, size_t) {
  882. return false;
  883. }
  884. bool parse_array_stop(size_t) {
  885. return false;
  886. }
  887. bool parse_object_start() {
  888. return false;
  889. }
  890. template <typename Iter> bool parse_object_item(input<Iter> &, const std::string &) {
  891. return false;
  892. }
  893. };
  894. class default_parse_context {
  895. protected:
  896. value *out_;
  897. public:
  898. default_parse_context(value *out) : out_(out) {
  899. }
  900. bool set_null() {
  901. *out_ = value();
  902. return true;
  903. }
  904. bool set_bool(bool b) {
  905. *out_ = value(b);
  906. return true;
  907. }
  908. #ifdef PICOJSON_USE_INT64
  909. bool set_int64(int64_t i) {
  910. *out_ = value(i);
  911. return true;
  912. }
  913. #endif
  914. bool set_number(double f) {
  915. *out_ = value(f);
  916. return true;
  917. }
  918. template <typename Iter> bool parse_string(input<Iter> &in) {
  919. *out_ = value(string_type, false);
  920. return _parse_string(out_->get<std::string>(), in);
  921. }
  922. bool parse_array_start() {
  923. *out_ = value(array_type, false);
  924. return true;
  925. }
  926. template <typename Iter> bool parse_array_item(input<Iter> &in, size_t) {
  927. array &a = out_->get<array>();
  928. a.push_back(value());
  929. default_parse_context ctx(&a.back());
  930. return _parse(ctx, in);
  931. }
  932. bool parse_array_stop(size_t) {
  933. return true;
  934. }
  935. bool parse_object_start() {
  936. *out_ = value(object_type, false);
  937. return true;
  938. }
  939. template <typename Iter> bool parse_object_item(input<Iter> &in, const std::string &key) {
  940. object &o = out_->get<object>();
  941. default_parse_context ctx(&o[key]);
  942. return _parse(ctx, in);
  943. }
  944. private:
  945. default_parse_context(const default_parse_context &);
  946. default_parse_context &operator=(const default_parse_context &);
  947. };
  948. class null_parse_context {
  949. public:
  950. struct dummy_str {
  951. void push_back(int) {
  952. }
  953. };
  954. public:
  955. null_parse_context() {
  956. }
  957. bool set_null() {
  958. return true;
  959. }
  960. bool set_bool(bool) {
  961. return true;
  962. }
  963. #ifdef PICOJSON_USE_INT64
  964. bool set_int64(int64_t) {
  965. return true;
  966. }
  967. #endif
  968. bool set_number(double) {
  969. return true;
  970. }
  971. template <typename Iter> bool parse_string(input<Iter> &in) {
  972. dummy_str s;
  973. return _parse_string(s, in);
  974. }
  975. bool parse_array_start() {
  976. return true;
  977. }
  978. template <typename Iter> bool parse_array_item(input<Iter> &in, size_t) {
  979. return _parse(*this, in);
  980. }
  981. bool parse_array_stop(size_t) {
  982. return true;
  983. }
  984. bool parse_object_start() {
  985. return true;
  986. }
  987. template <typename Iter> bool parse_object_item(input<Iter> &in, const std::string &) {
  988. return _parse(*this, in);
  989. }
  990. private:
  991. null_parse_context(const null_parse_context &);
  992. null_parse_context &operator=(const null_parse_context &);
  993. };
  994. // obsolete, use the version below
  995. template <typename Iter> inline std::string parse(value &out, Iter &pos, const Iter &last) {
  996. std::string err;
  997. pos = parse(out, pos, last, &err);
  998. return err;
  999. }
  1000. template <typename Context, typename Iter> inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) {
  1001. input<Iter> in(first, last);
  1002. if (!_parse(ctx, in) && err != NULL) {
  1003. char buf[64];
  1004. SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
  1005. *err = buf;
  1006. while (1) {
  1007. int ch = in.getc();
  1008. if (ch == -1 || ch == '\n') {
  1009. break;
  1010. } else if (ch >= ' ') {
  1011. err->push_back(static_cast<char>(ch));
  1012. }
  1013. }
  1014. }
  1015. return in.cur();
  1016. }
  1017. template <typename Iter> inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) {
  1018. default_parse_context ctx(&out);
  1019. return _parse(ctx, first, last, err);
  1020. }
  1021. inline std::string parse(value &out, const std::string &s) {
  1022. std::string err;
  1023. parse(out, s.begin(), s.end(), &err);
  1024. return err;
  1025. }
  1026. inline std::string parse(value &out, std::istream &is) {
  1027. std::string err;
  1028. parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
  1029. return err;
  1030. }
  1031. template <typename T> struct last_error_t { static std::string s; };
  1032. template <typename T> std::string last_error_t<T>::s;
  1033. inline void set_last_error(const std::string &s) {
  1034. last_error_t<bool>::s = s;
  1035. }
  1036. inline const std::string &get_last_error() {
  1037. return last_error_t<bool>::s;
  1038. }
  1039. inline bool operator==(const value &x, const value &y) {
  1040. if (x.is<null>())
  1041. return y.is<null>();
  1042. #define PICOJSON_CMP(type) \
  1043. if (x.is<type>()) \
  1044. return y.is<type>() && x.get<type>() == y.get<type>()
  1045. PICOJSON_CMP(bool);
  1046. PICOJSON_CMP(double);
  1047. PICOJSON_CMP(std::string);
  1048. PICOJSON_CMP(array);
  1049. PICOJSON_CMP(object);
  1050. #undef PICOJSON_CMP
  1051. PICOJSON_ASSERT(0);
  1052. #ifdef _MSC_VER
  1053. __assume(0);
  1054. #endif
  1055. return false;
  1056. }
  1057. inline bool operator!=(const value &x, const value &y) {
  1058. return !(x == y);
  1059. }
  1060. }
  1061. #if !PICOJSON_USE_RVALUE_REFERENCE
  1062. namespace std {
  1063. template <> inline void swap(picojson::value &x, picojson::value &y) {
  1064. x.swap(y);
  1065. }
  1066. }
  1067. #endif
  1068. inline std::istream &operator>>(std::istream &is, picojson::value &x) {
  1069. picojson::set_last_error(std::string());
  1070. const std::string err(picojson::parse(x, is));
  1071. if (!err.empty()) {
  1072. picojson::set_last_error(err);
  1073. is.setstate(std::ios::failbit);
  1074. }
  1075. return is;
  1076. }
  1077. inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
  1078. x.serialize(std::ostream_iterator<char>(os));
  1079. return os;
  1080. }
  1081. #ifdef _MSC_VER
  1082. #pragma warning(pop)
  1083. #endif
  1084. #endif