c6b9aded56842dc2f067ba8f7531a174f44e2d68
[platform/core/api/webapi-plugins.git] / src / common / picojson.h
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
31 #include <algorithm>
32 #include <cstddef>
33 #include <cstdio>
34 #include <cstdlib>
35 #include <cstring>
36 #include <iomanip>
37 #include <iostream>
38 #include <iterator>
39 #include <limits>
40 #include <map>
41 #include <memory>
42 #include <sstream>
43 #include <stdexcept>
44 #include <string>
45 #include <utility>
46 #include <vector>
47 #include "common/assert.h"
48
49 // for isnan/isinf
50 #if __cplusplus >= 201103L
51 #include <cmath>
52 #else
53 extern "C" {
54 #ifdef _MSC_VER
55 #include <float.h>
56 #elif defined(__INTEL_COMPILER)
57 #include <mathimf.h>
58 #else
59 #include <math.h>
60 #endif
61 }
62 #endif
63
64 #ifndef PICOJSON_USE_RVALUE_REFERENCE
65 #if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || \
66     (defined(_MSC_VER) && _MSC_VER >= 1600)
67 #define PICOJSON_USE_RVALUE_REFERENCE 1
68 #else
69 #define PICOJSON_USE_RVALUE_REFERENCE 0
70 #endif
71 #endif  // PICOJSON_USE_RVALUE_REFERENCE
72
73 #ifndef PICOJSON_NOEXCEPT
74 #if PICOJSON_USE_RVALUE_REFERENCE
75 #define PICOJSON_NOEXCEPT noexcept
76 #else
77 #define PICOJSON_NOEXCEPT throw()
78 #endif
79 #endif
80
81 // experimental support for int64_t (see README.mkdn for detail)
82 #ifdef PICOJSON_USE_INT64
83 #define __STDC_FORMAT_MACROS
84 #include <errno.h>
85 #include <inttypes.h>
86 #endif
87
88 #ifdef _MSC_VER
89 #define SNPRINTF _snprintf_s
90 #pragma warning(push)
91 #pragma warning(disable : 4244)  // conversion from int to char
92 #pragma warning(disable : 4127)  // conditional expression is constant
93 #pragma warning(disable : 4702)  // unreachable code
94 #else
95 #define SNPRINTF snprintf
96 #endif
97
98 namespace picojson {
99
100 enum {
101   null_type,
102   boolean_type,
103   number_type,
104   string_type,
105   array_type,
106   object_type
107 #ifdef PICOJSON_USE_INT64
108   ,
109   int64_type
110 #endif
111 };
112
113 enum { INDENT_WIDTH = 2 };
114
115 struct null {};
116
117 class value {
118  public:
119   typedef std::vector<value> array;
120   typedef std::map<std::string, value> object;
121   union _storage {
122     bool boolean_;
123     double number_;
124 #ifdef PICOJSON_USE_INT64
125     int64_t int64_;
126 #endif
127     std::string *string_;
128     array *array_;
129     object *object_;
130   };
131
132  protected:
133   int type_;
134   _storage u_;
135
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>
163   bool is() const;
164   template <typename T>
165   const T &get() const;
166   template <typename T>
167   T &get();
168   template <typename T>
169   void set(const T &);
170 #if PICOJSON_USE_RVALUE_REFERENCE
171   template <typename T>
172   void set(T &&);
173 #endif
174   bool evaluate_as_boolean() const;
175   const value &get(const size_t idx) const;
176   const value &get(const std::string &key) const;
177   value &get(const size_t idx);
178   value &get(const std::string &key);
179
180   bool contains(const size_t idx) const;
181   bool contains(const std::string &key) const;
182   std::string to_str() const;
183   template <typename Iter>
184   void serialize(Iter os, bool prettify = false) const;
185   std::string serialize(bool prettify = false) const;
186
187  private:
188   template <typename T>
189   value(const T *);  // intentionally defined to block implicit conversion of pointer to bool
190   template <typename Iter>
191   static void _indent(Iter os, int indent);
192   template <typename Iter>
193   void _serialize(Iter os, int indent) const;
194   std::string _serialize(int indent) const;
195   void clear();
196 };
197
198 typedef value::array array;
199 typedef value::object object;
200
201 inline value::value() : type_(null_type), u_() {
202 }
203
204 inline value::value(int type, bool) : type_(type), u_() {
205   switch (type) {
206 #define INIT(p, v) \
207   case p##type:    \
208     u_.p = v;      \
209     break
210     INIT(boolean_, false);
211     INIT(number_, 0.0);
212 #ifdef PICOJSON_USE_INT64
213     INIT(int64_, 0);
214 #endif
215     INIT(string_, new std::string());
216     INIT(array_, new array());
217     INIT(object_, new object());
218 #undef INIT
219     default:
220       break;
221   }
222 }
223
224 inline value::value(bool b) : type_(boolean_type), u_() {
225   u_.boolean_ = b;
226 }
227
228 #ifdef PICOJSON_USE_INT64
229 inline value::value(int64_t i) : type_(int64_type), u_() {
230   u_.int64_ = i;
231 }
232 #endif
233
234 inline value::value(double n) : type_(number_type), u_() {
235   if (
236 #ifdef _MSC_VER
237       !_finite(n)
238 #elif __cplusplus >= 201103L
239       std::isnan(n) || std::isinf(n)
240 #else
241       isnan(n) || isinf(n)
242 #endif
243           ) {
244     throw std::overflow_error("");
245   }
246   u_.number_ = n;
247 }
248
249 inline value::value(const std::string &s) : type_(string_type), u_() {
250   u_.string_ = new std::string(s);
251 }
252
253 inline value::value(const array &a) : type_(array_type), u_() {
254   u_.array_ = new array(a);
255 }
256
257 inline value::value(const object &o) : type_(object_type), u_() {
258   u_.object_ = new object(o);
259 }
260
261 #if PICOJSON_USE_RVALUE_REFERENCE
262 inline value::value(std::string &&s) : type_(string_type), u_() {
263   u_.string_ = new std::string(std::move(s));
264 }
265
266 inline value::value(array &&a) : type_(array_type), u_() {
267   u_.array_ = new array(std::move(a));
268 }
269
270 inline value::value(object &&o) : type_(object_type), u_() {
271   u_.object_ = new object(std::move(o));
272 }
273 #endif
274
275 inline value::value(const char *s) : type_(string_type), u_() {
276   u_.string_ = new std::string(s);
277 }
278
279 inline value::value(const char *s, size_t len) : type_(string_type), u_() {
280   u_.string_ = new std::string(s, len);
281 }
282
283 inline void value::clear() {
284   switch (type_) {
285 #define DEINIT(p) \
286   case p##type:   \
287     delete u_.p;  \
288     break
289     DEINIT(string_);
290     DEINIT(array_);
291     DEINIT(object_);
292 #undef DEINIT
293     default:
294       break;
295   }
296 }
297
298 inline value::~value() {
299   clear();
300 }
301
302 inline value::value(const value &x) : type_(x.type_), u_() {
303   switch (type_) {
304 #define INIT(p, v) \
305   case p##type:    \
306     u_.p = v;      \
307     break
308     INIT(string_, new std::string(*x.u_.string_));
309     INIT(array_, new array(*x.u_.array_));
310     INIT(object_, new object(*x.u_.object_));
311 #undef INIT
312     default:
313       u_ = x.u_;
314       break;
315   }
316 }
317
318 inline value &value::operator=(const value &x) {
319   if (this != &x) {
320     value t(x);
321     swap(t);
322   }
323   return *this;
324 }
325
326 #if PICOJSON_USE_RVALUE_REFERENCE
327 inline value::value(value &&x) PICOJSON_NOEXCEPT : type_(null_type), u_() {
328   swap(x);
329 }
330 inline value &value::operator=(value &&x) PICOJSON_NOEXCEPT {
331   swap(x);
332   return *this;
333 }
334 #endif
335 inline void value::swap(value &x) PICOJSON_NOEXCEPT {
336   std::swap(type_, x.type_);
337   std::swap(u_, x.u_);
338 }
339
340 #define IS(ctype, jtype)                 \
341   template <>                            \
342   inline bool value::is<ctype>() const { \
343     return type_ == jtype##_type;        \
344   }
345 IS(null, null)
346 IS(bool, boolean)
347 #ifdef PICOJSON_USE_INT64
348 IS(int64_t, int64)
349 #endif
350 IS(std::string, string)
351 IS(array, array)
352 IS(object, object)
353 #undef IS
354 template <>
355 inline bool value::is<double>() const {
356   return type_ == number_type
357 #ifdef PICOJSON_USE_INT64
358          || type_ == int64_type
359 #endif
360       ;
361 }
362
363 #define GET(ctype, var)                                                         \
364   template <>                                                                   \
365   inline const ctype &value::get<ctype>() const {                               \
366     Assert("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
367     return var;                                                                 \
368   }                                                                             \
369   template <>                                                                   \
370   inline ctype &value::get<ctype>() {                                           \
371     Assert("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
372     return var;                                                                 \
373   }
374 GET(bool, u_.boolean_)
375 GET(std::string, *u_.string_)
376 GET(array, *u_.array_)
377 GET(object, *u_.object_)
378 #ifdef PICOJSON_USE_INT64
379 GET(double, (type_ == int64_type && (const_cast<value *>(this)->type_ = number_type,
380                                      const_cast<value *>(this)->u_.number_ = u_.int64_),
381              u_.number_))
382 GET(int64_t, u_.int64_)
383 #else
384 GET(double, u_.number_)
385 #endif
386 #undef GET
387
388 #define SET(ctype, jtype, setter)                    \
389   template <>                                        \
390   inline void value::set<ctype>(const ctype &_val) { \
391     clear();                                         \
392     type_ = jtype##_type;                            \
393     setter                                           \
394   }
395 SET(bool, boolean, u_.boolean_ = _val;)
396 SET(std::string, string, u_.string_ = new std::string(_val);)
397 SET(array, array, u_.array_ = new array(_val);)
398 SET(object, object, u_.object_ = new object(_val);)
399 SET(double, number, u_.number_ = _val;)
400 #ifdef PICOJSON_USE_INT64
401 SET(int64_t, int64, u_.int64_ = _val;)
402 #endif
403 #undef SET
404
405 #if PICOJSON_USE_RVALUE_REFERENCE
406 #define MOVESET(ctype, jtype, setter)            \
407   template <>                                    \
408   inline void value::set<ctype>(ctype && _val) { \
409     clear();                                     \
410     type_ = jtype##_type;                        \
411     setter                                       \
412   }
413 MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));)
414 MOVESET(array, array, u_.array_ = new array(std::move(_val));)
415 MOVESET(object, object, u_.object_ = new object(std::move(_val));)
416 #undef MOVESET
417 #endif
418
419 inline bool value::evaluate_as_boolean() const {
420   switch (type_) {
421     case null_type:
422       return false;
423     case boolean_type:
424       return u_.boolean_;
425     case number_type:
426       return u_.number_ != 0;
427 #ifdef PICOJSON_USE_INT64
428     case int64_type:
429       return u_.int64_ != 0;
430 #endif
431     case string_type:
432       return !u_.string_->empty();
433     default:
434       return true;
435   }
436 }
437
438 inline const value &value::get(const size_t idx) const {
439   static value s_null;
440   Assert(is<array>());
441   return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
442 }
443
444 inline value &value::get(const size_t idx) {
445   static value s_null;
446   Assert(is<array>());
447   return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
448 }
449
450 inline const value &value::get(const std::string &key) const {
451   static value s_null;
452   Assert(is<object>());
453   object::const_iterator i = u_.object_->find(key);
454   return i != u_.object_->end() ? i->second : s_null;
455 }
456
457 inline value &value::get(const std::string &key) {
458   static value s_null;
459   Assert(is<object>());
460   object::iterator i = u_.object_->find(key);
461   return i != u_.object_->end() ? i->second : s_null;
462 }
463
464 inline bool value::contains(const size_t idx) const {
465   Assert(is<array>());
466   return idx < u_.array_->size();
467 }
468
469 inline bool value::contains(const std::string &key) const {
470   Assert(is<object>());
471   object::const_iterator i = u_.object_->find(key);
472   return i != u_.object_->end();
473 }
474
475 inline std::string value::to_str() const {
476   switch (type_) {
477     case null_type:
478       return "null";
479     case boolean_type:
480       return u_.boolean_ ? "true" : "false";
481 #ifdef PICOJSON_USE_INT64
482     case int64_type: {
483       char buf[sizeof("-9223372036854775808")];
484       SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
485       return buf;
486     }
487 #endif
488     case number_type: {
489       std::stringstream num_str;
490       num_str.imbue(std::locale::classic());
491       num_str << std::setprecision(16) << u_.number_;
492       return num_str.str();
493     }
494     case string_type:
495       return *u_.string_;
496     case array_type:
497       return "array";
498     case object_type:
499       return "object";
500     default:
501       Assert(0);
502 #ifdef _MSC_VER
503       __assume(0);
504 #endif
505   }
506   return std::string();
507 }
508
509 template <typename Iter>
510 void copy(const std::string &s, Iter oi) {
511   std::copy(s.begin(), s.end(), oi);
512 }
513
514 template <typename Iter>
515 struct serialize_str_char {
516   Iter oi;
517   void operator()(char c) {
518     // C0 control characters, 00-1F
519     static const char *u_map[] = {
520         "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
521         "\\b",     "\\t",     "\\n",     "\\u000b", "\\f",     "\\r",     "\\u000e", "\\u000f",
522         "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
523         "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"};
524     // To be sure we could rewrite C1 control characters also (first decode UTF-8, check, then map
525     // to
526     // \u sequence), but for now chromium allows C1 in JSON.parse
527     switch (c) {
528       case '"':
529         copy("\\\"", oi);
530         break;
531       case '\\':
532         copy("\\\\", oi);
533         break;
534       case '\x7f':
535         copy("\\u007f", oi);
536         break;
537       default:
538         if ((unsigned char)c < 0x20) {
539           const char *u = u_map[(unsigned char)c];
540           while (*u) {
541             *oi++ = *u++;
542           }
543         } else {
544           *oi++ = c;
545         }
546         break;
547     }
548   }
549 };
550
551 template <typename Iter>
552 void serialize_str(const std::string &s, Iter oi) {
553   *oi++ = '"';
554   serialize_str_char<Iter> process_char = {oi};
555   std::for_each(s.begin(), s.end(), process_char);
556   *oi++ = '"';
557 }
558
559 template <typename Iter>
560 void value::serialize(Iter oi, bool prettify) const {
561   return _serialize(oi, prettify ? 0 : -1);
562 }
563
564 inline std::string value::serialize(bool prettify) const {
565   return _serialize(prettify ? 0 : -1);
566 }
567
568 template <typename Iter>
569 void value::_indent(Iter oi, int indent) {
570   *oi++ = '\n';
571   for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
572     *oi++ = ' ';
573   }
574 }
575
576 template <typename Iter>
577 void value::_serialize(Iter oi, int indent) const {
578   switch (type_) {
579     case string_type:
580       serialize_str(*u_.string_, oi);
581       break;
582     case array_type: {
583       *oi++ = '[';
584       if (indent != -1) {
585         ++indent;
586       }
587       for (array::const_iterator i = u_.array_->begin(); i != u_.array_->end(); ++i) {
588         if (i != u_.array_->begin()) {
589           *oi++ = ',';
590         }
591         if (indent != -1) {
592           _indent(oi, indent);
593         }
594         i->_serialize(oi, indent);
595       }
596       if (indent != -1) {
597         --indent;
598         if (!u_.array_->empty()) {
599           _indent(oi, indent);
600         }
601       }
602       *oi++ = ']';
603       break;
604     }
605     case object_type: {
606       *oi++ = '{';
607       if (indent != -1) {
608         ++indent;
609       }
610       for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) {
611         if (i != u_.object_->begin()) {
612           *oi++ = ',';
613         }
614         if (indent != -1) {
615           _indent(oi, indent);
616         }
617         serialize_str(i->first, oi);
618         *oi++ = ':';
619         if (indent != -1) {
620           *oi++ = ' ';
621         }
622         i->second._serialize(oi, indent);
623       }
624       if (indent != -1) {
625         --indent;
626         if (!u_.object_->empty()) {
627           _indent(oi, indent);
628         }
629       }
630       *oi++ = '}';
631       break;
632     }
633     default:
634       copy(to_str(), oi);
635       break;
636   }
637   if (indent == 0) {
638     *oi++ = '\n';
639   }
640 }
641
642 inline std::string value::_serialize(int indent) const {
643   std::string s;
644   _serialize(std::back_inserter(s), indent);
645   return s;
646 }
647
648 template <typename Iter>
649 class input {
650  protected:
651   Iter cur_, end_;
652   bool consumed_;
653   int line_;
654
655  public:
656   input(const Iter &first, const Iter &last) : cur_(first), end_(last), consumed_(false), line_(1) {
657   }
658   int getc() {
659     if (consumed_) {
660       if (*cur_ == '\n') {
661         ++line_;
662       }
663       ++cur_;
664     }
665     if (cur_ == end_) {
666       consumed_ = false;
667       return -1;
668     }
669     consumed_ = true;
670     return *cur_ & 0xff;
671   }
672   void ungetc() {
673     consumed_ = false;
674   }
675   Iter cur() const {
676     if (consumed_) {
677       input<Iter> *self = const_cast<input<Iter> *>(this);
678       self->consumed_ = false;
679       ++self->cur_;
680     }
681     return cur_;
682   }
683   int line() const {
684     return line_;
685   }
686   void skip_ws() {
687     while (1) {
688       int ch = getc();
689       if (!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
690         ungetc();
691         break;
692       }
693     }
694   }
695   bool expect(const int expected) {
696     skip_ws();
697     if (getc() != expected) {
698       ungetc();
699       return false;
700     }
701     return true;
702   }
703   bool match(const std::string &pattern) {
704     for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
705       if (getc() != *pi) {
706         ungetc();
707         return false;
708       }
709     }
710     return true;
711   }
712 };
713
714 template <typename Iter>
715 inline int _parse_quadhex(input<Iter> &in) {
716   int uni_ch = 0, hex;
717   for (int i = 0; i < 4; i++) {
718     if ((hex = in.getc()) == -1) {
719       return -1;
720     }
721     if ('0' <= hex && hex <= '9') {
722       hex -= '0';
723     } else if ('A' <= hex && hex <= 'F') {
724       hex -= 'A' - 0xa;
725     } else if ('a' <= hex && hex <= 'f') {
726       hex -= 'a' - 0xa;
727     } else {
728       in.ungetc();
729       return -1;
730     }
731     uni_ch = uni_ch * 16 + hex;
732   }
733   return uni_ch;
734 }
735
736 template <typename String, typename Iter>
737 inline bool _parse_codepoint(String &out, input<Iter> &in) {
738   int uni_ch;
739   if ((uni_ch = _parse_quadhex(in)) == -1) {
740     return false;
741   }
742   if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
743     if (0xdc00 <= uni_ch) {
744       // a second 16-bit of a surrogate pair appeared
745       return false;
746     }
747     // first 16-bit of surrogate pair, get the next one
748     if (in.getc() != '\\' || in.getc() != 'u') {
749       in.ungetc();
750       return false;
751     }
752     int second = _parse_quadhex(in);
753     if (!(0xdc00 <= second && second <= 0xdfff)) {
754       return false;
755     }
756     uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
757     uni_ch += 0x10000;
758   }
759   if (uni_ch < 0x80) {
760     out.push_back(static_cast<char>(uni_ch));
761   } else {
762     if (uni_ch < 0x800) {
763       out.push_back(static_cast<char>(0xc0 | (uni_ch >> 6)));
764     } else {
765       if (uni_ch < 0x10000) {
766         out.push_back(static_cast<char>(0xe0 | (uni_ch >> 12)));
767       } else {
768         out.push_back(static_cast<char>(0xf0 | (uni_ch >> 18)));
769         out.push_back(static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
770       }
771       out.push_back(static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
772     }
773     out.push_back(static_cast<char>(0x80 | (uni_ch & 0x3f)));
774   }
775   return true;
776 }
777
778 template <typename String, typename Iter>
779 inline bool _parse_string(String &out, input<Iter> &in) {
780   while (1) {
781     int ch = in.getc();
782     if (ch < ' ') {
783       in.ungetc();
784       return false;
785     } else if (ch == '"') {
786       return true;
787     } else if (ch == '\\') {
788       if ((ch = in.getc()) == -1) {
789         return false;
790       }
791       switch (ch) {
792 #define MAP(sym, val)   \
793   case sym:             \
794     out.push_back(val); \
795     break
796         MAP('"', '\"');
797         MAP('\\', '\\');
798         MAP('/', '/');
799         MAP('b', '\b');
800         MAP('f', '\f');
801         MAP('n', '\n');
802         MAP('r', '\r');
803         MAP('t', '\t');
804 #undef MAP
805         case 'u':
806           if (!_parse_codepoint(out, in)) {
807             return false;
808           }
809           break;
810         default:
811           return false;
812       }
813     } else {
814       out.push_back(static_cast<char>(ch));
815     }
816   }
817   return false;
818 }
819
820 template <typename Context, typename Iter>
821 inline bool _parse_array(Context &ctx, input<Iter> &in) {
822   if (!ctx.parse_array_start()) {
823     return false;
824   }
825   size_t idx = 0;
826   if (in.expect(']')) {
827     return ctx.parse_array_stop(idx);
828   }
829   do {
830     if (!ctx.parse_array_item(in, idx)) {
831       return false;
832     }
833     idx++;
834   } while (in.expect(','));
835   return in.expect(']') && ctx.parse_array_stop(idx);
836 }
837
838 template <typename Context, typename Iter>
839 inline bool _parse_object(Context &ctx, input<Iter> &in) {
840   if (!ctx.parse_object_start()) {
841     return false;
842   }
843   if (in.expect('}')) {
844     return true;
845   }
846   do {
847     std::string key;
848     if (!in.expect('"') || !_parse_string(key, in) || !in.expect(':')) {
849       return false;
850     }
851     if (!ctx.parse_object_item(in, key)) {
852       return false;
853     }
854   } while (in.expect(','));
855   return in.expect('}');
856 }
857
858 template <typename Iter>
859 inline std::string _parse_number(input<Iter> &in) {
860   std::stringstream num_str;
861   num_str.imbue(std::locale::classic());
862
863   while (true) {
864     int ch = in.getc();
865     if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E' || ch == '.') {
866       num_str.put(ch);
867     } else {
868       in.ungetc();
869       break;
870     }
871   }
872
873   return num_str.str();
874 }
875
876 template <typename Context, typename Iter>
877 inline bool _parse(Context &ctx, input<Iter> &in) {
878   in.skip_ws();
879   int ch = in.getc();
880   switch (ch) {
881 #define IS(ch, text, op)        \
882   case ch:                      \
883     if (in.match(text) && op) { \
884       return true;              \
885     } else {                    \
886       return false;             \
887     }
888     IS('n', "ull", ctx.set_null());
889     IS('f', "alse", ctx.set_bool(false));
890     IS('t', "rue", ctx.set_bool(true));
891 #undef IS
892     case '"':
893       return ctx.parse_string(in);
894     case '[':
895       return _parse_array(ctx, in);
896     case '{':
897       return _parse_object(ctx, in);
898     default:
899       if (('0' <= ch && ch <= '9') || ch == '-') {
900         double f;
901         char *endp;
902         in.ungetc();
903         std::string num_str(_parse_number(in));
904         if (num_str.empty()) {
905           return false;
906         }
907 #ifdef PICOJSON_USE_INT64
908         {
909           errno = 0;
910           intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
911           if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival &&
912               ival <= std::numeric_limits<int64_t>::max() &&
913               endp == num_str.c_str() + num_str.size()) {
914             ctx.set_int64(ival);
915             return true;
916           }
917         }
918 #endif
919         f = strtod(num_str.c_str(), &endp);
920         if (endp == num_str.c_str() + num_str.size()) {
921           ctx.set_number(f);
922           return true;
923         }
924         return false;
925       }
926       break;
927   }
928   in.ungetc();
929   return false;
930 }
931
932 class deny_parse_context {
933  public:
934   bool set_null() {
935     return false;
936   }
937   bool set_bool(bool) {
938     return false;
939   }
940 #ifdef PICOJSON_USE_INT64
941   bool set_int64(int64_t) {
942     return false;
943   }
944 #endif
945   bool set_number(double) {
946     return false;
947   }
948   template <typename Iter>
949   bool parse_string(input<Iter> &) {
950     return false;
951   }
952   bool parse_array_start() {
953     return false;
954   }
955   template <typename Iter>
956   bool parse_array_item(input<Iter> &, size_t) {
957     return false;
958   }
959   bool parse_array_stop(size_t) {
960     return false;
961   }
962   bool parse_object_start() {
963     return false;
964   }
965   template <typename Iter>
966   bool parse_object_item(input<Iter> &, const std::string &) {
967     return false;
968   }
969 };
970
971 class default_parse_context {
972  protected:
973   value *out_;
974
975  public:
976   default_parse_context(value *out) : out_(out) {
977   }
978   bool set_null() {
979     *out_ = value();
980     return true;
981   }
982   bool set_bool(bool b) {
983     *out_ = value(b);
984     return true;
985   }
986 #ifdef PICOJSON_USE_INT64
987   bool set_int64(int64_t i) {
988     *out_ = value(i);
989     return true;
990   }
991 #endif
992   bool set_number(double f) {
993     *out_ = value(f);
994     return true;
995   }
996   template <typename Iter>
997   bool parse_string(input<Iter> &in) {
998     *out_ = value(string_type, false);
999     return _parse_string(out_->get<std::string>(), in);
1000   }
1001   bool parse_array_start() {
1002     *out_ = value(array_type, false);
1003     return true;
1004   }
1005   template <typename Iter>
1006   bool parse_array_item(input<Iter> &in, size_t) {
1007     array &a = out_->get<array>();
1008     a.push_back(value());
1009     default_parse_context ctx(&a.back());
1010     return _parse(ctx, in);
1011   }
1012   bool parse_array_stop(size_t) {
1013     return true;
1014   }
1015   bool parse_object_start() {
1016     *out_ = value(object_type, false);
1017     return true;
1018   }
1019   template <typename Iter>
1020   bool parse_object_item(input<Iter> &in, const std::string &key) {
1021     object &o = out_->get<object>();
1022     default_parse_context ctx(&o[key]);
1023     return _parse(ctx, in);
1024   }
1025
1026  private:
1027   default_parse_context(const default_parse_context &);
1028   default_parse_context &operator=(const default_parse_context &);
1029 };
1030
1031 class null_parse_context {
1032  public:
1033   struct dummy_str {
1034     void push_back(int) {
1035     }
1036   };
1037
1038  public:
1039   null_parse_context() {
1040   }
1041   bool set_null() {
1042     return true;
1043   }
1044   bool set_bool(bool) {
1045     return true;
1046   }
1047 #ifdef PICOJSON_USE_INT64
1048   bool set_int64(int64_t) {
1049     return true;
1050   }
1051 #endif
1052   bool set_number(double) {
1053     return true;
1054   }
1055   template <typename Iter>
1056   bool parse_string(input<Iter> &in) {
1057     dummy_str s;
1058     return _parse_string(s, in);
1059   }
1060   bool parse_array_start() {
1061     return true;
1062   }
1063   template <typename Iter>
1064   bool parse_array_item(input<Iter> &in, size_t) {
1065     return _parse(*this, in);
1066   }
1067   bool parse_array_stop(size_t) {
1068     return true;
1069   }
1070   bool parse_object_start() {
1071     return true;
1072   }
1073   template <typename Iter>
1074   bool parse_object_item(input<Iter> &in, const std::string &) {
1075     return _parse(*this, in);
1076   }
1077
1078  private:
1079   null_parse_context(const null_parse_context &);
1080   null_parse_context &operator=(const null_parse_context &);
1081 };
1082
1083 // obsolete, use the version below
1084 template <typename Iter>
1085 inline std::string parse(value &out, Iter &pos, const Iter &last) {
1086   std::string err;
1087   pos = parse(out, pos, last, &err);
1088   return err;
1089 }
1090
1091 template <typename Context, typename Iter>
1092 inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) {
1093   input<Iter> in(first, last);
1094   if (!_parse(ctx, in) && err != NULL) {
1095     char buf[64];
1096     SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
1097     *err = buf;
1098     while (1) {
1099       int ch = in.getc();
1100       if (ch == -1 || ch == '\n') {
1101         break;
1102       } else if (ch >= ' ') {
1103         err->push_back(static_cast<char>(ch));
1104       }
1105     }
1106   }
1107   return in.cur();
1108 }
1109
1110 template <typename Iter>
1111 inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) {
1112   default_parse_context ctx(&out);
1113   return _parse(ctx, first, last, err);
1114 }
1115
1116 inline std::string parse(value &out, const std::string &s) {
1117   std::string err;
1118   parse(out, s.begin(), s.end(), &err);
1119   return err;
1120 }
1121
1122 inline std::string parse(value &out, std::istream &is) {
1123   std::string err;
1124   parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1125   return err;
1126 }
1127
1128 template <typename T>
1129 struct last_error_t {
1130   static std::string s;
1131 };
1132 template <typename T>
1133 std::string last_error_t<T>::s;
1134
1135 inline void set_last_error(const std::string &s) {
1136   last_error_t<bool>::s = s;
1137 }
1138
1139 inline const std::string &get_last_error() {
1140   return last_error_t<bool>::s;
1141 }
1142
1143 inline bool operator==(const value &x, const value &y) {
1144   if (x.is<null>()) return y.is<null>();
1145 #define PICOJSON_CMP(type) \
1146   if (x.is<type>()) return y.is<type>() && x.get<type>() == y.get<type>()
1147   PICOJSON_CMP(bool);
1148   PICOJSON_CMP(double);
1149   PICOJSON_CMP(std::string);
1150   PICOJSON_CMP(array);
1151   PICOJSON_CMP(object);
1152 #undef PICOJSON_CMP
1153   Assert(0);
1154 #ifdef _MSC_VER
1155   __assume(0);
1156 #endif
1157   return false;
1158 }
1159
1160 inline bool operator!=(const value &x, const value &y) {
1161   return !(x == y);
1162 }
1163 }
1164
1165 #if !PICOJSON_USE_RVALUE_REFERENCE
1166 namespace std {
1167 template <>
1168 inline void swap(picojson::value &x, picojson::value &y) {
1169   x.swap(y);
1170 }
1171 }
1172 #endif
1173
1174 inline std::istream &operator>>(std::istream &is, picojson::value &x) {
1175   picojson::set_last_error(std::string());
1176   const std::string err(picojson::parse(x, is));
1177   if (!err.empty()) {
1178     picojson::set_last_error(err);
1179     is.setstate(std::ios::failbit);
1180   }
1181   return is;
1182 }
1183
1184 inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
1185   x.serialize(std::ostream_iterator<char>(os));
1186   return os;
1187 }
1188 #ifdef _MSC_VER
1189 #pragma warning(pop)
1190 #endif
1191
1192 #endif