[Common] Fixed invalid parsing of decimal values
[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         locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
920         f = strtod_l(num_str.c_str(), &endp, loc);
921         freelocale(loc);
922         if (endp == num_str.c_str() + num_str.size()) {
923           ctx.set_number(f);
924           return true;
925         }
926         return false;
927       }
928       break;
929   }
930   in.ungetc();
931   return false;
932 }
933
934 class deny_parse_context {
935  public:
936   bool set_null() {
937     return false;
938   }
939   bool set_bool(bool) {
940     return false;
941   }
942 #ifdef PICOJSON_USE_INT64
943   bool set_int64(int64_t) {
944     return false;
945   }
946 #endif
947   bool set_number(double) {
948     return false;
949   }
950   template <typename Iter>
951   bool parse_string(input<Iter> &) {
952     return false;
953   }
954   bool parse_array_start() {
955     return false;
956   }
957   template <typename Iter>
958   bool parse_array_item(input<Iter> &, size_t) {
959     return false;
960   }
961   bool parse_array_stop(size_t) {
962     return false;
963   }
964   bool parse_object_start() {
965     return false;
966   }
967   template <typename Iter>
968   bool parse_object_item(input<Iter> &, const std::string &) {
969     return false;
970   }
971 };
972
973 class default_parse_context {
974  protected:
975   value *out_;
976
977  public:
978   default_parse_context(value *out) : out_(out) {
979   }
980   bool set_null() {
981     *out_ = value();
982     return true;
983   }
984   bool set_bool(bool b) {
985     *out_ = value(b);
986     return true;
987   }
988 #ifdef PICOJSON_USE_INT64
989   bool set_int64(int64_t i) {
990     *out_ = value(i);
991     return true;
992   }
993 #endif
994   bool set_number(double f) {
995     *out_ = value(f);
996     return true;
997   }
998   template <typename Iter>
999   bool parse_string(input<Iter> &in) {
1000     *out_ = value(string_type, false);
1001     return _parse_string(out_->get<std::string>(), in);
1002   }
1003   bool parse_array_start() {
1004     *out_ = value(array_type, false);
1005     return true;
1006   }
1007   template <typename Iter>
1008   bool parse_array_item(input<Iter> &in, size_t) {
1009     array &a = out_->get<array>();
1010     a.push_back(value());
1011     default_parse_context ctx(&a.back());
1012     return _parse(ctx, in);
1013   }
1014   bool parse_array_stop(size_t) {
1015     return true;
1016   }
1017   bool parse_object_start() {
1018     *out_ = value(object_type, false);
1019     return true;
1020   }
1021   template <typename Iter>
1022   bool parse_object_item(input<Iter> &in, const std::string &key) {
1023     object &o = out_->get<object>();
1024     default_parse_context ctx(&o[key]);
1025     return _parse(ctx, in);
1026   }
1027
1028  private:
1029   default_parse_context(const default_parse_context &);
1030   default_parse_context &operator=(const default_parse_context &);
1031 };
1032
1033 class null_parse_context {
1034  public:
1035   struct dummy_str {
1036     void push_back(int) {
1037     }
1038   };
1039
1040  public:
1041   null_parse_context() {
1042   }
1043   bool set_null() {
1044     return true;
1045   }
1046   bool set_bool(bool) {
1047     return true;
1048   }
1049 #ifdef PICOJSON_USE_INT64
1050   bool set_int64(int64_t) {
1051     return true;
1052   }
1053 #endif
1054   bool set_number(double) {
1055     return true;
1056   }
1057   template <typename Iter>
1058   bool parse_string(input<Iter> &in) {
1059     dummy_str s;
1060     return _parse_string(s, in);
1061   }
1062   bool parse_array_start() {
1063     return true;
1064   }
1065   template <typename Iter>
1066   bool parse_array_item(input<Iter> &in, size_t) {
1067     return _parse(*this, in);
1068   }
1069   bool parse_array_stop(size_t) {
1070     return true;
1071   }
1072   bool parse_object_start() {
1073     return true;
1074   }
1075   template <typename Iter>
1076   bool parse_object_item(input<Iter> &in, const std::string &) {
1077     return _parse(*this, in);
1078   }
1079
1080  private:
1081   null_parse_context(const null_parse_context &);
1082   null_parse_context &operator=(const null_parse_context &);
1083 };
1084
1085 // obsolete, use the version below
1086 template <typename Iter>
1087 inline std::string parse(value &out, Iter &pos, const Iter &last) {
1088   std::string err;
1089   pos = parse(out, pos, last, &err);
1090   return err;
1091 }
1092
1093 template <typename Context, typename Iter>
1094 inline Iter _parse(Context &ctx, const Iter &first, const Iter &last, std::string *err) {
1095   input<Iter> in(first, last);
1096   if (!_parse(ctx, in) && err != NULL) {
1097     char buf[64];
1098     SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
1099     *err = buf;
1100     while (1) {
1101       int ch = in.getc();
1102       if (ch == -1 || ch == '\n') {
1103         break;
1104       } else if (ch >= ' ') {
1105         err->push_back(static_cast<char>(ch));
1106       }
1107     }
1108   }
1109   return in.cur();
1110 }
1111
1112 template <typename Iter>
1113 inline Iter parse(value &out, const Iter &first, const Iter &last, std::string *err) {
1114   default_parse_context ctx(&out);
1115   return _parse(ctx, first, last, err);
1116 }
1117
1118 inline std::string parse(value &out, const std::string &s) {
1119   std::string err;
1120   parse(out, s.begin(), s.end(), &err);
1121   return err;
1122 }
1123
1124 inline std::string parse(value &out, std::istream &is) {
1125   std::string err;
1126   parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1127   return err;
1128 }
1129
1130 template <typename T>
1131 struct last_error_t {
1132   static std::string s;
1133 };
1134 template <typename T>
1135 std::string last_error_t<T>::s;
1136
1137 inline void set_last_error(const std::string &s) {
1138   last_error_t<bool>::s = s;
1139 }
1140
1141 inline const std::string &get_last_error() {
1142   return last_error_t<bool>::s;
1143 }
1144
1145 inline bool operator==(const value &x, const value &y) {
1146   if (x.is<null>()) return y.is<null>();
1147 #define PICOJSON_CMP(type) \
1148   if (x.is<type>()) return y.is<type>() && x.get<type>() == y.get<type>()
1149   PICOJSON_CMP(bool);
1150   PICOJSON_CMP(double);
1151   PICOJSON_CMP(std::string);
1152   PICOJSON_CMP(array);
1153   PICOJSON_CMP(object);
1154 #undef PICOJSON_CMP
1155   Assert(0);
1156 #ifdef _MSC_VER
1157   __assume(0);
1158 #endif
1159   return false;
1160 }
1161
1162 inline bool operator!=(const value &x, const value &y) {
1163   return !(x == y);
1164 }
1165 }
1166
1167 #if !PICOJSON_USE_RVALUE_REFERENCE
1168 namespace std {
1169 template <>
1170 inline void swap(picojson::value &x, picojson::value &y) {
1171   x.swap(y);
1172 }
1173 }
1174 #endif
1175
1176 inline std::istream &operator>>(std::istream &is, picojson::value &x) {
1177   picojson::set_last_error(std::string());
1178   const std::string err(picojson::parse(x, is));
1179   if (!err.empty()) {
1180     picojson::set_last_error(err);
1181     is.setstate(std::ios::failbit);
1182   }
1183   return is;
1184 }
1185
1186 inline std::ostream &operator<<(std::ostream &os, const picojson::value &x) {
1187   x.serialize(std::ostream_iterator<char>(os));
1188   return os;
1189 }
1190 #ifdef _MSC_VER
1191 #pragma warning(pop)
1192 #endif
1193
1194 #endif