DALi Version 1.9.29
[platform/core/uifw/dali-demo.git] / third-party / pico-json.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 <iostream>
37 #include <iterator>
38 #include <limits>
39 #include <map>
40 #include <stdexcept>
41 #include <string>
42 #include <utility>
43 #include <vector>
44
45 // for isnan/isinf
46 #if __cplusplus >= 201103L
47 #include <cmath>
48 #else
49 extern "C"
50 {
51 #ifdef _MSC_VER
52 #include <float.h>
53 #elif defined(__INTEL_COMPILER)
54 #include <mathimf.h>
55 #else
56 #include <math.h>
57 #endif
58 }
59 #endif
60
61 #ifndef PICOJSON_USE_RVALUE_REFERENCE
62 #if(defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
63 #define PICOJSON_USE_RVALUE_REFERENCE 1
64 #else
65 #define PICOJSON_USE_RVALUE_REFERENCE 0
66 #endif
67 #endif //PICOJSON_USE_RVALUE_REFERENCE
68
69 // experimental support for int64_t (see README.mkdn for detail)
70 #ifdef PICOJSON_USE_INT64
71 #define __STDC_FORMAT_MACROS
72 #include <errno.h>
73 #include <inttypes.h>
74 #endif
75
76 // to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
77 #ifndef PICOJSON_USE_LOCALE
78 #define PICOJSON_USE_LOCALE 1
79 #endif
80 #if PICOJSON_USE_LOCALE
81 extern "C"
82 {
83 #include <locale.h>
84 }
85 #endif
86
87 #ifndef PICOJSON_ASSERT
88 #define PICOJSON_ASSERT(e)                 \
89   do                                       \
90   {                                        \
91     if(!(e)) throw std::runtime_error(#e); \
92   } while(0)
93 #endif
94
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
105 namespace picojson
106 {
107 enum
108 {
109   null_type,
110   boolean_type,
111   number_type,
112   string_type,
113   array_type,
114   object_type
115 #ifdef PICOJSON_USE_INT64
116   ,
117   int64_type
118 #endif
119 };
120
121 enum
122 {
123   INDENT_WIDTH = 2
124 };
125
126 struct null
127 {
128 };
129
130 class value
131 {
132 public:
133   typedef std::vector<value>           array;
134   typedef std::map<std::string, value> object;
135   union _storage
136   {
137     bool   boolean_;
138     double number_;
139 #ifdef PICOJSON_USE_INT64
140     int64_t int64_;
141 #endif
142     std::string* string_;
143     array*       array_;
144     object*      object_;
145   };
146
147 protected:
148   int      type_{};
149   _storage u_{};
150
151 public:
152   value();
153   value(int type, bool);
154   explicit value(bool b);
155 #ifdef PICOJSON_USE_INT64
156   explicit value(int64_t i);
157 #endif
158   explicit value(double n);
159   explicit value(const std::string& s);
160   explicit value(const array& a);
161   explicit value(const object& o);
162   explicit value(const char* s);
163   value(const char* s, size_t len);
164   ~value();
165   value(const value& x);
166   value& operator=(const value& x);
167 #if PICOJSON_USE_RVALUE_REFERENCE
168   value(value&& x) throw();
169   value& operator=(value&& x) throw();
170 #endif
171   void swap(value& x) throw();
172   template<typename T>
173   bool is() const;
174   template<typename T>
175   const T& get() const;
176   template<typename T>
177   T& get();
178   template<typename T>
179   void set(const T&);
180 #if PICOJSON_USE_RVALUE_REFERENCE
181   template<typename T>
182   void set(T&&);
183 #endif
184   bool         evaluate_as_boolean() const;
185   const value& get(size_t idx) const;
186   const value& get(const std::string& key) const;
187   value&       get(size_t idx);
188   value&       get(const std::string& key);
189
190   bool        contains(size_t idx) const;
191   bool        contains(const std::string& key) const;
192   std::string to_str() const;
193   template<typename Iter>
194   void        serialize(Iter os, bool prettify = false) const;
195   std::string serialize(bool prettify = false) const;
196
197 private:
198   template<typename T>
199   value(const T*); // intentionally defined to block implicit conversion of pointer to bool
200   template<typename Iter>
201   static void _indent(Iter os, int indent);
202   template<typename Iter>
203   void        _serialize(Iter os, int indent) const;
204   std::string _serialize(int indent) const;
205   void        clear();
206 };
207
208 typedef value::array  array;
209 typedef value::object object;
210
211 inline value::value()
212 : type_(null_type)
213 {
214 }
215
216 inline value::value(int type, bool)
217 : type_(type)
218 {
219   switch(type)
220   {
221 #define INIT(p, v) \
222   case p##type:    \
223     u_.p = v;      \
224     break
225     INIT(boolean_, false);
226     INIT(number_, 0.0);
227 #ifdef PICOJSON_USE_INT64
228     INIT(int64_, 0);
229 #endif
230     INIT(string_, new std::string());
231     INIT(array_, new array());
232     INIT(object_, new object());
233 #undef INIT
234     default:
235       break;
236   }
237 }
238
239 inline value::value(bool b)
240 : type_(boolean_type)
241 {
242   u_.boolean_ = b;
243 }
244
245 #ifdef PICOJSON_USE_INT64
246 inline value::value(int64_t i)
247 : type_(int64_type)
248 {
249   u_.int64_ = i;
250 }
251 #endif
252
253 inline value::value(double n)
254 : type_(number_type)
255 {
256   if(
257 #ifdef _MSC_VER
258     !_finite(n)
259 #elif __cplusplus >= 201103L || !(defined(isnan) && defined(isinf))
260     std::isnan(n) || std::isinf(n)
261 #else
262     isnan(n) || isinf(n)
263 #endif
264   )
265   {
266     throw std::overflow_error("");
267   }
268   u_.number_ = n;
269 }
270
271 inline value::value(const std::string& s)
272 : type_(string_type)
273 {
274   u_.string_ = new std::string(s);
275 }
276
277 inline value::value(const array& a)
278 : type_(array_type)
279 {
280   u_.array_ = new array(a);
281 }
282
283 inline value::value(const object& o)
284 : type_(object_type)
285 {
286   u_.object_ = new object(o);
287 }
288
289 inline value::value(const char* s)
290 : type_(string_type)
291 {
292   u_.string_ = new std::string(s);
293 }
294
295 inline value::value(const char* s, size_t len)
296 : type_(string_type)
297 {
298   u_.string_ = new std::string(s, len);
299 }
300
301 inline void value::clear()
302 {
303   switch(type_)
304   {
305 #define DEINIT(p) \
306   case p##type:   \
307     delete u_.p;  \
308     break
309     DEINIT(string_);
310     DEINIT(array_);
311     DEINIT(object_);
312 #undef DEINIT
313     default:
314       break;
315   }
316 }
317
318 inline value::~value()
319 {
320   clear();
321 }
322
323 inline value::value(const value& x)
324 : type_(x.type_)
325 {
326   switch(type_)
327   {
328 #define INIT(p, v) \
329   case p##type:    \
330     u_.p = v;      \
331     break
332     INIT(string_, new std::string(*x.u_.string_));
333     INIT(array_, new array(*x.u_.array_));
334     INIT(object_, new object(*x.u_.object_));
335 #undef INIT
336     default:
337       u_ = x.u_;
338       break;
339   }
340 }
341
342 inline value& value::operator=(const value& x)
343 {
344   if(this != &x)
345   {
346     value t(x);
347     swap(t);
348   }
349   return *this;
350 }
351
352 #if PICOJSON_USE_RVALUE_REFERENCE
353 inline value::value(value&& x) throw()
354 : type_(null_type)
355 {
356   swap(x);
357 }
358 inline value& value::operator=(value&& x) throw()
359 {
360   swap(x);
361   return *this;
362 }
363 #endif
364 inline void value::swap(value& x) throw()
365 {
366   std::swap(type_, x.type_);
367   std::swap(u_, x.u_);
368 }
369
370 #define IS(ctype, jtype)               \
371   template<>                           \
372   inline bool value::is<ctype>() const \
373   {                                    \
374     return type_ == jtype##_type;      \
375   }
376 IS(null, null)
377 IS(bool, boolean)
378 #ifdef PICOJSON_USE_INT64
379 IS(int64_t, int64)
380 #endif
381 IS(std::string, string)
382 IS(array, array)
383 IS(object, object)
384 #undef IS
385 template<>
386 inline bool value::is<double>() const
387 {
388   return type_ == number_type
389 #ifdef PICOJSON_USE_INT64
390          || type_ == int64_type
391 #endif
392     ;
393 }
394
395 #define GET(ctype, var)                                                                  \
396   template<>                                                                             \
397   inline const ctype& value::get<ctype>() const                                          \
398   {                                                                                      \
399     PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
400     return var;                                                                          \
401   }                                                                                      \
402   template<>                                                                             \
403   inline ctype& value::get<ctype>()                                                      \
404   {                                                                                      \
405     PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
406     return var;                                                                          \
407   }
408 GET(bool, u_.boolean_)
409 GET(std::string, *u_.string_)
410 GET(array, *u_.array_)
411 GET(object, *u_.object_)
412 #ifdef PICOJSON_USE_INT64
413 GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_))
414 GET(int64_t, u_.int64_)
415 #else
416 GET(double, u_.number_)
417 #endif
418 #undef GET
419
420 #define SET(ctype, jtype, setter)                  \
421   template<>                                       \
422   inline void value::set<ctype>(const ctype& _val) \
423   {                                                \
424     clear();                                       \
425     type_ = jtype##_type;                          \
426     setter                                         \
427   }
428 SET(bool, boolean, u_.boolean_ = _val;)
429 SET(std::string, string, u_.string_ = new std::string(_val);)
430 SET(array, array, u_.array_ = new array(_val);)
431 SET(object, object, u_.object_ = new object(_val);)
432 SET(double, number, u_.number_ = _val;)
433 #ifdef PICOJSON_USE_INT64
434 SET(int64_t, int64, u_.int64_ = _val;)
435 #endif
436 #undef SET
437
438 #if PICOJSON_USE_RVALUE_REFERENCE
439 #define MOVESET(ctype, jtype, setter)          \
440   template<>                                   \
441   inline void value::set<ctype>(ctype && _val) \
442   {                                            \
443     clear();                                   \
444     type_ = jtype##_type;                      \
445     setter                                     \
446   }
447 MOVESET(std::string, string, u_.string_ = new std::string(std::move(_val));)
448 MOVESET(array, array, u_.array_ = new array(std::move(_val));)
449 MOVESET(object, object, u_.object_ = new object(std::move(_val));)
450 #undef MOVESET
451 #endif
452
453 inline bool value::evaluate_as_boolean() const
454 {
455   switch(type_)
456   {
457     case null_type:
458       return false;
459     case boolean_type:
460       return u_.boolean_;
461     case number_type:
462       return u_.number_ != 0;
463 #ifdef PICOJSON_USE_INT64
464     case int64_type:
465       return u_.int64_ != 0;
466 #endif
467     case string_type:
468       return !u_.string_->empty();
469     default:
470       return true;
471   }
472 }
473
474 inline const value& value::get(size_t idx) const
475 {
476   static value s_null;
477   PICOJSON_ASSERT(is<array>());
478   return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
479 }
480
481 inline value& value::get(size_t idx)
482 {
483   static value s_null;
484   PICOJSON_ASSERT(is<array>());
485   return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
486 }
487
488 inline const value& value::get(const std::string& key) const
489 {
490   static value s_null;
491   PICOJSON_ASSERT(is<object>());
492   object::const_iterator i = u_.object_->find(key);
493   return i != u_.object_->end() ? i->second : s_null;
494 }
495
496 inline value& value::get(const std::string& key)
497 {
498   static value s_null;
499   PICOJSON_ASSERT(is<object>());
500   object::iterator i = u_.object_->find(key);
501   return i != u_.object_->end() ? i->second : s_null;
502 }
503
504 inline bool value::contains(size_t idx) const
505 {
506   PICOJSON_ASSERT(is<array>());
507   return idx < u_.array_->size();
508 }
509
510 inline bool value::contains(const std::string& key) const
511 {
512   PICOJSON_ASSERT(is<object>());
513   object::const_iterator i = u_.object_->find(key);
514   return i != u_.object_->end();
515 }
516
517 inline std::string value::to_str() const
518 {
519   switch(type_)
520   {
521     case null_type:
522       return "null";
523     case boolean_type:
524       return u_.boolean_ ? "true" : "false";
525 #ifdef PICOJSON_USE_INT64
526     case int64_type:
527     {
528       char buf[sizeof("-9223372036854775808")];
529       SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
530       return buf;
531     }
532 #endif
533     case number_type:
534     {
535       char   buf[256];
536       double tmp;
537       SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
538 #if PICOJSON_USE_LOCALE
539       char* decimal_point = localeconv()->decimal_point;
540       if(strcmp(decimal_point, ".") != 0)
541       {
542         size_t decimal_point_len = strlen(decimal_point);
543         for(char* p = buf; *p != '\0'; ++p)
544         {
545           if(strncmp(p, decimal_point, decimal_point_len) == 0)
546           {
547             return std::string(buf, p) + "." + (p + decimal_point_len);
548           }
549         }
550       }
551 #endif
552       return buf;
553     }
554     case string_type:
555       return *u_.string_;
556     case array_type:
557       return "array";
558     case object_type:
559       return "object";
560     default:
561       PICOJSON_ASSERT(0);
562 #ifdef _MSC_VER
563       __assume(0);
564 #endif
565   }
566   return std::string();
567 }
568
569 template<typename Iter>
570 void copy(const std::string& s, Iter oi)
571 {
572   std::copy(s.begin(), s.end(), oi);
573 }
574
575 template<typename Iter>
576 struct serialize_str_char
577 {
578   Iter oi;
579   void operator()(char c)
580   {
581     switch(c)
582     {
583 #define MAP(val, sym) \
584   case val:           \
585     copy(sym, oi);    \
586     break
587       MAP('"', "\\\"");
588       MAP('\\', "\\\\");
589       MAP('/', "\\/");
590       MAP('\b', "\\b");
591       MAP('\f', "\\f");
592       MAP('\n', "\\n");
593       MAP('\r', "\\r");
594       MAP('\t', "\\t");
595 #undef MAP
596       default:
597         if(static_cast<unsigned char>(c) < 0x20 || c == 0x7f)
598         {
599           char buf[7];
600           SNPRINTF(buf, sizeof(buf), "\\u%04x", c & 0xff);
601           copy(buf, buf + 6, oi);
602         }
603         else
604         {
605           *oi++ = c;
606         }
607         break;
608     }
609   }
610 };
611
612 template<typename Iter>
613 void serialize_str(const std::string& s, Iter oi)
614 {
615   *oi++                                 = '"';
616   serialize_str_char<Iter> process_char = {oi};
617   std::for_each(s.begin(), s.end(), process_char);
618   *oi++ = '"';
619 }
620
621 template<typename Iter>
622 void value::serialize(Iter oi, bool prettify) const
623 {
624   return _serialize(oi, prettify ? 0 : -1);
625 }
626
627 inline std::string value::serialize(bool prettify) const
628 {
629   return _serialize(prettify ? 0 : -1);
630 }
631
632 template<typename Iter>
633 void value::_indent(Iter oi, int indent)
634 {
635   *oi++ = '\n';
636   for(int i = 0; i < indent * INDENT_WIDTH; ++i)
637   {
638     *oi++ = ' ';
639   }
640 }
641
642 template<typename Iter>
643 void value::_serialize(Iter oi, int indent) const
644 {
645   switch(type_)
646   {
647     case string_type:
648       serialize_str(*u_.string_, oi);
649       break;
650     case array_type:
651     {
652       *oi++ = '[';
653       if(indent != -1)
654       {
655         ++indent;
656       }
657       for(array::const_iterator i = u_.array_->begin();
658           i != u_.array_->end();
659           ++i)
660       {
661         if(i != u_.array_->begin())
662         {
663           *oi++ = ',';
664         }
665         if(indent != -1)
666         {
667           _indent(oi, indent);
668         }
669         i->_serialize(oi, indent);
670       }
671       if(indent != -1)
672       {
673         --indent;
674         if(!u_.array_->empty())
675         {
676           _indent(oi, indent);
677         }
678       }
679       *oi++ = ']';
680       break;
681     }
682     case object_type:
683     {
684       *oi++ = '{';
685       if(indent != -1)
686       {
687         ++indent;
688       }
689       for(object::const_iterator i = u_.object_->begin();
690           i != u_.object_->end();
691           ++i)
692       {
693         if(i != u_.object_->begin())
694         {
695           *oi++ = ',';
696         }
697         if(indent != -1)
698         {
699           _indent(oi, indent);
700         }
701         serialize_str(i->first, oi);
702         *oi++ = ':';
703         if(indent != -1)
704         {
705           *oi++ = ' ';
706         }
707         i->second._serialize(oi, indent);
708       }
709       if(indent != -1)
710       {
711         --indent;
712         if(!u_.object_->empty())
713         {
714           _indent(oi, indent);
715         }
716       }
717       *oi++ = '}';
718       break;
719     }
720     default:
721       copy(to_str(), oi);
722       break;
723   }
724   if(indent == 0)
725   {
726     *oi++ = '\n';
727   }
728 }
729
730 inline std::string value::_serialize(int indent) const
731 {
732   std::string s;
733   _serialize(std::back_inserter(s), indent);
734   return s;
735 }
736
737 template<typename Iter>
738 class input
739 {
740 protected:
741   Iter cur_, end_;
742   bool consumed_;
743   int  line_;
744
745 public:
746   input(const Iter& first, const Iter& last)
747   : cur_(first),
748     end_(last),
749     consumed_(false),
750     line_(1)
751   {
752   }
753   int getc()
754   {
755     if(consumed_)
756     {
757       if(*cur_ == '\n')
758       {
759         ++line_;
760       }
761       ++cur_;
762     }
763     if(cur_ == end_)
764     {
765       consumed_ = false;
766       return -1;
767     }
768     consumed_ = true;
769     return *cur_ & 0xff;
770   }
771   void ungetc()
772   {
773     consumed_ = false;
774   }
775   Iter cur() const
776   {
777     if(consumed_)
778     {
779       input<Iter>* self = const_cast<input<Iter>*>(this);
780       self->consumed_   = false;
781       ++self->cur_;
782     }
783     return cur_;
784   }
785   int line() const
786   {
787     return line_;
788   }
789   void skip_ws()
790   {
791     while(1)
792     {
793       int ch = getc();
794       if(!(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'))
795       {
796         ungetc();
797         break;
798       }
799     }
800   }
801   bool expect(int expect)
802   {
803     skip_ws();
804     if(getc() != expect)
805     {
806       ungetc();
807       return false;
808     }
809     return true;
810   }
811   bool match(const std::string& pattern)
812   {
813     for(std::string::const_iterator pi(pattern.begin());
814         pi != pattern.end();
815         ++pi)
816     {
817       if(getc() != *pi)
818       {
819         ungetc();
820         return false;
821       }
822     }
823     return true;
824   }
825 };
826
827 template<typename Iter>
828 inline int _parse_quadhex(input<Iter>& in)
829 {
830   int uni_ch = 0, hex;
831   for(int i = 0; i < 4; i++)
832   {
833     if((hex = in.getc()) == -1)
834     {
835       return -1;
836     }
837     if('0' <= hex && hex <= '9')
838     {
839       hex -= '0';
840     }
841     else if('A' <= hex && hex <= 'F')
842     {
843       hex -= 'A' - 0xa;
844     }
845     else if('a' <= hex && hex <= 'f')
846     {
847       hex -= 'a' - 0xa;
848     }
849     else
850     {
851       in.ungetc();
852       return -1;
853     }
854     uni_ch = uni_ch * 16 + hex;
855   }
856   return uni_ch;
857 }
858
859 template<typename String, typename Iter>
860 inline bool _parse_codepoint(String& out, input<Iter>& in)
861 {
862   int uni_ch;
863   if((uni_ch = _parse_quadhex(in)) == -1)
864   {
865     return false;
866   }
867   if(0xd800 <= uni_ch && uni_ch <= 0xdfff)
868   {
869     if(0xdc00 <= uni_ch)
870     {
871       // a second 16-bit of a surrogate pair appeared
872       return false;
873     }
874     // first 16-bit of surrogate pair, get the next one
875     if(in.getc() != '\\' || in.getc() != 'u')
876     {
877       in.ungetc();
878       return false;
879     }
880     int second = _parse_quadhex(in);
881     if(!(0xdc00 <= second && second <= 0xdfff))
882     {
883       return false;
884     }
885     uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
886     uni_ch += 0x10000;
887   }
888   if(uni_ch < 0x80)
889   {
890     out.push_back(uni_ch);
891   }
892   else
893   {
894     if(uni_ch < 0x800)
895     {
896       out.push_back(0xc0 | (uni_ch >> 6));
897     }
898     else
899     {
900       if(uni_ch < 0x10000)
901       {
902         out.push_back(0xe0 | (uni_ch >> 12));
903       }
904       else
905       {
906         out.push_back(0xf0 | (uni_ch >> 18));
907         out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
908       }
909       out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
910     }
911     out.push_back(0x80 | (uni_ch & 0x3f));
912   }
913   return true;
914 }
915
916 template<typename String, typename Iter>
917 inline bool _parse_string(String& out, input<Iter>& in)
918 {
919   while(1)
920   {
921     int ch = in.getc();
922     if(ch < ' ')
923     {
924       in.ungetc();
925       return false;
926     }
927     else if(ch == '"')
928     {
929       return true;
930     }
931     else if(ch == '\\')
932     {
933       if((ch = in.getc()) == -1)
934       {
935         return false;
936       }
937       switch(ch)
938       {
939 #define MAP(sym, val)   \
940   case sym:             \
941     out.push_back(val); \
942     break
943         MAP('"', '\"');
944         MAP('\\', '\\');
945         MAP('/', '/');
946         MAP('b', '\b');
947         MAP('f', '\f');
948         MAP('n', '\n');
949         MAP('r', '\r');
950         MAP('t', '\t');
951 #undef MAP
952         case 'u':
953           if(!_parse_codepoint(out, in))
954           {
955             return false;
956           }
957           break;
958         default:
959           return false;
960       }
961     }
962     else
963     {
964       out.push_back(ch);
965     }
966   }
967   return false;
968 }
969
970 template<typename Context, typename Iter>
971 inline bool _parse_array(Context& ctx, input<Iter>& in)
972 {
973   if(!ctx.parse_array_start())
974   {
975     return false;
976   }
977   size_t idx = 0;
978   if(in.expect(']'))
979   {
980     return ctx.parse_array_stop(idx);
981   }
982   do
983   {
984     if(!ctx.parse_array_item(in, idx))
985     {
986       return false;
987     }
988     idx++;
989   } while(in.expect(','));
990   return in.expect(']') && ctx.parse_array_stop(idx);
991 }
992
993 template<typename Context, typename Iter>
994 inline bool _parse_object(Context& ctx, input<Iter>& in)
995 {
996   if(!ctx.parse_object_start())
997   {
998     return false;
999   }
1000   if(in.expect('}'))
1001   {
1002     return true;
1003   }
1004   do
1005   {
1006     std::string key;
1007     if(!in.expect('"') || !_parse_string(key, in) || !in.expect(':'))
1008     {
1009       return false;
1010     }
1011     if(!ctx.parse_object_item(in, key))
1012     {
1013       return false;
1014     }
1015   } while(in.expect(','));
1016   return in.expect('}');
1017 }
1018
1019 template<typename Iter>
1020 inline std::string _parse_number(input<Iter>& in)
1021 {
1022   std::string num_str;
1023   while(1)
1024   {
1025     int ch = in.getc();
1026     if(('0' <= ch && ch <= '9') || ch == '+' || ch == '-' || ch == 'e' || ch == 'E')
1027     {
1028       num_str.push_back(ch);
1029     }
1030     else if(ch == '.')
1031     {
1032 #if PICOJSON_USE_LOCALE
1033       num_str += localeconv()->decimal_point;
1034 #else
1035       num_str.push_back('.');
1036 #endif
1037     }
1038     else
1039     {
1040       in.ungetc();
1041       break;
1042     }
1043   }
1044   return num_str;
1045 }
1046
1047 template<typename Context, typename Iter>
1048 inline bool _parse(Context& ctx, input<Iter>& in)
1049 {
1050   in.skip_ws();
1051   int ch = in.getc();
1052   switch(ch)
1053   {
1054 #define IS(ch, text, op)     \
1055   case ch:                   \
1056     if(in.match(text) && op) \
1057     {                        \
1058       return true;           \
1059     }                        \
1060     else                     \
1061     {                        \
1062       return false;          \
1063     }
1064     IS('n', "ull", ctx.set_null());
1065     IS('f', "alse", ctx.set_bool(false));
1066     IS('t', "rue", ctx.set_bool(true));
1067 #undef IS
1068     case '"':
1069       return ctx.parse_string(in);
1070     case '[':
1071       return _parse_array(ctx, in);
1072     case '{':
1073       return _parse_object(ctx, in);
1074     default:
1075       if(('0' <= ch && ch <= '9') || ch == '-')
1076       {
1077         double f;
1078         char*  endp;
1079         in.ungetc();
1080         std::string num_str = _parse_number(in);
1081         if(num_str.empty())
1082         {
1083           return false;
1084         }
1085 #ifdef PICOJSON_USE_INT64
1086         {
1087           errno         = 0;
1088           intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
1089           if(errno == 0 && std::numeric_limits<int64_t>::min() <= ival && ival <= std::numeric_limits<int64_t>::max() && endp == num_str.c_str() + num_str.size())
1090           {
1091             ctx.set_int64(ival);
1092             return true;
1093           }
1094         }
1095 #endif
1096         f = strtod(num_str.c_str(), &endp);
1097         if(endp == num_str.c_str() + num_str.size())
1098         {
1099           ctx.set_number(f);
1100           return true;
1101         }
1102         return false;
1103       }
1104       break;
1105   }
1106   in.ungetc();
1107   return false;
1108 }
1109
1110 class deny_parse_context
1111 {
1112 public:
1113   bool set_null()
1114   {
1115     return false;
1116   }
1117   bool set_bool(bool)
1118   {
1119     return false;
1120   }
1121 #ifdef PICOJSON_USE_INT64
1122   bool set_int64(int64_t)
1123   {
1124     return false;
1125   }
1126 #endif
1127   bool set_number(double)
1128   {
1129     return false;
1130   }
1131   template<typename Iter>
1132   bool parse_string(input<Iter>&)
1133   {
1134     return false;
1135   }
1136   bool parse_array_start()
1137   {
1138     return false;
1139   }
1140   template<typename Iter>
1141   bool parse_array_item(input<Iter>&, size_t)
1142   {
1143     return false;
1144   }
1145   bool parse_array_stop(size_t)
1146   {
1147     return false;
1148   }
1149   bool parse_object_start()
1150   {
1151     return false;
1152   }
1153   template<typename Iter>
1154   bool parse_object_item(input<Iter>&, const std::string&)
1155   {
1156     return false;
1157   }
1158 };
1159
1160 class default_parse_context
1161 {
1162 protected:
1163   value* out_;
1164
1165 public:
1166   default_parse_context(value* out)
1167   : out_(out)
1168   {
1169   }
1170   bool set_null()
1171   {
1172     *out_ = value();
1173     return true;
1174   }
1175   bool set_bool(bool b)
1176   {
1177     *out_ = value(b);
1178     return true;
1179   }
1180 #ifdef PICOJSON_USE_INT64
1181   bool set_int64(int64_t i)
1182   {
1183     *out_ = value(i);
1184     return true;
1185   }
1186 #endif
1187   bool set_number(double f)
1188   {
1189     *out_ = value(f);
1190     return true;
1191   }
1192   template<typename Iter>
1193   bool parse_string(input<Iter>& in)
1194   {
1195     *out_ = value(string_type, false);
1196     return _parse_string(out_->get<std::string>(), in);
1197   }
1198   bool parse_array_start()
1199   {
1200     *out_ = value(array_type, false);
1201     return true;
1202   }
1203   template<typename Iter>
1204   bool parse_array_item(input<Iter>& in, size_t)
1205   {
1206     array& a = out_->get<array>();
1207     a.push_back(value());
1208     default_parse_context ctx(&a.back());
1209     return _parse(ctx, in);
1210   }
1211   bool parse_array_stop(size_t)
1212   {
1213     return true;
1214   }
1215   bool parse_object_start()
1216   {
1217     *out_ = value(object_type, false);
1218     return true;
1219   }
1220   template<typename Iter>
1221   bool parse_object_item(input<Iter>& in, const std::string& key)
1222   {
1223     object&               o = out_->get<object>();
1224     default_parse_context ctx(&o[key]);
1225     return _parse(ctx, in);
1226   }
1227
1228 private:
1229   default_parse_context(const default_parse_context&);
1230   default_parse_context& operator=(const default_parse_context&);
1231 };
1232
1233 class null_parse_context
1234 {
1235 public:
1236   struct dummy_str
1237   {
1238     void push_back(int)
1239     {
1240     }
1241   };
1242
1243 public:
1244   null_parse_context()
1245   {
1246   }
1247   bool set_null()
1248   {
1249     return true;
1250   }
1251   bool set_bool(bool)
1252   {
1253     return true;
1254   }
1255 #ifdef PICOJSON_USE_INT64
1256   bool set_int64(int64_t)
1257   {
1258     return true;
1259   }
1260 #endif
1261   bool set_number(double)
1262   {
1263     return true;
1264   }
1265   template<typename Iter>
1266   bool parse_string(input<Iter>& in)
1267   {
1268     dummy_str s;
1269     return _parse_string(s, in);
1270   }
1271   bool parse_array_start()
1272   {
1273     return true;
1274   }
1275   template<typename Iter>
1276   bool parse_array_item(input<Iter>& in, size_t)
1277   {
1278     return _parse(*this, in);
1279   }
1280   bool parse_array_stop(size_t)
1281   {
1282     return true;
1283   }
1284   bool parse_object_start()
1285   {
1286     return true;
1287   }
1288   template<typename Iter>
1289   bool parse_object_item(input<Iter>& in, const std::string&)
1290   {
1291     return _parse(*this, in);
1292   }
1293
1294 private:
1295   null_parse_context(const null_parse_context&);
1296   null_parse_context& operator=(const null_parse_context&);
1297 };
1298
1299 // obsolete, use the version below
1300 template<typename Iter>
1301 inline std::string parse(value& out, Iter& pos, const Iter& last)
1302 {
1303   std::string err;
1304   pos = parse(out, pos, last, &err);
1305   return err;
1306 }
1307
1308 template<typename Context, typename Iter>
1309 inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err)
1310 {
1311   input<Iter> in(first, last);
1312   if(!_parse(ctx, in) && err != NULL)
1313   {
1314     char buf[64];
1315     SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
1316     *err = buf;
1317     while(1)
1318     {
1319       int ch = in.getc();
1320       if(ch == -1 || ch == '\n')
1321       {
1322         break;
1323       }
1324       else if(ch >= ' ')
1325       {
1326         err->push_back(ch);
1327       }
1328     }
1329   }
1330   return in.cur();
1331 }
1332
1333 template<typename Iter>
1334 inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err)
1335 {
1336   default_parse_context ctx(&out);
1337   return _parse(ctx, first, last, err);
1338 }
1339
1340 inline std::string parse(value& out, const std::string& s)
1341 {
1342   std::string err;
1343   parse(out, s.begin(), s.end(), &err);
1344   return err;
1345 }
1346
1347 inline std::string parse(value& out, std::istream& is)
1348 {
1349   std::string err;
1350   parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1351   return err;
1352 }
1353
1354 template<typename T>
1355 struct last_error_t
1356 {
1357   static std::string s;
1358 };
1359 template<typename T>
1360 std::string last_error_t<T>::s;
1361
1362 inline void set_last_error(const std::string& s)
1363 {
1364   last_error_t<bool>::s = s;
1365 }
1366
1367 inline const std::string& get_last_error()
1368 {
1369   return last_error_t<bool>::s;
1370 }
1371
1372 inline bool operator==(const value& x, const value& y)
1373 {
1374   if(x.is<null>())
1375     return y.is<null>();
1376 #define PICOJSON_CMP(type) \
1377   if(x.is<type>())         \
1378   return y.is<type>() && x.get<type>() == y.get<type>()
1379   PICOJSON_CMP(bool);
1380   PICOJSON_CMP(double);
1381   PICOJSON_CMP(std::string);
1382   PICOJSON_CMP(array);
1383   PICOJSON_CMP(object);
1384 #undef PICOJSON_CMP
1385   PICOJSON_ASSERT(0);
1386 #ifdef _MSC_VER
1387   __assume(0);
1388 #endif
1389   return false;
1390 }
1391
1392 inline bool operator!=(const value& x, const value& y)
1393 {
1394   return !(x == y);
1395 }
1396 } // namespace picojson
1397
1398 #if !PICOJSON_USE_RVALUE_REFERENCE
1399 namespace std
1400 {
1401 template<>
1402 inline void swap(picojson::value& x, picojson::value& y)
1403 {
1404   x.swap(y);
1405 }
1406 } // namespace std
1407 #endif
1408
1409 inline std::istream& operator>>(std::istream& is, picojson::value& x)
1410 {
1411   picojson::set_last_error(std::string());
1412   std::string err = picojson::parse(x, is);
1413   if(!err.empty())
1414   {
1415     picojson::set_last_error(err);
1416     is.setstate(std::ios::failbit);
1417   }
1418   return is;
1419 }
1420
1421 inline std::ostream& operator<<(std::ostream& os, const picojson::value& x)
1422 {
1423   x.serialize(std::ostream_iterator<char>(os));
1424   return os;
1425 }
1426 #ifdef _MSC_VER
1427 #pragma warning(pop)
1428 #endif
1429
1430 #endif