]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_json.cpp
Initial vogl checkin
[vogl] / src / voglcore / vogl_json.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_json.h
28 #include "vogl_core.h"
29 #include "vogl_json.h"
30 #include "vogl_console.h"
31 #include "vogl_growable_array.h"
32 #include "vogl_hash_map.h"
33 #include "vogl_map.h"
34
35 namespace vogl
36 {
37
38     json_node_object_pool *g_pJSON_node_pool;
39     json_value g_null_json_value;
40
41     static const char *g_to_hex = "0123456789ABCDEF";
42
43     const uint cMaxValidDepth = 511;
44
45     const uint cJSONTabSize = 3;
46
47     void json_node_pool_init()
48     {
49         if (!g_pJSON_node_pool)
50             g_pJSON_node_pool = vogl_new(json_node_object_pool, 256, cObjectPoolGrowExponential);
51     }
52
53     // class json_deserialize_buf_ptr
54
55     class json_deserialize_buf_ptr
56     {
57     public:
58         inline json_deserialize_buf_ptr(const char *p, size_t len)
59         {
60             init(p, len);
61         }
62
63         inline void init(const char *p, size_t len)
64         {
65             m_pPtr = p;
66             m_pEnd = p + len;
67             m_cur_line = 1;
68         }
69
70         inline const char *get_end() const
71         {
72             return m_pEnd;
73         }
74         inline bool at_end() const
75         {
76             return m_pPtr >= m_pEnd;
77         }
78
79         inline size_t get_num_remaining() const
80         {
81             return m_pEnd - m_pPtr;
82         }
83
84         inline char get_char() const
85         {
86             char c = (m_pPtr < m_pEnd) ? *m_pPtr : 0;
87             if (c == '\r')
88                 c = '\n';
89             return c;
90         }
91
92         inline uint get_cur_line() const
93         {
94             return m_cur_line;
95         }
96
97         inline char operator*() const
98         {
99             return get_char();
100         }
101         inline operator const char *() const
102         {
103             return m_pPtr;
104         }
105
106         inline json_deserialize_buf_ptr &operator++()
107         {
108             get_and_advance();
109             return *this;
110         }
111
112         inline json_deserialize_buf_ptr operator++(int)
113         {
114             json_deserialize_buf_ptr cur(*this);
115             get_and_advance();
116             return cur;
117         }
118
119         inline char get_and_advance()
120         {
121             char c = (m_pPtr < m_pEnd) ? *m_pPtr++ : 0;
122             if (c <= '\r')
123             {
124                 if ((c == '\r') && (m_pPtr < m_pEnd) && (*m_pPtr == '\n'))
125                     c = *m_pPtr++;
126                 if ((c == '\n') || (c == '\r'))
127                 {
128                     c = '\n';
129                     m_cur_line++;
130                 }
131             }
132             return c;
133         }
134
135         inline void advance()
136         {
137             get_and_advance();
138         }
139
140         json_deserialize_buf_ptr &skip_whitespace();
141
142         inline bool compare_string(const char *pStr, size_t n) const
143         {
144             return ((m_pEnd - m_pPtr) < (int)n) ? false : !strncmp(m_pPtr, pStr, n);
145         }
146
147         inline json_deserialize_buf_ptr &advance_in_line(uint n)
148         {
149             m_pPtr = VOGL_MIN(m_pEnd, m_pPtr + n);
150             return *this;
151         }
152         inline json_deserialize_buf_ptr &advance_in_line_no_end_check(uint n)
153         {
154             m_pPtr += n;
155             VOGL_ASSERT(m_pPtr <= m_pEnd);
156             return *this;
157         }
158
159     private:
160         const char *m_pPtr;
161         const char *m_pEnd;
162         uint m_cur_line;
163     };
164
165     json_deserialize_buf_ptr &json_deserialize_buf_ptr::skip_whitespace()
166     {
167         while (m_pPtr < m_pEnd)
168         {
169             char c = *m_pPtr;
170             if ((c == ' ') || (c == '\t'))
171             {
172                 ++m_pPtr;
173                 continue;
174             }
175
176             if ((c == '/') && (((m_pPtr + 1) < m_pEnd) && (m_pPtr[1] == '/')))
177             {
178                 m_pPtr += 2;
179                 while ((!at_end()) && (get_char() != '\n'))
180                     advance();
181                 continue;
182             }
183             else if (c > ' ')
184                 break;
185             else if (c == '\r')
186             {
187                 if (((m_pPtr + 1) < m_pEnd) && (m_pPtr[1] == '\n'))
188                     ++m_pPtr;
189                 m_cur_line++;
190             }
191             else if (c == '\n')
192                 m_cur_line++;
193
194             ++m_pPtr;
195         }
196         return *this;
197     }
198
199     // class json_growable_char_buf
200
201     class json_growable_char_buf
202     {
203         VOGL_NO_COPY_OR_ASSIGNMENT_OP(json_growable_char_buf);
204
205     public:
206         inline json_growable_char_buf(vogl::vector<char> &buf)
207             : m_buf(buf)
208         {
209         }
210
211         inline uint size() const
212         {
213             return m_buf.size();
214         }
215
216         inline const vogl::vector<char> &get() const
217         {
218             return m_buf;
219         }
220         inline vogl::vector<char> &get()
221         {
222             return m_buf;
223         }
224
225         void puts(const char *pStr);
226         void printf(const char *pFmt, ...);
227         void print_escaped(const char *pStr);
228         void print_tabs(uint n);
229         inline void print_char(char c)
230         {
231             m_buf.push_back(c);
232         }
233
234     private:
235         vogl::vector<char> &m_buf;
236     };
237
238     void json_growable_char_buf::puts(const char *pStr)
239     {
240         size_t l = strlen(pStr);
241         if (l > cUINT32_MAX)
242             return;
243
244         char *p = m_buf.try_enlarge(static_cast<uint>(l));
245         if (p)
246             memcpy(p, pStr, l);
247     }
248
249     void json_growable_char_buf::printf(const char *pFmt, ...)
250     {
251         char str[512];
252
253         va_list args;
254         va_start(args, pFmt);
255 #ifdef _MSC_VER
256         int l = _vsnprintf_s(str, sizeof(str), pFmt, args);
257 #else
258         int l = vsnprintf(str, sizeof(str), pFmt, args);
259         str[sizeof(str) - 1] = '\0';
260 #endif
261         va_end(args);
262
263         char *p = m_buf.try_enlarge(l);
264         if (p)
265             memcpy(p, str, l);
266     }
267
268     void json_growable_char_buf::print_tabs(uint n)
269     {
270 #if 0
271         // Apparently tabs are not valid JSON.
272         char *p = m_buf.enlarge(n);
273         if (p)
274                 memset(p, '\t', n);
275 #else
276         char *p = m_buf.enlarge(n * cJSONTabSize);
277         if (p)
278             memset(p, ' ', n * cJSONTabSize);
279 #endif
280     }
281
282     void json_growable_char_buf::print_escaped(const char *pStr)
283     {
284         m_buf.push_back('\"');
285
286         while (*pStr)
287         {
288             char c = *pStr++;
289             if ((static_cast<uint8>(c) >= 32U) && (c != '\"') && (c != '\\'))
290                 m_buf.push_back(c);
291             else
292             {
293                 m_buf.push_back('\\');
294                 switch (c)
295                 {
296                     case '\b':
297                         m_buf.push_back('b');
298                         break;
299                     case '\r':
300                         m_buf.push_back('r');
301                         break;
302                     case '\t':
303                         m_buf.push_back('t');
304                         break;
305                     case '\f':
306                         m_buf.push_back('f');
307                         break;
308                     case '\n':
309                         m_buf.push_back('n');
310                         break;
311                     case '\\':
312                         m_buf.push_back('\\');
313                         break;
314                     case '\"':
315                         m_buf.push_back('\"');
316                         break;
317                     default:
318                         m_buf.push_back('u');
319                         m_buf.push_back('0');
320                         m_buf.push_back('0');
321                         m_buf.push_back(g_to_hex[static_cast<uint8>(c) >> 4]);
322                         m_buf.push_back(g_to_hex[c & 0xF]);
323                         break;
324                 }
325             }
326         }
327
328         m_buf.push_back('\"');
329     }
330
331     void json_error_info_t::set_error(uint line, const char *pMsg, ...)
332     {
333         m_error_line = line;
334
335         va_list args;
336         va_start(args, pMsg);
337         m_error_msg.format_args(pMsg, args);
338         va_end(args);
339     }
340
341     // class json_value
342
343     json_value::json_value(const json_value &other)
344         : m_type(other.m_type),
345           m_line(0)
346     {
347         if (other.m_type == cJSONValueTypeString)
348             m_data.m_pStr = vogl_strdup(other.m_data.m_pStr);
349         else if (other.m_type == cJSONValueTypeNode)
350             m_data.m_pNode = get_json_node_pool()->alloc(*other.get_node_ptr());
351         else
352             memcpy(&m_data, &other.m_data, sizeof(m_data));
353     }
354
355     void json_value::set_value(uint64_t nVal)
356     {
357         free_data();
358
359         if (nVal > static_cast<uint64_t>(cINT64_MAX))
360         {
361             // Encode as a hex string because otherwise some json parsers have a fit, and the UJB format doesn't directly support uint64_t.
362             char buf[32];
363             vogl_sprintf_s(buf, sizeof(buf), "0x%" PRIX64, nVal);
364             set_value(buf);
365         }
366         else
367         {
368             set_value(static_cast<int64_t>(nVal));
369         }
370     }
371
372     json_value &json_value::operator=(const json_value &rhs)
373     {
374         free_data();
375
376         m_type = rhs.m_type;
377
378         if (m_type == cJSONValueTypeString)
379             m_data.m_pStr = vogl_strdup(rhs.m_data.m_pStr);
380         else if (m_type == cJSONValueTypeNode)
381             m_data.m_pNode = get_json_node_pool()->alloc(*rhs.get_node_ptr());
382         else
383             memcpy(&m_data, &rhs.m_data, sizeof(m_data));
384
385         m_line = rhs.m_line;
386
387         return *this;
388     }
389
390     bool json_value::convert_to_bool(bool &val, bool def) const
391     {
392         switch (m_type)
393         {
394             case cJSONValueTypeBool:
395             case cJSONValueTypeInt:
396             {
397                 val = (m_data.m_nVal != 0);
398                 return true;
399             }
400             case cJSONValueTypeDouble:
401             {
402                 val = (m_data.m_flVal != 0);
403                 return true;
404             }
405             case cJSONValueTypeString:
406             {
407                 if (!vogl_stricmp(m_data.m_pStr, "false"))
408                 {
409                     val = false;
410                     return true;
411                 }
412                 else if (!vogl_stricmp(m_data.m_pStr, "true"))
413                 {
414                     val = true;
415                     return true;
416                 }
417
418                 double flVal = 0.0f;
419                 const char *pStr = m_data.m_pStr;
420                 if (!string_ptr_to_double(pStr, flVal))
421                 {
422                     val = def;
423                     return false;
424                 }
425                 val = (flVal != 0);
426                 return true;
427             }
428             default:
429                 break;
430         }
431         val = def;
432         return false;
433     }
434
435     bool json_value::convert_to_int32(int32 &val, int32 def) const
436     {
437         val = def;
438         int64_t val64;
439         if (!convert_to_int64(val64, def))
440             return false;
441         if ((val64 < cINT32_MIN) || (val64 > cINT32_MAX))
442             return false;
443         val = static_cast<int32>(val64);
444         return true;
445     }
446
447     bool json_value::convert_to_int64(int64_t &val, int64_t def) const
448     {
449         switch (m_type)
450         {
451             case cJSONValueTypeBool:
452             case cJSONValueTypeInt:
453             {
454                 val = m_data.m_nVal;
455                 return true;
456             }
457             case cJSONValueTypeDouble:
458             {
459                 val = static_cast<int64_t>(m_data.m_flVal);
460                 return true;
461             }
462             case cJSONValueTypeString:
463             {
464                 if (!vogl_stricmp(m_data.m_pStr, "false"))
465                 {
466                     val = 0;
467                     return true;
468                 }
469                 else if (!vogl_stricmp(m_data.m_pStr, "true"))
470                 {
471                     val = 1;
472                     return true;
473                 }
474
475                 const char *pStr = m_data.m_pStr;
476
477                 // string_to_ptr_int64() will handle hex or decimal conversions
478                 if (!string_ptr_to_int64(pStr, val))
479                 {
480                     val = def;
481                     return false;
482                 }
483                 return true;
484             }
485             default:
486                 break;
487         }
488         val = def;
489         return false;
490     }
491
492     bool json_value::convert_to_uint64(uint64_t &val, uint64_t def) const
493     {
494         switch (m_type)
495         {
496             case cJSONValueTypeBool:
497             {
498                 val = m_data.m_nVal;
499                 break;
500             }
501             case cJSONValueTypeInt:
502             {
503                 if (m_data.m_nVal < 0)
504                     break;
505
506                 val = m_data.m_nVal;
507                 return true;
508             }
509             case cJSONValueTypeDouble:
510             {
511                 if (m_data.m_flVal < 0)
512                     break;
513
514                 val = static_cast<uint64_t>(m_data.m_flVal);
515                 return true;
516             }
517             case cJSONValueTypeString:
518             {
519                 if (!vogl_stricmp(m_data.m_pStr, "false"))
520                 {
521                     val = 0;
522                     return true;
523                 }
524                 else if (!vogl_stricmp(m_data.m_pStr, "true"))
525                 {
526                     val = 1;
527                     return true;
528                 }
529
530                 const char *pStr = m_data.m_pStr;
531
532                 // string_to_uint64() will handle hex or decimal conversions
533                 if (!string_ptr_to_uint64(pStr, val))
534                     break;
535
536                 return true;
537             }
538             default:
539                 break;
540         }
541         val = def;
542         return false;
543     }
544
545     bool json_value::convert_to_float(float &val, float def) const
546     {
547         switch (m_type)
548         {
549             case cJSONValueTypeBool:
550             case cJSONValueTypeInt:
551             {
552                 val = static_cast<float>(m_data.m_nVal);
553                 return true;
554             }
555             case cJSONValueTypeDouble:
556             {
557                 val = static_cast<float>(m_data.m_flVal);
558                 return true;
559             }
560             case cJSONValueTypeString:
561             {
562                 if (!vogl_stricmp(m_data.m_pStr, "false"))
563                 {
564                     val = 0;
565                     return true;
566                 }
567                 else if (!vogl_stricmp(m_data.m_pStr, "true"))
568                 {
569                     val = 1;
570                     return true;
571                 }
572
573                 const char *pStr = m_data.m_pStr;
574                 if (!string_ptr_to_float(pStr, val))
575                     break;
576
577                 return true;
578             }
579             default:
580                 break;
581         }
582         val = def;
583         return false;
584     }
585
586     bool json_value::convert_to_double(double &val, double def) const
587     {
588         switch (m_type)
589         {
590             case cJSONValueTypeBool:
591             case cJSONValueTypeInt:
592             {
593                 val = static_cast<double>(m_data.m_nVal);
594                 return true;
595             }
596             case cJSONValueTypeDouble:
597             {
598                 val = m_data.m_flVal;
599                 return true;
600             }
601             case cJSONValueTypeString:
602             {
603                 if (!vogl_stricmp(m_data.m_pStr, "false"))
604                 {
605                     val = 0;
606                     return true;
607                 }
608                 else if (!vogl_stricmp(m_data.m_pStr, "true"))
609                 {
610                     val = 1;
611                     return true;
612                 }
613
614                 const char *pStr = m_data.m_pStr;
615                 if (!string_ptr_to_double(pStr, val))
616                 {
617                     val = def;
618                     return false;
619                 }
620                 return true;
621             }
622             default:
623                 break;
624         }
625         val = def;
626         return false;
627     }
628
629     bool json_value::convert_to_string(dynamic_string &val, const char *pDef) const
630     {
631         switch (m_type)
632         {
633             case cJSONValueTypeNull:
634             {
635                 val.set("null");
636                 return true;
637             }
638             case cJSONValueTypeBool:
639             {
640                 val.set(!m_data.m_nVal ? "false" : "true");
641                 return true;
642             }
643             case cJSONValueTypeInt:
644             {
645                 val.format("%" PRIi64, m_data.m_nVal);
646                 return true;
647             }
648             case cJSONValueTypeDouble:
649             {
650                 val.format("%1.18f", m_data.m_flVal);
651
652                 if ((!val.contains('E')) && (!val.contains('e')))
653                 {
654                     // Remove trailing 0's, except the first after the decimal point which is required for valid JSON.
655                     int dot_ofs = val.find_right('.');
656                     if (dot_ofs >= 0)
657                     {
658                         int len = val.get_len();
659
660                         int i;
661                         for (i = dot_ofs + 1; i < len; i++)
662                         {
663                             char c = val[i];
664                             if (!vogl_isdigit(c))
665                                 break;
666                         }
667                         if (i == len)
668                         {
669                             int cur_ofs = len - 1;
670                             while ((val[cur_ofs] == '0') && (cur_ofs > (dot_ofs + 1)))
671                             {
672                                 val.set_len(cur_ofs);
673                                 cur_ofs--;
674                             }
675                         }
676                     }
677                 }
678                 return true;
679             }
680             case cJSONValueTypeString:
681             {
682                 val = m_data.m_pStr;
683                 return true;
684             }
685             default:
686                 break;
687         }
688         val.set(pDef);
689         return false;
690     }
691
692     static int scan_string_list(const char *p, const char **pList, int def)
693     {
694         int index = 0;
695         for (;;)
696         {
697             const char *s = pList[index];
698             if (!s)
699                 break;
700             if (vogl_stricmp(p, s) == 0)
701                 return index;
702             index++;
703         }
704         return def;
705     }
706
707     bool json_value::get_enum(const char **pStringList, int &val, int def) const
708     {
709         val = def;
710
711         dynamic_string tmp_str;
712         const char *pStr;
713
714         if (get_type() == cJSONValueTypeString)
715             pStr = m_data.m_pStr;
716         else
717         {
718             if (!convert_to_string(tmp_str, ""))
719                 return false;
720             pStr = tmp_str.get_ptr();
721         }
722
723         int val_index = scan_string_list(pStr, pStringList, -1);
724         if (val_index < 0)
725             return false;
726         val = val_index;
727         return true;
728     }
729
730     bool json_value::get_numeric(int8 &val, int8 def) const
731     {
732         int64_t val64;
733         if (!get_numeric(val64))
734         {
735             val = def;
736             return false;
737         }
738         if ((val64 < static_cast<int64_t>(cINT8_MIN)) || (val64 > static_cast<int64_t>(cINT8_MAX)))
739         {
740             val = def;
741             return false;
742         }
743         val = static_cast<int8>(val64);
744         return true;
745     }
746
747     bool json_value::get_numeric(int16 &val, int16 def) const
748     {
749         int64_t val64;
750         if (!get_numeric(val64))
751         {
752             val = def;
753             return false;
754         }
755         if ((val64 < static_cast<int64_t>(cINT16_MIN)) || (val64 > static_cast<int64_t>(cINT16_MAX)))
756         {
757             val = def;
758             return false;
759         }
760         val = static_cast<int16>(val64);
761         return true;
762     }
763
764     bool json_value::get_numeric(uint8 &val, uint8 def) const
765     {
766         uint64_t val64;
767         if (!get_numeric(val64))
768         {
769             val = def;
770             return false;
771         }
772         if (val64 > static_cast<int64_t>(cUINT8_MAX))
773         {
774             val = def;
775             return false;
776         }
777         val = static_cast<uint8>(val64);
778         return true;
779     }
780
781     bool json_value::get_numeric(uint16 &val, uint16 def) const
782     {
783         uint64_t val64;
784         if (!get_numeric(val64))
785         {
786             val = def;
787             return false;
788         }
789         if (val64 > static_cast<int64_t>(cUINT16_MAX))
790         {
791             val = def;
792             return false;
793         }
794         val = static_cast<uint16>(val64);
795         return true;
796     }
797
798     bool json_value::get_numeric(uint32 &val, uint32 def) const
799     {
800         int64_t val64;
801         if (!get_numeric(val64))
802         {
803             val = def;
804             return false;
805         }
806         if ((val64 < 0) || (val64 > static_cast<int64_t>(cUINT32_MAX)))
807         {
808             val = def;
809             return false;
810         }
811         val = static_cast<uint32>(val64);
812         return true;
813     }
814
815     bool json_value::validate(const json_node *pParent) const
816     {
817         if (is_node())
818         {
819             const json_node *pNode = get_node_ptr();
820             if (!pNode)
821                 return false;
822
823             if (!pNode->basic_validation(pParent))
824                 return false;
825
826             for (uint i = 0; i < pNode->size(); i++)
827                 if ((pNode->is_child(i)) && (!pNode->get_value(i).validate(pNode)))
828                     return false;
829         }
830         else if (is_string())
831         {
832             if (!m_data.m_pStr)
833                 return false;
834         }
835
836         return true;
837     }
838
839     void json_value::binary_serialize_value(vogl::vector<uint8> &buf) const
840     {
841         switch (m_type)
842         {
843             case cJSONValueTypeNull:
844             {
845                 buf.push_back('Z');
846                 break;
847             }
848             case cJSONValueTypeBool:
849             {
850                 buf.push_back(m_data.m_nVal ? 'T' : 'F');
851                 break;
852             }
853             case cJSONValueTypeInt:
854             {
855                 int shift;
856                 uint8 *pDst;
857                 if (static_cast<uint64_t>(m_data.m_nVal) <= 0xFFU)
858                 {
859                     pDst = buf.enlarge(2);
860                     *pDst++ = 'B';
861                     shift = 8 - 8;
862                 }
863                 else if ((m_data.m_nVal >= cINT16_MIN) && (m_data.m_nVal <= cINT16_MAX))
864                 {
865                     pDst = buf.enlarge(3);
866                     *pDst++ = 'i';
867                     shift = 16 - 8;
868                 }
869                 else if ((m_data.m_nVal >= cINT32_MIN) && (m_data.m_nVal <= cINT32_MAX))
870                 {
871                     pDst = buf.enlarge(5);
872                     *pDst++ = 'I';
873                     shift = 32 - 8;
874                 }
875                 else
876                 {
877                     pDst = buf.enlarge(9);
878                     *pDst++ = 'L';
879                     shift = 64 - 8;
880                 }
881
882                 uint64_t n = static_cast<uint64_t>(m_data.m_nVal);
883                 do
884                 {
885                     *pDst++ = static_cast<uint8>(n >> shift);
886                 } while ((shift -= 8) >= 0);
887
888                 break;
889             }
890             case cJSONValueTypeDouble:
891             {
892                 float flVal32 = static_cast<float>(m_data.m_flVal);
893                 if (math::equal_tol(m_data.m_flVal, static_cast<double>(flVal32), 1e-17))
894                 {
895                     uint8 *pDst = buf.enlarge(5);
896                     pDst[0] = 'd';
897                     utils::write_obj(flVal32, pDst + 1, false);
898                 }
899                 else
900                 {
901                     uint8 *pDst = buf.enlarge(9);
902                     pDst[0] = 'D';
903                     utils::write_obj(m_data.m_flVal, pDst + 1, false);
904                 }
905
906                 break;
907             }
908             case cJSONValueTypeString:
909             {
910                 uint len = static_cast<uint>(strlen(m_data.m_pStr));
911                 if (len <= 254)
912                 {
913                     uint8 *pDst = buf.enlarge(2 + len);
914                     pDst[0] = 's';
915                     pDst[1] = static_cast<uint8>(len);
916                     memcpy(pDst + 2, m_data.m_pStr, len);
917                 }
918                 else
919                 {
920                     uint8 *pDst = buf.enlarge(5 + len);
921                     pDst[0] = 'S';
922                     pDst[1] = static_cast<uint8>(len >> 24);
923                     pDst[2] = static_cast<uint8>(len >> 16);
924                     pDst[3] = static_cast<uint8>(len >> 8);
925                     pDst[4] = static_cast<uint8>(len);
926                     memcpy(pDst + 5, m_data.m_pStr, len);
927                 }
928
929                 break;
930             }
931             default:
932                 break;
933         }
934     }
935
936     void json_value::binary_serialize(vogl::vector<uint8> &buf) const
937     {
938         const json_node *pNode = get_node_ptr();
939         if (pNode)
940             pNode->binary_serialize(buf);
941         else
942             binary_serialize_value(buf);
943     }
944
945     bool json_value::binary_serialize_to_file(const char *pFilename)
946     {
947         FILE *pFile = vogl_fopen(pFilename, "wb");
948         if (!pFile)
949             return false;
950         bool success = binary_serialize(pFile);
951         if (vogl_fclose(pFile) == EOF)
952             success = false;
953         return success;
954     }
955
956     bool json_value::binary_serialize(FILE *pFile)
957     {
958         vogl::vector<uint8> buf;
959         binary_serialize(buf);
960         return fwrite(buf.get_ptr(), 1, buf.size(), pFile) == buf.size();
961     }
962
963     void json_value::serialize(vogl::vector<char> &buf, bool formatted, uint cur_indent, bool null_terminate, uint max_line_len) const
964     {
965         const json_node *pNode = get_node_ptr();
966         if (pNode)
967         {
968             pNode->serialize(buf, formatted, cur_indent, false, max_line_len);
969             if (formatted)
970                 buf.push_back('\n');
971         }
972         else
973         {
974             if (formatted)
975             {
976                 while (cur_indent--)
977                 {
978 #if 0
979                     // Apparently tabs are not valid JSON.
980                     buf.push_back('\t');
981 #else
982                     for (uint i = 0; i < cJSONTabSize; i++)
983                         buf.push_back(' ');
984 #endif
985                 }
986             }
987             if (is_string())
988             {
989                 json_growable_char_buf growable_buf(buf);
990                 growable_buf.print_escaped(m_data.m_pStr);
991             }
992             else
993             {
994                 dynamic_string str;
995                 get_string(str);
996                 buf.append(str.get_ptr(), str.get_len());
997             }
998         }
999
1000         if (null_terminate)
1001             buf.push_back('\0');
1002     }
1003
1004     bool json_value::binary_deserialize_file(const char *pFilename)
1005     {
1006         FILE *pFile = vogl_fopen(pFilename, "rb");
1007         if (!pFile)
1008             return false;
1009         bool success = binary_deserialize(pFile);
1010         if (vogl_fclose(pFile) == EOF)
1011             success = false;
1012         return success;
1013     }
1014
1015     bool json_value::binary_deserialize(FILE *pFile)
1016     {
1017         vogl_fseek(pFile, 0, SEEK_END);
1018         const uint64_t filesize = vogl_ftell(pFile);
1019         vogl_fseek(pFile, 0, SEEK_SET);
1020
1021         if (!filesize)
1022             return false;
1023
1024         if ((filesize > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE) || (filesize != static_cast<size_t>(filesize)))
1025             return false;
1026
1027         uint8 *pBuf = (uint8 *)vogl_malloc(static_cast<size_t>(filesize));
1028         if (!pBuf)
1029             return false;
1030
1031         if (vogl_fread(pBuf, 1, static_cast<size_t>(filesize), pFile) != filesize)
1032         {
1033             vogl_free(pBuf);
1034             return false;
1035         }
1036
1037         bool status = binary_deserialize(pBuf, static_cast<size_t>(filesize));
1038
1039         vogl_free(pBuf);
1040
1041         return status;
1042     }
1043
1044     bool json_value::binary_deserialize(const vogl::vector<uint8> &buf)
1045     {
1046         return buf.size() ? binary_deserialize(buf.get_ptr(), buf.size()) : false;
1047     }
1048
1049     bool json_value::binary_deserialize(const uint8 *pBuf, size_t n)
1050     {
1051         return binary_deserialize(pBuf, pBuf + n, NULL, 0);
1052     }
1053
1054     bool json_value::binary_deserialize(const uint8 *&pBuf, const uint8 *pBuf_end, json_node *pParent, uint depth)
1055     {
1056 #define JSON_BD_FAIL() \
1057     do                 \
1058     {                  \
1059         pBuf = pSrc;   \
1060         return false;  \
1061     } while (0)
1062         const uint8 *pSrc = pBuf;
1063         set_value_to_null();
1064
1065         if (depth > cMaxValidDepth)
1066             return false;
1067
1068         uint8 c;
1069         for (;;)
1070         {
1071             if (pSrc >= pBuf_end)
1072                 JSON_BD_FAIL();
1073             c = *pSrc++;
1074             if (c != 'N')
1075                 break;
1076         }
1077
1078         size_t n = pBuf_end - pSrc;
1079
1080         // Process huge nums as strings
1081         if (c == 'h')
1082             c = 's';
1083         else if (c == 'H')
1084             c = 'S';
1085
1086         switch (c)
1087         {
1088             case 'E':
1089                 JSON_BD_FAIL();
1090             case 'Z':
1091                 break;
1092             case 'A':
1093             case 'a':
1094             case 'O':
1095             case 'o':
1096             {
1097                 const bool is_object = ((c == 'O') || (c == 'o'));
1098
1099                 if (n < 1)
1100                     JSON_BD_FAIL();
1101
1102                 uint l = *pSrc++;
1103                 n--;
1104
1105                 bool unknown_len = false;
1106
1107                 if (c <= 'O')
1108                 {
1109                     if (n < 3)
1110                         JSON_BD_FAIL();
1111                     l = (l << 24) | (pSrc[0] << 16) | (pSrc[1] << 8) | pSrc[2];
1112
1113                     pSrc += 3;
1114                     n -= 3;
1115                 }
1116                 else if (l == 255)
1117                     unknown_len = true;
1118
1119                 json_node *pNode = set_value_to_node(is_object, pParent);
1120                 if (!unknown_len)
1121                     pNode->resize(l);
1122
1123                 uint idx = 0;
1124                 while ((unknown_len) || (idx < l))
1125                 {
1126                     uint8 q;
1127                     for (;;)
1128                     {
1129                         if (n < 1)
1130                             JSON_BD_FAIL();
1131                         q = *pSrc;
1132                         if (q != 'N')
1133                             break;
1134                         pSrc++;
1135                         n--;
1136                     }
1137
1138                     if (q == 'E')
1139                     {
1140                         pSrc++;
1141                         break;
1142                     }
1143                     if (unknown_len)
1144                         pNode->enlarge(1);
1145
1146                     if (is_object)
1147                     {
1148                         if ((q != 'S') && (q != 's'))
1149                             JSON_BD_FAIL();
1150
1151                         pSrc++;
1152                         n--;
1153
1154                         if (!n)
1155                             JSON_BD_FAIL();
1156
1157                         uint l = *pSrc++;
1158                         n--;
1159
1160                         if (c == 'S')
1161                         {
1162                             if (n < 3)
1163                                 JSON_BD_FAIL();
1164                             l = (l << 24) | (pSrc[0] << 16) | (pSrc[1] << 8) | pSrc[2];
1165                             pSrc += 3;
1166                             n -= 3;
1167                         }
1168
1169                         if (n < l)
1170                             JSON_BD_FAIL();
1171
1172                         pNode->get_key(idx).set_from_buf(pSrc, l);
1173
1174                         pSrc += l;
1175                     }
1176
1177                     if (!pNode->get_value(idx).binary_deserialize(pSrc, pBuf_end, pNode, depth + 1))
1178                         JSON_BD_FAIL();
1179
1180                     ++idx;
1181                 }
1182
1183                 break;
1184             }
1185             case 's':
1186             case 'S':
1187             {
1188                 if (!n)
1189                     JSON_BD_FAIL();
1190
1191                 uint l = *pSrc++;
1192                 n--;
1193
1194                 if (c == 'S')
1195                 {
1196                     if (n < 3)
1197                         JSON_BD_FAIL();
1198                     l = (l << 24) | (pSrc[0] << 16) | (pSrc[1] << 8) | pSrc[2];
1199                     pSrc += 3;
1200                     n -= 3;
1201                 }
1202
1203                 if (n < l)
1204                     JSON_BD_FAIL();
1205
1206                 m_type = cJSONValueTypeString;
1207                 m_data.m_pStr = (char *)vogl_malloc(l + 1);
1208                 if (!m_data.m_pStr)
1209                 {
1210                     set_value_to_null();
1211                     JSON_BD_FAIL();
1212                 }
1213                 memcpy(m_data.m_pStr, pSrc, l);
1214                 m_data.m_pStr[l] = '\0';
1215                 pSrc += l;
1216                 break;
1217             }
1218             case 'T':
1219             {
1220                 set_value(true);
1221                 break;
1222             }
1223             case 'F':
1224             {
1225                 set_value(false);
1226                 break;
1227             }
1228             case 'B':
1229             {
1230                 if (n < 1)
1231                     JSON_BD_FAIL();
1232                 m_type = cJSONValueTypeInt;
1233                 m_data.m_nVal = *pSrc++;
1234                 break;
1235             }
1236             case 'i':
1237             {
1238                 if (n < 2)
1239                     JSON_BD_FAIL();
1240                 m_type = cJSONValueTypeInt;
1241                 m_data.m_nVal = static_cast<int16>((pSrc[0] << 8) | pSrc[1]);
1242                 pSrc += 2;
1243                 break;
1244             }
1245             case 'I':
1246             {
1247                 if (n < 4)
1248                     JSON_BD_FAIL();
1249                 m_type = cJSONValueTypeInt;
1250                 m_data.m_nVal = static_cast<int32>((pSrc[0] << 24) | (pSrc[1] << 16) | (pSrc[2] << 8) | pSrc[3]);
1251                 pSrc += 4;
1252                 break;
1253             }
1254             case 'L':
1255             {
1256                 if (n < 8)
1257                     JSON_BD_FAIL();
1258                 m_type = cJSONValueTypeInt;
1259                 uint64_t v = 0;
1260                 for (uint i = 8; i; --i)
1261                     v = (v << 8) | *pSrc++;
1262                 m_data.m_nVal = static_cast<int64_t>(v);
1263                 break;
1264             }
1265             case 'd':
1266             {
1267                 if (n < 4)
1268                     JSON_BD_FAIL();
1269                 m_type = cJSONValueTypeDouble;
1270                 union
1271                 {
1272                     uint32 m_u32;
1273                     float m_fl32;
1274                 } bits;
1275                 bits.m_u32 = static_cast<uint32>((pSrc[0] << 24) | (pSrc[1] << 16) | (pSrc[2] << 8) | pSrc[3]);
1276                 pSrc += 4;
1277                 m_data.m_flVal = static_cast<double>(bits.m_fl32);
1278                 break;
1279             }
1280             case 'D':
1281             {
1282                 if (n < 8)
1283                     JSON_BD_FAIL();
1284                 m_type = cJSONValueTypeDouble;
1285                 uint64_t v = 0;
1286                 for (uint i = 8; i; --i)
1287                     v = (v << 8) | *pSrc++;
1288                 m_data.m_nVal = v;
1289                 break;
1290             }
1291             default:
1292                 return false;
1293         }
1294
1295 #undef JSON_BD_FAIL
1296
1297         pBuf = pSrc;
1298         return true;
1299     }
1300
1301     dynamic_string &json_value::serialize(dynamic_string &str, bool formatted, uint cur_indent, uint max_line_len) const
1302     {
1303         vogl::vector<char> buf;
1304         serialize(buf, formatted, cur_indent, false, max_line_len);
1305         return str.set_from_buf(buf.get_ptr(), buf.size_in_bytes());
1306     }
1307
1308     void json_value::print(bool formatted, uint cur_indent, uint max_line_len) const
1309     {
1310         vogl::vector<char> buf;
1311         serialize(buf, formatted, cur_indent, true, max_line_len);
1312         puts(buf.get_ptr());
1313     }
1314
1315     bool json_value::serialize_to_file(const char *pFilename, bool formatted, uint max_line_len) const
1316     {
1317         FILE *pFile = vogl_fopen(pFilename, "wb");
1318         if (!pFile)
1319             return false;
1320         bool success = serialize(pFile, formatted, max_line_len);
1321         if (vogl_fclose(pFile) == EOF)
1322             success = false;
1323         return success;
1324     }
1325
1326     bool json_value::serialize(FILE *pFile, bool formatted, uint max_line_len) const
1327     {
1328         vogl::vector<char> buf;
1329         serialize(buf, formatted, 0, false, max_line_len);
1330         return fwrite(buf.get_ptr(), 1, buf.size(), pFile) == buf.size();
1331     }
1332
1333     bool json_value::deserialize_node(json_deserialize_buf_ptr &pStr, json_node *pParent, uint level, json_error_info_t &error_info)
1334     {
1335         const bool is_object = (*pStr == '{');
1336         const char end_char = is_object ? '}' : ']';
1337
1338         json_node *pNode = set_value_to_node(is_object, pParent);
1339         pNode->m_line = pStr.get_cur_line();
1340
1341         pStr.advance_in_line_no_end_check(1);
1342         pStr.skip_whitespace();
1343
1344         for (;;)
1345         {
1346             char c = pStr.get_char();
1347             if (c == end_char)
1348                 break;
1349
1350             uint value_index = pNode->enlarge(1);
1351
1352             if (is_object)
1353             {
1354                 if (c != '\"')
1355                 {
1356                     error_info.set_error(pStr.get_cur_line(), "Expected quoted key string");
1357                     return false;
1358                 }
1359
1360                 pStr.advance_in_line_no_end_check(1);
1361
1362                 uint estimated_len;
1363                 if (!estimate_deserialized_string_size(pStr, error_info, estimated_len))
1364                     return false;
1365
1366                 if (estimated_len >= cMaxDynamicStringLen)
1367                 {
1368                     error_info.set_error(pStr.get_cur_line(), "Quoted name string is too long");
1369                     return false;
1370                 }
1371                 uint buf_size = estimated_len + 1;
1372                 char *pBuf = dynamic_string::create_raw_buffer(buf_size);
1373
1374                 char *pDst = pBuf;
1375                 if (!deserialize_quoted_string_to_buf(pDst, buf_size, pStr, error_info))
1376                 {
1377                     dynamic_string::free_raw_buffer(pBuf);
1378                     return false;
1379                 }
1380                 pNode->get_key(value_index).set_from_raw_buf_and_assume_ownership(pBuf, buf_size, static_cast<uint>(pDst - pBuf));
1381
1382                 pStr.skip_whitespace();
1383
1384                 if (*pStr != ':')
1385                 {
1386                     error_info.set_error(pStr.get_cur_line(), "Missing colon after key");
1387                     return false;
1388                 }
1389
1390                 pStr.advance_in_line_no_end_check(1);
1391
1392                 pStr.skip_whitespace();
1393             }
1394
1395             json_value &newVal = pNode->m_values[value_index];
1396             if (level > cMaxValidDepth)
1397             {
1398                 error_info.set_error(pStr.get_cur_line(), "Document is too complex");
1399                 return false;
1400             }
1401
1402             if (!newVal.deserialize(pStr, pNode, level + 1, error_info))
1403                 return false;
1404
1405             pStr.skip_whitespace();
1406
1407             if (*pStr != ',')
1408                 break;
1409
1410             pStr.advance_in_line_no_end_check(1);
1411
1412             pStr.skip_whitespace();
1413         }
1414
1415         if (pStr.get_and_advance() != end_char)
1416         {
1417             error_info.set_error(pStr.get_cur_line(), "Unexpected character within object or array");
1418             return false;
1419         }
1420
1421         return true;
1422     }
1423
1424     static const uint8 g_utf8_first_byte[7] =
1425         {
1426             0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
1427         };
1428
1429     bool json_value::estimate_deserialized_string_size(json_deserialize_buf_ptr &pStr, json_error_info_t &error_info, uint &size)
1430     {
1431         json_deserialize_buf_ptr pTmpStr(pStr);
1432         uint len = 0;
1433         for (;;)
1434         {
1435             char c = pTmpStr.get_and_advance();
1436             if ((!c) || (c == '\n'))
1437             {
1438                 error_info.set_error(pStr.get_cur_line(), "Missing end quote in string");
1439                 return false;
1440             }
1441             if (c == '\"')
1442                 break;
1443             else if (c == '\\')
1444             {
1445                 c = pTmpStr.get_and_advance();
1446                 if ((!c) || (c == '\n'))
1447                 {
1448                     error_info.set_error(pStr.get_cur_line(), "Missing escape character");
1449                     return false;
1450                 }
1451                 len++; // in case the escape char is a backslash
1452             }
1453             len++;
1454         }
1455         size = len;
1456         return true;
1457     }
1458
1459     // Note: This method assumes estimate_deserialized_string_size() was called on the string first, so it skips some checks.
1460     bool json_value::deserialize_quoted_string_to_buf(char *&pBuf, uint buf_size, json_deserialize_buf_ptr &pStr, json_error_info_t &error_info)
1461     {
1462         VOGL_NOTE_UNUSED(buf_size);
1463
1464         char *pDst = pBuf;
1465         for (;;)
1466         {
1467             char c = pStr.get_and_advance();
1468             if (c == '\"')
1469                 break;
1470             else if (c == '\\')
1471             {
1472                 c = pStr.get_and_advance();
1473                 if (c == 'u')
1474                 {
1475                     uint u = 0;
1476                     for (uint i = 0; i < 4; i++)
1477                     {
1478                         u <<= 4;
1479                         int c = vogl_tolower(pStr.get_and_advance());
1480                         if ((c >= 'a') && (c <= 'f'))
1481                             u += c - 'a' + 10;
1482                         else if ((c >= '0') && (c <= '9'))
1483                             u += c - '0';
1484                         else
1485                         {
1486                             error_info.set_error(pStr.get_cur_line(), "Invalid Unicode escape");
1487                             return false;
1488                         }
1489                     }
1490
1491                     uint len;
1492                     if ((u) && (u < 0x80))
1493                         len = 1;
1494                     else if (u < 0x800)
1495                         len = 2;
1496                     else
1497                         len = 3;
1498
1499                     pDst += len;
1500                     switch (len)
1501                     {
1502                         case 3:
1503                             *--pDst = static_cast<char>((u | 0x80) & 0xBF);
1504                             u >>= 6; // falls through
1505                         case 2:
1506                             *--pDst = static_cast<char>((u | 0x80) & 0xBF);
1507                             u >>= 6; // falls through
1508                         case 1:
1509                             *--pDst = static_cast<char>(u | g_utf8_first_byte[len]);
1510                     }
1511                     pDst += len;
1512                 }
1513                 else
1514                 {
1515                     switch (c)
1516                     {
1517                         case 'b':
1518                             c = '\b';
1519                             break;
1520                         case 'f':
1521                             c = '\f';
1522                             break;
1523                         case 'n':
1524                             c = '\n';
1525                             break;
1526                         case 'r':
1527                             c = '\r';
1528                             break;
1529                         case 't':
1530                             c = '\t';
1531                             break;
1532                         case '\\':
1533                         case '\"':
1534                         case '/':
1535                             break;
1536                         default:
1537                             *pDst++ = '\\';
1538                             break; // unrecognized escape, so forcefully escape the backslash
1539                     }
1540
1541                     *pDst++ = c;
1542                 }
1543             }
1544             else
1545             {
1546                 *pDst++ = c;
1547             }
1548         }
1549
1550         *pDst = '\0';
1551
1552         VOGL_ASSERT((pDst - pBuf) < (int)buf_size);
1553
1554         pBuf = pDst;
1555
1556         return true;
1557     }
1558
1559     bool json_value::deserialize_string(json_deserialize_buf_ptr &pStr, json_error_info_t &error_info)
1560     {
1561         pStr.advance_in_line_no_end_check(1);
1562
1563         uint estimated_len;
1564         if (!estimate_deserialized_string_size(pStr, error_info, estimated_len))
1565             return false;
1566
1567         uint buf_size = estimated_len + 1;
1568         char *pBuf = (char *)vogl_malloc(buf_size);
1569         if (!pBuf)
1570         {
1571             error_info.set_error(pStr.get_cur_line(), "Out of memory");
1572             return false;
1573         }
1574
1575         char *pDst = pBuf;
1576         if (!deserialize_quoted_string_to_buf(pDst, buf_size, pStr, error_info))
1577             return false;
1578
1579         set_value_assume_ownership(pBuf);
1580
1581         return true;
1582     }
1583
1584     bool json_value::is_equal(const json_value &other, double tol) const
1585     {
1586         if (this == &other)
1587             return true;
1588
1589         if (get_type() != other.get_type())
1590         {
1591             if (is_numeric() && other.is_numeric())
1592                 return math::equal_tol(as_double(), other.as_double(), tol);
1593             return false;
1594         }
1595
1596         switch (get_type())
1597         {
1598             case cJSONValueTypeNull:
1599                 return true;
1600             case cJSONValueTypeBool:
1601             case cJSONValueTypeInt:
1602                 return m_data.m_nVal == other.m_data.m_nVal;
1603             case cJSONValueTypeDouble:
1604                 return math::equal_tol(m_data.m_flVal, other.m_data.m_flVal, tol);
1605             case cJSONValueTypeString:
1606                 return !strcmp(m_data.m_pStr, other.m_data.m_pStr);
1607             case cJSONValueTypeNode:
1608             {
1609                 const json_node *pNode = get_node_ptr();
1610                 const json_node *pOther_node = other.get_node_ptr();
1611                 if (pNode->is_object() != pOther_node->is_object())
1612                     return false;
1613
1614                 if (pNode->size() != pOther_node->size())
1615                     return false;
1616
1617                 for (uint i = 0; i < pNode->size(); i++)
1618                 {
1619                     if ((pNode->is_object()) && (pNode->get_key(i).compare(pOther_node->get_key(i), true) != 0))
1620                         return false;
1621                     if (!pNode->get_value(i).is_equal(pOther_node->get_value(i), tol))
1622                         return false;
1623                 }
1624             }
1625         }
1626
1627         return true;
1628     }
1629
1630     static const double g_pow10_table[63] =
1631         {
1632             1.e-031, 1.e-030, 1.e-029, 1.e-028, 1.e-027, 1.e-026, 1.e-025, 1.e-024, 1.e-023, 1.e-022, 1.e-021, 1.e-020, 1.e-019, 1.e-018, 1.e-017, 1.e-016,
1633             1.e-015, 1.e-014, 1.e-013, 1.e-012, 1.e-011, 1.e-010, 1.e-009, 1.e-008, 1.e-007, 1.e-006, 1.e-005, 1.e-004, 1.e-003, 1.e-002, 1.e-001, 1.e+000,
1634             1.e+001, 1.e+002, 1.e+003, 1.e+004, 1.e+005, 1.e+006, 1.e+007, 1.e+008, 1.e+009, 1.e+010, 1.e+011, 1.e+012, 1.e+013, 1.e+014, 1.e+015, 1.e+016,
1635             1.e+017, 1.e+018, 1.e+019, 1.e+020, 1.e+021, 1.e+022, 1.e+023, 1.e+024, 1.e+025, 1.e+026, 1.e+027, 1.e+028, 1.e+029, 1.e+030, 1.e+031
1636         };
1637
1638     bool json_value::deserialize_number(json_deserialize_buf_ptr &pStr, json_error_info_t &error_info)
1639     {
1640         uint64_t n = 0, limit = cINT64_MAX;
1641         int sign = 1;
1642         bool bParseAsDouble = false;
1643
1644         char c = pStr.get_char();
1645         if (c == '-')
1646         {
1647             sign = -1;
1648             limit++;
1649             pStr.advance_in_line_no_end_check(1);
1650             c = pStr.get_char();
1651         }
1652
1653         while ((c >= '0') && (c <= '9'))
1654         {
1655             if (n > 0x1999999999999998ULL)
1656             {
1657                 bParseAsDouble = true;
1658                 break;
1659             }
1660             n = n * 10U + c - '0';
1661             pStr.advance_in_line_no_end_check(1);
1662             c = pStr.get_char();
1663         }
1664
1665         if ((bParseAsDouble) || (n > limit) || (c == 'e') || (c == 'E') || (c == '.'))
1666         {
1667             double f = static_cast<double>(n);
1668             int scale = 0, escalesign = 1, escale = 0;
1669
1670             while ((c >= '0') && (c <= '9'))
1671             {
1672                 f = f * 10.0f + (c - '0');
1673                 pStr.advance_in_line_no_end_check(1);
1674                 c = pStr.get_char();
1675             }
1676
1677             if (c == '.')
1678             {
1679                 pStr.advance_in_line_no_end_check(1);
1680                 c = pStr.get_char();
1681                 while ((c >= '0') && (c <= '9'))
1682                 {
1683                     scale--;
1684                     f = f * 10.0f + (c - '0');
1685                     pStr.advance_in_line_no_end_check(1);
1686                     c = pStr.get_char();
1687                 }
1688             }
1689
1690             if ((c == 'e') || (c == 'E'))
1691             {
1692                 pStr.advance_in_line_no_end_check(1);
1693                 char c = pStr.get_char();
1694                 if (c == '-')
1695                 {
1696                     escalesign = -1;
1697                     pStr.advance_in_line_no_end_check(1);
1698                     c = pStr.get_char();
1699                 }
1700                 else if (c == '+')
1701                 {
1702                     pStr.advance_in_line_no_end_check(1);
1703                     c = pStr.get_char();
1704                 }
1705                 while ((c >= '0') && (c <= '9'))
1706                 {
1707                     if (escale > 0xCCCCCCB)
1708                     {
1709                         error_info.set_error(pStr.get_cur_line(), "Failed parsing numeric value");
1710                         return false;
1711                     }
1712                     escale = escale * 10 + (c - '0');
1713                     pStr.advance_in_line_no_end_check(1);
1714                     c = pStr.get_char();
1715                 }
1716             }
1717
1718             double v = sign * f;
1719             int64_t final_scale = scale + escale * escalesign;
1720             if ((final_scale < -31) || (final_scale > 31))
1721             {
1722                 if ((final_scale < cINT32_MIN) || (final_scale > cINT32_MAX))
1723                 {
1724                     error_info.set_error(pStr.get_cur_line(), "Failed parsing numeric value");
1725                     return false;
1726                 }
1727                 v *= pow(10.0, static_cast<int>(final_scale));
1728             }
1729             else
1730                 v *= g_pow10_table[static_cast<int>(final_scale) + 31];
1731
1732             set_value(v);
1733         }
1734         else
1735         {
1736             int64_t v = static_cast<int64_t>(n);
1737             if (sign < 0)
1738                 v = -v;
1739             set_value(v);
1740         }
1741
1742         return true;
1743     }
1744
1745     bool json_value::deserialize_file(const char *pFilename, json_error_info_t *pError_info)
1746     {
1747         clear();
1748
1749         FILE *pFile = vogl_fopen(pFilename, "rb");
1750         if (!pFile)
1751         {
1752             if (pError_info)
1753                 pError_info->set_error(0, "Unable to open file");
1754             return false;
1755         }
1756
1757         bool success = deserialize(pFile, pError_info);
1758
1759         if (vogl_fclose(pFile) == EOF)
1760             success = false;
1761
1762         return success;
1763     }
1764
1765     bool json_value::deserialize(const vogl::vector<char> &buf, json_error_info_t *pError_info)
1766     {
1767         return deserialize(buf.get_ptr(), buf.size(), pError_info);
1768     }
1769
1770     bool json_value::deserialize(FILE *pFile, json_error_info_t *pError_info)
1771     {
1772         vogl_fseek(pFile, 0, SEEK_END);
1773         const uint64_t filesize = vogl_ftell(pFile);
1774         vogl_fseek(pFile, 0, SEEK_SET);
1775
1776         if ((filesize > VOGL_MAX_POSSIBLE_HEAP_BLOCK_SIZE) || (filesize != static_cast<size_t>(filesize)))
1777         {
1778             if (pError_info)
1779                 pError_info->set_error(0, "File too large");
1780             return false;
1781         }
1782
1783         char *pBuf = (char *)vogl_malloc(static_cast<size_t>(filesize) + 1);
1784         if (!pBuf)
1785         {
1786             if (pError_info)
1787                 pError_info->set_error(0, "Out of memory");
1788             return false;
1789         }
1790
1791         if (vogl_fread(pBuf, 1, static_cast<size_t>(filesize), pFile) != static_cast<size_t>(filesize))
1792         {
1793             vogl_free(pBuf);
1794             if (pError_info)
1795                 pError_info->set_error(0, "Failed reading from file");
1796             return false;
1797         }
1798
1799         // Not really necesssary
1800         pBuf[filesize] = '\0';
1801
1802         bool status = deserialize(pBuf, static_cast<size_t>(filesize), pError_info);
1803
1804         vogl_free(pBuf);
1805
1806         return status;
1807     }
1808
1809     bool json_value::deserialize(const char *pStr, json_error_info_t *pError_info)
1810     {
1811         return deserialize(pStr, strlen(pStr), pError_info);
1812     }
1813
1814     bool json_value::deserialize(const dynamic_string &str, json_error_info_t *pError_info)
1815     {
1816         return deserialize(str.get_ptr(), str.get_len(), pError_info);
1817     }
1818
1819     bool json_value::deserialize(const char *pBuf, size_t buf_size, json_error_info_t *pError_info)
1820     {
1821         set_value_to_null();
1822
1823         if (!buf_size)
1824         {
1825             if (pError_info)
1826                 pError_info->set_error(0, "Nothing to deserialize");
1827             return false;
1828         }
1829
1830         json_deserialize_buf_ptr buf_ptr(pBuf, buf_size);
1831         buf_ptr.skip_whitespace();
1832         if (*buf_ptr == '\0')
1833         {
1834             if (pError_info)
1835                 pError_info->set_error(0, "Nothing to deserialize");
1836             return false;
1837         }
1838
1839         json_error_info_t dummy_error_info;
1840         if (!deserialize(buf_ptr, NULL, 0, pError_info ? *pError_info : dummy_error_info))
1841             return false;
1842
1843         buf_ptr.skip_whitespace();
1844         if (!buf_ptr.at_end())
1845         {
1846             if (pError_info)
1847                 pError_info->set_error(buf_ptr.get_cur_line(), "Syntax error on/near line");
1848             return false;
1849         }
1850         return true;
1851     }
1852
1853     bool json_value::deserialize(json_deserialize_buf_ptr &pStr, json_node *pParent, uint level, json_error_info_t &error_info)
1854     {
1855         m_line = pStr.get_cur_line();
1856
1857         char c = *pStr;
1858         switch (c)
1859         {
1860             case '{':
1861             case '[':
1862                 return deserialize_node(pStr, pParent, level, error_info);
1863             case '\"':
1864                 return deserialize_string(pStr, error_info);
1865             case 'n':
1866             {
1867                 if (pStr.compare_string("null", 4))
1868                 {
1869                     set_value_to_null();
1870                     pStr.advance_in_line(4);
1871                     return true;
1872                 }
1873                 break;
1874             }
1875             case 't':
1876             {
1877                 if (pStr.compare_string("true", 4))
1878                 {
1879                     set_value(true);
1880                     pStr.advance_in_line(4);
1881                     return true;
1882                 }
1883                 break;
1884             }
1885             case 'f':
1886             {
1887                 if (pStr.compare_string("false", 5))
1888                 {
1889                     set_value(false);
1890                     pStr.advance_in_line(5);
1891                     return true;
1892                 }
1893                 break;
1894             }
1895             default:
1896             {
1897                 if ((c == '-') || (c == '.') || ((c >= '0') && (c <= '9')))
1898                     return deserialize_number(pStr, error_info);
1899                 break;
1900             }
1901         }
1902         error_info.set_error(pStr.get_cur_line(), "Unrecognized character: '%c'", c);
1903         return false;
1904     }
1905
1906     // class json_node
1907
1908     json_node::json_node()
1909         : m_pParent(NULL),
1910           m_line(0),
1911           m_is_object(false)
1912     {
1913     }
1914
1915     json_node::json_node(const json_node &other)
1916         : m_pParent(NULL),
1917           m_line(0),
1918           m_is_object(false)
1919     {
1920         *this = other;
1921     }
1922
1923     json_node::json_node(const json_node *pParent, bool is_object)
1924         : m_pParent(pParent),
1925           m_line(0),
1926           m_is_object(is_object)
1927     {
1928     }
1929
1930     json_node::~json_node()
1931     {
1932         clear();
1933     }
1934
1935     json_node &json_node::operator=(const json_node &rhs)
1936     {
1937         if (this == &rhs)
1938             return *this;
1939
1940         clear();
1941
1942         set_is_object(rhs.is_object());
1943         m_pParent = rhs.m_pParent;
1944
1945         if (is_object())
1946             m_keys.resize(rhs.size());
1947         m_values.resize(rhs.size());
1948
1949         for (uint i = 0; i < rhs.size(); i++)
1950         {
1951             if (is_object())
1952                 m_keys[i] = rhs.m_keys[i];
1953
1954             m_values[i] = rhs.m_values[i];
1955             if (m_values[i].is_node())
1956                 m_values[i].get_node_ptr()->m_pParent = this;
1957
1958             //VOGL_ASSERT(m_values[i].validate(this));
1959         }
1960
1961         m_line = rhs.m_line;
1962
1963         return *this;
1964     }
1965
1966     const json_value &json_node::find_value(const char *pKey) const
1967     {
1968         int index = find_key(pKey);
1969         return (index < 0) ? g_null_json_value : m_values[index];
1970     }
1971
1972     int json_node::find_key(const char *pKey) const
1973     {
1974         for (uint i = 0; i < m_keys.size(); i++)
1975             if (m_keys[i] == pKey)
1976                 return i;
1977         return cInvalidIndex;
1978     }
1979
1980     int json_node::find_child(const json_node *pNode) const
1981     {
1982         for (uint i = 0; i < m_values.size(); i++)
1983             if (m_values[i].get_node_ptr() == pNode)
1984                 return i;
1985         return cInvalidIndex;
1986     }
1987
1988     json_value_type_t json_node::find_value_type(const char *pKey) const
1989     {
1990         int index = find_key(pKey);
1991         return (index >= 0) ? get_value_type(index) : cJSONValueTypeNull;
1992     }
1993
1994     const json_node *json_node::find_child(const char *pKey) const
1995     {
1996         int index = find_key(pKey);
1997         return (index >= 0) ? get_child(index) : NULL;
1998     }
1999
2000     json_node *json_node::find_child(const char *pKey)
2001     {
2002         int index = find_key(pKey);
2003         return (index >= 0) ? get_child(index) : NULL;
2004     }
2005
2006     const json_node *json_node::find_child_array(const char *pKey) const
2007     {
2008         const json_node *pNode = find_child(pKey);
2009         return (pNode && pNode->is_array()) ? pNode : NULL;
2010     }
2011
2012     json_node *json_node::find_child_array(const char *pKey)
2013     {
2014         json_node *pNode = find_child(pKey);
2015         return (pNode && pNode->is_array()) ? pNode : NULL;
2016     }
2017
2018     const json_node *json_node::find_child_object(const char *pKey) const
2019     {
2020         const json_node *pNode = find_child(pKey);
2021         return (pNode && pNode->is_object()) ? pNode : NULL;
2022     }
2023
2024     bool json_node::are_all_children_values() const
2025     {
2026         for (uint i = 0; i < m_values.size(); i++)
2027             if (m_values[i].is_object_or_array())
2028                 return false;
2029         return true;
2030     }
2031
2032     bool json_node::are_all_children_objects() const
2033     {
2034         for (uint i = 0; i < m_values.size(); i++)
2035             if (!m_values[i].is_object())
2036                 return false;
2037         return true;
2038     }
2039
2040     bool json_node::are_all_children_arrays() const
2041     {
2042         for (uint i = 0; i < m_values.size(); i++)
2043             if (!m_values[i].is_array())
2044                 return false;
2045         return true;
2046     }
2047
2048     bool json_node::are_all_children_objects_or_arrays() const
2049     {
2050         for (uint i = 0; i < m_values.size(); i++)
2051             if (!m_values[i].is_object_or_array())
2052                 return false;
2053         return true;
2054     }
2055
2056     json_node *json_node::find_child_object(const char *pKey)
2057     {
2058         json_node *pNode = find_child(pKey);
2059         return (pNode && pNode->is_object()) ? pNode : NULL;
2060     }
2061
2062     bool json_node::get_value_as_string(const char *pKey, dynamic_string &val, const char *pDef) const
2063     {
2064         int index = find_key(pKey);
2065         if (index < 0)
2066         {
2067             val.set(pDef);
2068             return false;
2069         }
2070         return m_values[index].get_string(val, pDef);
2071     }
2072
2073     bool json_node::get_value_as_int64(const char *pKey, int64_t &val, int64_t def) const
2074     {
2075         int index = find_key(pKey);
2076         if (index < 0)
2077         {
2078             val = def;
2079             return false;
2080         }
2081         return m_values[index].get_numeric(val, def);
2082     }
2083
2084     bool json_node::get_value_as_uint32(const char *pKey, uint32 &val, uint32 def) const
2085     {
2086         int index = find_key(pKey);
2087         if (index < 0)
2088         {
2089             val = def;
2090             return false;
2091         }
2092         return m_values[index].get_numeric(val, def);
2093     }
2094
2095     bool json_node::get_value_as_uint64(const char *pKey, uint64_t &val, uint64_t def) const
2096     {
2097         int index = find_key(pKey);
2098         if (index < 0)
2099         {
2100             val = def;
2101             return false;
2102         }
2103         return m_values[index].get_numeric(val, def);
2104     }
2105
2106     bool json_node::get_value_as_float(const char *pKey, float &val, float def) const
2107     {
2108         int index = find_key(pKey);
2109         if (index < 0)
2110         {
2111             val = def;
2112             return false;
2113         }
2114         return m_values[index].get_numeric(val, def);
2115     }
2116
2117     bool json_node::get_value_as_double(const char *pKey, double &val, double def) const
2118     {
2119         int index = find_key(pKey);
2120         if (index < 0)
2121         {
2122             val = def;
2123             return false;
2124         }
2125         return m_values[index].get_numeric(val, def);
2126     }
2127
2128     bool json_node::get_value_as_bool(const char *pKey, bool &val, bool def) const
2129     {
2130         int index = find_key(pKey);
2131         if (index < 0)
2132         {
2133             val = def;
2134             return false;
2135         }
2136         return m_values[index].get_bool(val, def);
2137     }
2138
2139     dynamic_string json_node::value_as_string(const char *pKey, const char *pDef) const
2140     {
2141         dynamic_string result;
2142         get_value_as_string(pKey, result, pDef);
2143         return result;
2144     }
2145
2146     const char *json_node::value_as_string_ptr(const char *pKey, const char *pDef) const
2147     {
2148         int index = find_key(pKey);
2149         if (index < 0)
2150             return pDef;
2151         return value_as_string_ptr(index, pDef);
2152     }
2153
2154     int json_node::value_as_int(const char *pKey, int def) const
2155     {
2156         int result;
2157         get_value_as_int(pKey, result, def);
2158         return result;
2159     }
2160
2161     int32 json_node::value_as_int32(const char *pKey, int32 def) const
2162     {
2163         int32 result;
2164         get_value_as_int(pKey, result, def);
2165         return result;
2166     }
2167
2168     uint32 json_node::value_as_uint32(const char *pKey, uint32 def) const
2169     {
2170         uint32 result;
2171         get_value_as_uint32(pKey, result, def);
2172         return result;
2173     }
2174
2175     uint64_t json_node::value_as_uint64(const char *pKey, uint64_t def) const
2176     {
2177         uint64_t result;
2178         get_value_as_uint64(pKey, result, def);
2179         return result;
2180     }
2181
2182     int64_t json_node::value_as_int64(const char *pKey, int64_t def) const
2183     {
2184         int64_t result;
2185         get_value_as_int(pKey, result, def);
2186         return result;
2187     }
2188
2189     float json_node::value_as_float(const char *pKey, float def) const
2190     {
2191         float result;
2192         get_value_as_float(pKey, result, def);
2193         return result;
2194     }
2195
2196     double json_node::value_as_double(const char *pKey, double def) const
2197     {
2198         double result;
2199         get_value_as_double(pKey, result, def);
2200         return result;
2201     }
2202
2203     bool json_node::value_as_bool(const char *pKey, bool def) const
2204     {
2205         bool result;
2206         get_value_as_bool(pKey, result, def);
2207         return result;
2208     }
2209
2210     dynamic_string json_node::value_as_string(uint index, const char *pDef) const
2211     {
2212         return m_values[index].as_string(pDef);
2213     }
2214
2215     const char *json_node::value_as_string_ptr(uint index, const char *pDef) const
2216     {
2217         return m_values[index].as_string_ptr(pDef);
2218     }
2219
2220     int json_node::value_as_int(uint index, int def) const
2221     {
2222         return m_values[index].as_int(def);
2223     }
2224
2225     int32 json_node::value_as_int32(uint index, int32 def) const
2226     {
2227         return m_values[index].as_int32(def);
2228     }
2229
2230     int64_t json_node::value_as_int64(uint index, int64_t def) const
2231     {
2232         return m_values[index].as_int64(def);
2233     }
2234
2235     uint64_t json_node::value_as_uint64(uint index, uint64_t def) const
2236     {
2237         return m_values[index].as_uint64(def);
2238     }
2239
2240     uint32 json_node::value_as_uint32(uint index, uint32 def) const
2241     {
2242         return m_values[index].as_uint32(def);
2243     }
2244
2245     float json_node::value_as_float(uint index, float def) const
2246     {
2247         return m_values[index].as_float(def);
2248     }
2249
2250     double json_node::value_as_double(uint index, double def) const
2251     {
2252         return m_values[index].as_double(def);
2253     }
2254
2255     bool json_node::value_as_bool(uint index, bool def) const
2256     {
2257         return m_values[index].as_bool(def);
2258     }
2259
2260     void json_node::clear()
2261     {
2262         m_keys.clear();
2263         m_values.clear();
2264         m_is_object = false;
2265         m_line = 0;
2266     }
2267
2268     void json_node::resize(uint new_size)
2269     {
2270         if (m_is_object)
2271             m_keys.resize(new_size, true);
2272         m_values.resize(new_size, true);
2273     }
2274
2275     void json_node::reserve(uint new_capacity)
2276     {
2277         if (m_is_object)
2278             m_keys.reserve(new_capacity);
2279         m_values.reserve(new_capacity);
2280     }
2281
2282     void json_node::set_is_object(bool is_object)
2283     {
2284         if (m_is_object == is_object)
2285             return;
2286         if (is_object)
2287             m_keys.resize(size());
2288         else
2289             m_keys.clear();
2290         m_is_object = is_object;
2291     }
2292
2293     void json_node::ensure_is_object()
2294     {
2295         if (!m_is_object)
2296         {
2297             m_is_object = true;
2298             m_keys.resize(m_values.size());
2299         }
2300     }
2301
2302     json_value &json_node::add_key_value(const char *pKey, const json_value &val)
2303     {
2304         ensure_is_object();
2305
2306         uint new_index = m_values.size();
2307
2308         m_keys.push_back(pKey);
2309
2310         m_values.push_back(val);
2311         if (val.is_node())
2312             m_values[new_index].get_node_ptr()->m_pParent = this;
2313
2314         return m_values[new_index];
2315     }
2316
2317     json_value &json_node::add_value()
2318     {
2319         if (m_is_object)
2320             m_keys.enlarge(1);
2321         return *m_values.enlarge(1);
2322     }
2323
2324     json_value &json_node::add_value(const json_value &val)
2325     {
2326         uint new_index = m_values.size();
2327
2328         if (m_is_object)
2329             m_keys.enlarge(1);
2330
2331         m_values.push_back(val);
2332         if (val.is_node())
2333             m_values[new_index].get_node_ptr()->m_pParent = this;
2334
2335         return m_values[new_index];
2336     }
2337
2338     bool json_node::add_key_and_parsed_value(const char *pKey, const char *pStr)
2339     {
2340         json_value val;
2341         if (!val.deserialize(pStr))
2342             return false;
2343
2344         ensure_is_object();
2345
2346         m_keys.push_back(pKey);
2347
2348         json_value *p = m_values.enlarge(1);
2349         val.release_ownership(*p);
2350         if (p->is_node())
2351             p->get_node_ptr()->m_pParent = this;
2352
2353         return true;
2354     }
2355
2356     bool json_node::add_parsed_value(const char *pStr)
2357     {
2358         json_value val;
2359         if (!val.deserialize(pStr))
2360             return false;
2361
2362         if (m_is_object)
2363             m_keys.enlarge(1);
2364
2365         json_value *p = m_values.enlarge(1);
2366         val.release_ownership(*p);
2367         if (p->is_node())
2368             p->get_node_ptr()->m_pParent = this;
2369
2370         return true;
2371     }
2372
2373     dynamic_string &json_node::get_key(uint index)
2374     {
2375         if (!m_is_object)
2376         {
2377             VOGL_ASSERT_ALWAYS;
2378             return g_empty_dynamic_string;
2379         }
2380         return m_keys[index];
2381     }
2382
2383     void json_node::set_key_value(uint index, const char *pKey, const json_value &val)
2384     {
2385         ensure_is_object();
2386         m_keys[index].set(pKey);
2387
2388         m_values[index] = val;
2389         if (m_values[index].is_node())
2390             m_values[index].get_node_ptr()->m_pParent = this;
2391     }
2392
2393     void json_node::set_key(uint index, const char *pKey)
2394     {
2395         ensure_is_object();
2396         m_keys[index].set(pKey);
2397     }
2398
2399     void json_node::set_value(uint index, const json_value &val)
2400     {
2401         m_values[index] = val;
2402         if (m_values[index].is_node())
2403             m_values[index].get_node_ptr()->m_pParent = this;
2404     }
2405
2406     void json_node::set_value_assume_ownership(uint index, json_value &val)
2407     {
2408         json_value &val_to_set = m_values[index];
2409         val_to_set.set_value_to_null();
2410         val_to_set.swap(val);
2411
2412         if (val_to_set.is_node())
2413             val_to_set.get_node_ptr()->m_pParent = this;
2414     }
2415
2416     void json_node::add_value_assume_ownership(json_value &val)
2417     {
2418         if (m_is_object)
2419             m_keys.enlarge(1);
2420         uint new_index = m_values.size();
2421         m_values.enlarge(1);
2422         set_value_assume_ownership(new_index, val);
2423     }
2424
2425     void json_node::add_key_value_assume_ownership(const char *pKey, json_value &val)
2426     {
2427         ensure_is_object();
2428         m_keys.push_back(pKey);
2429
2430         uint new_index = m_values.size();
2431         m_values.enlarge(1);
2432         set_value_assume_ownership(new_index, val);
2433     }
2434
2435     json_value &json_node::get_or_add(const char *pKey)
2436     {
2437         int index = find_key(pKey);
2438         if (index >= 0)
2439             return m_values[index];
2440
2441         ensure_is_object();
2442         m_keys.push_back(pKey);
2443         return *m_values.enlarge(1);
2444     }
2445
2446     json_value &json_node::add(const char *pKey)
2447     {
2448         ensure_is_object();
2449         m_keys.push_back(pKey);
2450         return *m_values.enlarge(1);
2451     }
2452
2453     json_node &json_node::add_object(const char *pKey)
2454     {
2455         ensure_is_object();
2456         m_keys.push_back(pKey);
2457
2458         json_node *pNode = get_json_node_pool()->alloc(this, true);
2459         m_values.enlarge(1);
2460         m_values.back().set_value_assume_ownership(pNode);
2461         return *pNode;
2462     }
2463
2464     json_node &json_node::add_array(const char *pKey)
2465     {
2466         ensure_is_object();
2467         m_keys.push_back(pKey);
2468
2469         json_node *pNode = get_json_node_pool()->alloc(this, false);
2470         m_values.enlarge(1)->set_value_assume_ownership(pNode);
2471         return *pNode;
2472     }
2473
2474     json_node &json_node::add_object()
2475     {
2476         if (m_is_object)
2477             m_keys.enlarge(1);
2478         json_node *pNode = get_json_node_pool()->alloc(this, true);
2479         m_values.enlarge(1)->set_value_assume_ownership(pNode);
2480         return *pNode;
2481     }
2482
2483     json_node &json_node::add_array()
2484     {
2485         if (m_is_object)
2486             m_keys.enlarge(1);
2487         json_node *pNode = get_json_node_pool()->alloc(this, false);
2488         m_values.enlarge(1)->set_value_assume_ownership(pNode);
2489         return *pNode;
2490     }
2491
2492     bool json_node::erase(const char *pKey)
2493     {
2494         int index = find_key(pKey);
2495         if (index >= 0)
2496         {
2497             erase(index);
2498             return true;
2499         }
2500         return false;
2501     }
2502
2503     void json_node::erase(uint index)
2504     {
2505         if (m_is_object)
2506             m_keys.erase(index);
2507         m_values.erase(index);
2508     }
2509
2510     bool json_node::basic_validation(const json_node *pParent) const
2511     {
2512         if (m_pParent != pParent)
2513             return false;
2514
2515         if (!m_is_object)
2516         {
2517             if (m_keys.size())
2518                 return false;
2519         }
2520         else if (m_keys.size() != m_values.size())
2521             return false;
2522
2523         return true;
2524     }
2525
2526     bool json_node::validate(const json_node *pParent) const
2527     {
2528         if (!basic_validation(pParent))
2529             return false;
2530
2531         for (uint i = 0; i < m_values.size(); i++)
2532             if (!m_values[i].validate(this))
2533                 return false;
2534
2535         return true;
2536     }
2537
2538     dynamic_string json_node::get_path_to_node() const
2539     {
2540         dynamic_string_array node_names;
2541
2542         const json_node *pCur_node = this;
2543
2544         for (;;)
2545         {
2546             const json_node *pParent = pCur_node->m_pParent;
2547
2548             if (!pParent)
2549             {
2550                 node_names.push_back("[root]");
2551                 break;
2552             }
2553
2554             int parent_child_index = pParent->find_child(pCur_node);
2555             if (parent_child_index < 0)
2556             {
2557                 VOGL_VERIFY(0);
2558                 break;
2559             }
2560
2561             if (pParent->is_array())
2562                 node_names.push_back(dynamic_string(cVarArg, "[%u]", parent_child_index));
2563             else
2564                 node_names.push_back(pParent->get_key(parent_child_index));
2565
2566             pCur_node = pParent;
2567         }
2568
2569         dynamic_string result;
2570         for (int i = node_names.size() - 1; i >= 0; i--)
2571         {
2572             result.append(node_names[i]);
2573             if (i)
2574                 result.append("/");
2575         }
2576
2577         return result;
2578     }
2579
2580     dynamic_string json_node::get_path_to_key(const char *pKey) const
2581     {
2582         dynamic_string path(get_path_to_node());
2583         path.append("/");
2584         path.append(pKey);
2585         return path;
2586     }
2587
2588     dynamic_string json_node::get_path_to_item(uint index) const
2589     {
2590         dynamic_string path(get_path_to_node());
2591         if (is_array())
2592             path.append(dynamic_string(cVarArg, "/[%u]", index).get_ptr());
2593         else
2594             path.append(dynamic_string(cVarArg, "/%s", m_keys[index].get_ptr()).get_ptr());
2595         return path;
2596     }
2597
2598     bool json_node::check_for_duplicate_keys() const
2599     {
2600         VOGL_VERIFY(validate(m_pParent));
2601
2602         bool status = false;
2603
2604         if (m_is_object)
2605         {
2606             dynamic_string_array sorted_keys(m_keys);
2607
2608             sorted_keys.sort(dynamic_string_less_than_case_sensitive());
2609
2610             for (uint i = 0; i < sorted_keys.size(); i++)
2611             {
2612                 uint count = 1;
2613
2614                 while (((i + 1) < sorted_keys.size()) && (sorted_keys[i].compare(sorted_keys[i + 1], true) == 0))
2615                 {
2616                     count++;
2617                     i++;
2618                 }
2619
2620                 VOGL_ASSERT(((i + 1) == sorted_keys.size()) || (sorted_keys[i].compare(sorted_keys[i + 1], true) < 0));
2621
2622                 if (count > 1)
2623                 {
2624                     status = true;
2625
2626                     console::debug("%s: Key appears %u times in node: %s\n", VOGL_METHOD_NAME, count, get_path_to_item(i).get_ptr());
2627                 }
2628             }
2629         }
2630
2631         for (uint i = 0; i < m_values.size(); i++)
2632         {
2633             const json_node *pChild = get_child(i);
2634
2635             if ((pChild) && (pChild->check_for_duplicate_keys()))
2636                 status = true;
2637         }
2638
2639         return status;
2640     }
2641
2642     void json_node::serialize(vogl::vector<char> &buf, bool formatted, uint cur_indent, bool null_terminate, uint max_line_len) const
2643     {
2644         json_growable_char_buf growable_buf(buf);
2645         if ((cur_indent) && (formatted))
2646             growable_buf.print_tabs(cur_indent);
2647         serialize(growable_buf, formatted, cur_indent, max_line_len);
2648         if (null_terminate)
2649             buf.push_back('\0');
2650     }
2651
2652     void json_node::serialize(dynamic_string &str, bool formatted, uint cur_index, uint max_line_len) const
2653     {
2654         vogl::vector<char> buf;
2655         serialize(buf, formatted, cur_index, max_line_len);
2656
2657         // FIXME: Pass along string ownership once dynamic_string supports non-pow2 sized buffers
2658         str.set_from_buf(buf.get_ptr(), vogl_strlen(buf.get_ptr()));
2659     }
2660
2661     void json_node::serialize(json_growable_char_buf &buf, bool formatted, uint cur_indent, uint max_line_len) const
2662     {
2663         if (is_object())
2664         {
2665             VOGL_ASSERT(m_keys.size() == m_values.size());
2666         }
2667         else
2668         {
2669             VOGL_ASSERT(!m_keys.size());
2670         }
2671
2672         if (!size())
2673         {
2674             if (formatted)
2675                 buf.puts(is_object() ? "{ }" : "[ ]");
2676             else
2677                 buf.puts(is_object() ? "{}" : "[]");
2678             return;
2679         }
2680
2681         const uint cMaxLineLen = max_line_len;
2682
2683 #if 0
2684         if (formatted && !has_children() && !is_object() && (size() <= 40))
2685         {
2686                 uint orig_buf_size = buf.size();
2687                 buf.puts("[ ");
2688
2689                 for (uint i = 0; i < size(); i++)
2690                 {
2691                         dynamic_string val;
2692                         get_value(i).get_string(val);
2693                         if (get_value_type(i) == cJSONValueTypeString)
2694                                 buf.print_escaped(val.get_ptr());
2695                         else
2696                                 buf.puts(val.get_ptr());
2697
2698                         if (i != size() - 1)
2699                         {
2700                                 buf.print_char(',');
2701                                 buf.print_char(' ');
2702                         }
2703
2704                         if ((buf.size() - orig_buf_size) > cMaxLineLen)
2705                                 break;
2706                 }
2707
2708                 buf.puts(" ]");
2709
2710                 if ((buf.size() - orig_buf_size) <= cMaxLineLen)
2711                         return;
2712
2713                 buf.get().resize(orig_buf_size);
2714         }
2715 #else
2716         if (formatted && !has_children() && !is_object())
2717         {
2718             uint line_start_ofs = buf.size();
2719
2720             buf.puts("[ ");
2721             if (formatted && !cMaxLineLen)
2722                 buf.print_char('\n');
2723
2724             for (uint i = 0; i < size(); i++)
2725             {
2726                 dynamic_string val;
2727                 get_value(i).get_string(val);
2728
2729                 if (formatted && !cMaxLineLen)
2730                     buf.print_tabs(cur_indent);
2731
2732                 if (get_value_type(i) == cJSONValueTypeString)
2733                     buf.print_escaped(val.get_ptr());
2734                 else
2735                     buf.puts(val.get_ptr());
2736
2737                 if (i != size() - 1)
2738                 {
2739                     buf.print_char(',');
2740                     if (formatted && !cMaxLineLen)
2741                         buf.print_char('\n');
2742                 }
2743
2744                 if (cMaxLineLen)
2745                 {
2746                     if ((buf.size() - line_start_ofs) >= cMaxLineLen)
2747                     {
2748                         buf.print_char('\n');
2749
2750                         buf.print_tabs(cur_indent);
2751
2752                         line_start_ofs = buf.size();
2753                     }
2754                     else if (i != size() - 1)
2755                         buf.print_char(' ');
2756                 }
2757             }
2758
2759             buf.puts(" ]");
2760
2761             return;
2762         }
2763 #endif
2764
2765         buf.print_char(is_object() ? '{' : '[');
2766         if (formatted)
2767             buf.print_char('\n');
2768
2769         cur_indent++;
2770
2771         dynamic_string val;
2772
2773         for (uint i = 0; i < size(); i++)
2774         {
2775             if (formatted)
2776                 buf.print_tabs(cur_indent);
2777             if (is_object())
2778             {
2779                 buf.print_escaped(get_key(i).get_ptr());
2780                 buf.puts(formatted ? " : " : ":");
2781             }
2782
2783             json_value_type_t val_type = get_value_type(i);
2784             if (val_type == cJSONValueTypeNode)
2785                 get_child(i)->serialize(buf, formatted, cur_indent, max_line_len);
2786             else if (val_type == cJSONValueTypeString)
2787                 buf.print_escaped(get_value(i).as_string_ptr());
2788             else
2789             {
2790                 get_value(i).get_string(val);
2791                 buf.puts(val.get_ptr());
2792             }
2793
2794             if (i != size() - 1)
2795                 buf.print_char(',');
2796             if (formatted)
2797                 buf.print_char('\n');
2798         }
2799
2800         cur_indent--;
2801
2802         if (formatted)
2803             buf.print_tabs(cur_indent);
2804         buf.print_char(is_object() ? '}' : ']');
2805     }
2806
2807     void json_node::binary_serialize(vogl::vector<uint8> &buf) const
2808     {
2809         uint8 *pDst;
2810         uint n = m_values.size();
2811         if (n <= 254)
2812         {
2813             pDst = buf.enlarge(2);
2814             pDst[0] = m_is_object ? 'o' : 'a';
2815             pDst[1] = static_cast<uint8>(n);
2816         }
2817         else
2818         {
2819             pDst = buf.enlarge(5);
2820             pDst[0] = m_is_object ? 'O' : 'A';
2821             pDst[1] = static_cast<uint8>(n >> 24);
2822             pDst[2] = static_cast<uint8>(n >> 16);
2823             pDst[3] = static_cast<uint8>(n >> 8);
2824             pDst[4] = static_cast<uint8>(n);
2825         }
2826         if (!n)
2827             return;
2828
2829         const dynamic_string *pKey = m_keys.get_ptr();
2830         const json_value *pVal = m_values.get_ptr();
2831         for (uint i = n; i; --i, ++pKey, ++pVal)
2832         {
2833             if (m_is_object)
2834             {
2835                 uint len = pKey->get_len();
2836                 if (len <= 254)
2837                 {
2838                     uint8 *pDst = buf.enlarge(2 + len);
2839                     pDst[0] = 's';
2840                     pDst[1] = static_cast<uint8>(len);
2841                     memcpy(pDst + 2, pKey->get_ptr(), len);
2842                 }
2843                 else
2844                 {
2845                     uint8 *pDst = buf.enlarge(5 + len);
2846                     pDst[0] = 'S';
2847                     pDst[1] = static_cast<uint8>(len >> 24);
2848                     pDst[2] = static_cast<uint8>(len >> 16);
2849                     pDst[3] = static_cast<uint8>(len >> 8);
2850                     pDst[4] = static_cast<uint8>(len);
2851                     memcpy(pDst + 5, pKey->get_ptr(), len);
2852                 }
2853             }
2854
2855             if (pVal->is_node())
2856                 pVal->get_node_ptr()->binary_serialize(buf);
2857             else
2858                 pVal->binary_serialize_value(buf);
2859         }
2860     }
2861
2862     bool json_node::has_children() const
2863     {
2864         for (uint i = 0; i < m_values.size(); i++)
2865             if (m_values[i].get_type() == cJSONValueTypeNode)
2866                 return true;
2867         return false;
2868     }
2869
2870     bool json_node::get_value_as_enum(const char *pKey, const char **pStringList, int &val, int def) const
2871     {
2872         val = def;
2873         int index = find_key(pKey);
2874         if (index < 0)
2875             return false;
2876         return get_value(index).get_enum(pStringList, val, def);
2877     }
2878
2879     // class json_document
2880
2881     json_document::json_document()
2882         : m_error_line(0)
2883     {
2884         init_object();
2885     }
2886
2887     json_document::json_document(const json_value &other)
2888         : m_error_line(0)
2889     {
2890         get_value() = other;
2891     }
2892
2893     json_document &json_document::operator=(const json_value &rhs)
2894     {
2895         if (&get_value() == &rhs)
2896             return *this;
2897
2898         clear();
2899
2900         get_value() = rhs;
2901
2902         return *this;
2903     }
2904
2905     json_document::json_document(const json_document &other)
2906         : json_value(other),
2907           m_error_line(0)
2908     {
2909         *this = other;
2910     }
2911
2912     json_document &json_document::operator=(const json_document &rhs)
2913     {
2914         if (this == &rhs)
2915             return *this;
2916
2917         clear();
2918
2919         m_error_msg = rhs.m_error_msg;
2920         m_error_line = rhs.m_error_line;
2921         m_filename = rhs.m_filename;
2922
2923         get_value() = rhs.get_value();
2924
2925         return *this;
2926     }
2927
2928     json_document::json_document(const char *pStr, const char *pFilename)
2929         : m_error_line(0)
2930     {
2931         deserialize(pStr, pFilename);
2932     }
2933
2934     json_document::json_document(const char *pBuf, uint n, const char *pFilename)
2935         : m_error_line(0)
2936     {
2937         deserialize(pBuf, n, pFilename);
2938     }
2939
2940     json_document::json_document(json_value_type_t value_type)
2941         : m_error_line(0)
2942     {
2943         init(value_type);
2944     }
2945
2946     json_document::~json_document()
2947     {
2948         clear();
2949     }
2950
2951     void json_document::swap(json_document &other)
2952     {
2953         std::swap(m_error_line, other.m_error_line);
2954         m_error_msg.swap(other.m_error_msg);
2955         m_filename.swap(other.m_filename);
2956         get_value().swap(other.get_value());
2957     }
2958
2959     bool json_document::deserialize_file(const char *pFilename)
2960     {
2961         set_filename(pFilename);
2962
2963         json_error_info_t err_info;
2964         if (!json_value::deserialize_file(pFilename, &err_info))
2965         {
2966             m_error_msg.swap(err_info.m_error_msg);
2967             m_error_line = err_info.m_error_line;
2968
2969             return false;
2970         }
2971
2972         return true;
2973     }
2974
2975     bool json_document::deserialize(const vogl::vector<char> &buf, const char *pFilename)
2976     {
2977         return deserialize(buf.get_ptr(), buf.size(), pFilename);
2978     }
2979
2980     bool json_document::deserialize(FILE *pFile, const char *pFilename)
2981     {
2982         set_filename(pFilename);
2983
2984         json_error_info_t err_info;
2985         if (!json_value::deserialize(pFile, &err_info))
2986         {
2987             m_error_msg.swap(err_info.m_error_msg);
2988             m_error_line = err_info.m_error_line;
2989
2990             return false;
2991         }
2992
2993         return true;
2994     }
2995
2996     bool json_document::deserialize(const char *pBuf, size_t n, const char *pFilename)
2997     {
2998         set_filename(pFilename);
2999
3000         json_error_info_t err_info;
3001         if (!json_value::deserialize(pBuf, n, &err_info))
3002         {
3003             m_error_msg.swap(err_info.m_error_msg);
3004             m_error_line = err_info.m_error_line;
3005
3006             return false;
3007         }
3008
3009         return true;
3010     }
3011
3012     bool json_document::deserialize(const char *pStr, const char *pFilename)
3013     {
3014         return deserialize(pStr, static_cast<uint>(strlen(pStr)), pFilename);
3015     }
3016
3017     bool json_document::deserialize(const dynamic_string &str, const char *pFilename)
3018     {
3019         return deserialize(str.get_ptr(), str.get_len(), pFilename);
3020     }
3021
3022     class my_type
3023     {
3024     public:
3025         vogl::vector<dynamic_string> a1;
3026         vogl::map<dynamic_string, dynamic_string_array> a2;
3027         dynamic_string a;
3028         dynamic_string b;
3029
3030         bool json_serialize(json_value &val) const
3031         {
3032             json_node *pObj = val.init_object();
3033             pObj->add_object("a1", a1);
3034             pObj->add_object("a2", a2);
3035             pObj->add_object("a", a);
3036             pObj->add_object("b", b);
3037             return true;
3038         }
3039
3040         bool json_deserialize(const json_value &val)
3041         {
3042             const json_node *pObj = val.get_node_ptr();
3043             if (!pObj)
3044                 return false;
3045             pObj->get_object("a1", a1);
3046             pObj->get_object("a2", a2);
3047             pObj->get_object("a", a);
3048             pObj->get_object("b", b);
3049             return true;
3050         }
3051     };
3052
3053     // TODO: Actually test these classes.
3054     bool json_test()
3055     {
3056         // Create a JSON document
3057         json_document doc;
3058         json_node *pRoot = doc.get_root();
3059
3060         typedef vogl::growable_array<uint, 16> my_growable_array_type;
3061         my_growable_array_type growable_array;
3062         growable_array.push_back(99);
3063         growable_array.push_back(100);
3064         pRoot->add_object("growable_array", growable_array);
3065         pRoot->get_object("growable_array", growable_array);
3066
3067         pRoot->add_vector("growable_array2", growable_array);
3068         pRoot->get_vector("growable_array2", growable_array);
3069
3070         // Create a vector of my_type's, put it into a JSON document, then retrieve it into another vector.
3071         typedef vogl::vector<my_type> my_type_vec;
3072
3073         my_type_vec mv;
3074         mv.resize(2);
3075         mv[0].a1.push_back("a");
3076         mv[0].a1.push_back("b");
3077         mv[0].a1.push_back("c");
3078         dynamic_string_array dsa;
3079         dsa.push_back("1");
3080         mv[0].a2.insert("zz", dsa);
3081         dsa.push_back("2");
3082         mv[0].a2.insert("xx", dsa);
3083         dsa.push_back("3");
3084         mv[0].a2.insert("yy", dsa);
3085         mv[0].a = "one";
3086         mv[0].b = "two";
3087         mv[1].a = "three";
3088         mv[1].b = "four";
3089
3090         pRoot->add_vector("my_type_vec", mv);
3091
3092         pRoot->add_object("hey", 2);
3093         int z = 0;
3094         pRoot->get_object("hey", z);
3095
3096         pRoot->add_object("blah", mv);
3097         pRoot->get_object("blah", mv);
3098
3099         my_type_vec mv2;
3100         pRoot->get_vector("my_type_vec", mv2);
3101
3102         printf("my_type_vec:\n");
3103         for (uint i = 0; i < mv2.size(); i++)
3104         {
3105             printf("a: %s\nb: %s\n", mv2[i].a.get_ptr(), mv2[i].b.get_ptr());
3106         }
3107
3108         // Create a string set and add it to the JSON document under the "set" object
3109         typedef vogl::map<dynamic_string> string_set;
3110         string_set ss;
3111         ss.insert("blah");
3112         pRoot->add_map("set", ss);
3113
3114         typedef vogl::vector<int16> cool_vec;
3115         cool_vec blah;
3116         blah.push_back(1);
3117         blah.push_back(3);
3118         blah.push_back(5);
3119         pRoot->add_vector("vec", blah);
3120
3121         cool_vec blah2;
3122         pRoot->get_vector("vec", blah2);
3123         printf("vec:\n");
3124         for (uint i = 0; i < blah2.size(); i++)
3125             printf("%i\n", blah2[i]);
3126
3127         // Now create a string to string array map
3128         typedef vogl::map<dynamic_string, dynamic_string_array> string_map;
3129         string_map s;
3130
3131         dynamic_string_array sa;
3132         sa.push_back("a");
3133         s.insert("1", sa);
3134
3135         dynamic_string_array sb;
3136         sb.push_back("b");
3137         sb.push_back("c");
3138         sb.push_back("d");
3139         s.insert("2", sb);
3140
3141         // Add the string to string map to the JSON document under the "hashmap" object
3142         pRoot->add_map("hashmap", s);
3143
3144         // Now serialize the JSON document to text and print it to stdout
3145         dynamic_string str;
3146         doc.serialize(str);
3147         printf("JSON: %s\n", str.get_ptr());
3148
3149         // Retrieve the string map under the "hashmap" object and put it into q
3150         string_map q;
3151         pRoot->get_map("hashmap", q);
3152
3153         // Now print q
3154         printf("hashmap:\n");
3155         for (string_map::const_iterator it = q.begin(); it != q.end(); ++it)
3156         {
3157             const dynamic_string_array &b = it->second;
3158
3159             printf("%s :\n", it->first.get_ptr());
3160             for (uint i = 0; i < b.size(); i++)
3161                 printf(" %s\n", b[i].get_ptr());
3162         }
3163
3164         return true;
3165     }
3166
3167 } // namespace vogl