Advertisement
Guest User

pjson.h - Super fast JSON parser, with Ensemble-style DOM

a guest
Dec 17th, 2016
2,255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 85.33 KB | None | 0 0
  1. // File: pjson.h - written by Rich Geldreich 2012 - License: Unlicense http://unlicense.org/
  2. #ifndef PURPLE_JSON_H
  3. #define PURPLE_JSON_H
  4.  
  5. #ifdef WIN32
  6. #pragma once
  7. #endif
  8.  
  9. #include <string>
  10. #include <vector>
  11. #include <limits>
  12. #include <assert.h>
  13.  
  14. // ---- Macros
  15.  
  16. #define PJSON_ASSERT assert
  17. #define PJSON_FORCEINLINE __forceinline
  18.  
  19. #define PJSON_PARSE_STATS 0
  20.  
  21. #define PJSON_DEFAULT_MIN_CHUNK_SIZE 4096
  22. #define PJSON_MAX_CHUNK_GROW_SIZE 8*1024*1024
  23. #define PJSON_DEFAULT_MAX_BYTES_TO_PRESERVE_ACROSS_RESETS 16*1024*1024
  24.  
  25. #define PJSON_MIN(a, b) (((a) < (b)) ? (a) : (b))
  26. #define PJSON_MAX(a, b) (((a) < (b)) ? (b) : (a))
  27.  
  28. namespace pjson
  29. {
  30.    // ---- Types
  31.    typedef unsigned char uint8;
  32.    typedef unsigned int uint;
  33.    typedef signed int int32;
  34.    typedef unsigned int uint32;
  35.    typedef signed __int64 int64;
  36.    typedef unsigned __int64 uint64;
  37.  
  38.    class document;
  39.    class value_variant;
  40.    struct value_variant_data;
  41.    struct key_value_t;
  42.    
  43.    typedef std::vector<char> char_vec_t;
  44.    typedef std::string string_t;
  45.  
  46.    // Memory allocation
  47.  
  48.    inline void* pjson_malloc(size_t size) { return malloc(size); }
  49.    inline void* pjson_realloc(void* p, size_t size) { return realloc(p, size); }
  50.    inline void pjson_free(void* p) { free(p); }
  51.    
  52.    // Misc. Helpers
  53.    template<typename T> inline void swap(T& l, T& r) { T temp(l); l = r; r = temp; }
  54.  
  55.    inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); }
  56.    inline uint32 next_pow2(uint32 val) { val--; val |= val >> 16; val |= val >> 8; val |= val >> 4; val |= val >> 2; val |= val >> 1; return val + 1; }
  57.  
  58.    inline int pjson_stricmp(const char* p, const char* q) { return _stricmp(p, q); }
  59.  
  60.    // ---- Global Arrays
  61.  
  62.    // This template utilizes the One Definition Rule to create global arrays in a header.
  63.    template<typename unused=void>
  64.    struct globals_struct
  65.    {
  66.       static const uint8 s_str_serialize_flags[256];
  67.       static const double s_pow10_table[63];
  68.       static const uint8 s_parse_flags[256];
  69.    };
  70.    typedef globals_struct<> globals;
  71.    
  72.    template<typename unused>
  73.    const uint8 globals_struct<unused>::s_str_serialize_flags[256] =
  74.    {
  75.    // 0    1    2    3    4    5    6    7      8    9    A    B    C    D    E    F
  76.       1,   1,   1,   1,   1,   1,   1,   1,     1,   1,   1,   1,   1,   1,   1,   1, // 0
  77.       1,   1,   1,   1,   1,   1,   1,   1,     1,   1,   1,   1,   1,   1,   1,   1, // 1
  78.       0,   0,   1,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 2
  79.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 1
  80.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 4
  81.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   1,   0,   0,   0, // 5
  82.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 6
  83.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 7
  84.    // 128-255
  85.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  86.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  87.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  88.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0
  89.    };
  90.  
  91.    template<typename unused>
  92.    const double globals_struct<unused>::s_pow10_table[63] =
  93.    {
  94.       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,
  95.       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,
  96.       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,
  97.       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
  98.    };
  99.  
  100.    // bit 0 (1) - set if: \0 cr lf " \
  101.    // bit 1 (2) - set if: \0 cr lf
  102.    // bit 2 (4) - set if: whitespace
  103.    // bit 3 (8) - set if: 0-9
  104.    // bit 4 (0x10) - set if: 0-9 e E .
  105.    template<typename unused>
  106.    const uint8 globals_struct<unused>::s_parse_flags[256] =
  107.    {
  108.    // 0    1    2    3    4    5    6    7      8    9    A    B    C    D    E    F
  109.       7,   4,   4,   4,   4,   4,   4,   4,     4,   4,   7,   4,   4,   7,   4,   4, // 0
  110.       4,   4,   4,   4,   4,   4,   4,   4,     4,   4,   4,   4,   4,   4,   4,   4, // 1
  111.       4,   0,   1,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0x10,0, // 2
  112.       0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,  0x18,0x18,0,   0,   0,   0,   0,   0, // 3
  113.       0,   0,   0,   0,   0,   0x10,0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 4
  114.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   1,   0,   0,   0, // 5
  115.       0,   0,   0,   0,   0,   0x10,0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 6
  116.       0,   0,   0,   0,   0,   0,   0,   0,     0,   0,   0,   0,   0,   0,   0,   0, // 7
  117.  
  118.    // 128-255
  119.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  120.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  121.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
  122.       0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0
  123.    };
  124.  
  125.    // ---- Pool Allocator
  126.  
  127.    struct pool_allocator
  128.    {
  129.       inline pool_allocator(uint initial_size = 0, uint min_chunk_size = PJSON_DEFAULT_MIN_CHUNK_SIZE, size_t max_bytes_to_preserve_across_resets = PJSON_DEFAULT_MAX_BYTES_TO_PRESERVE_ACROSS_RESETS) :
  130.          m_pActive_chunks(NULL),
  131.          m_pFree_chunks(NULL),
  132.          m_total_free_bytes(0),
  133.          m_initial_size(initial_size),
  134.          m_min_chunk_size(min_chunk_size),
  135.          m_cur_grow_size(min_chunk_size),
  136.          m_max_to_preserve_across_resets(max_bytes_to_preserve_across_resets)
  137.       {
  138.          if (initial_size)
  139.          {
  140.             m_pActive_chunks = static_cast<chunk*>(pjson_malloc(sizeof(chunk) + initial_size));
  141.             m_pActive_chunks->m_pNext = NULL;
  142.             m_pActive_chunks->m_ofs = 0;
  143.             m_pActive_chunks->m_size = initial_size;
  144.          }
  145.       }
  146.  
  147.       inline ~pool_allocator()
  148.       {
  149.          clear();
  150.       }
  151.  
  152.       // Release all active/free chunks
  153.       void clear()
  154.       {
  155.          free_chunk_chain(m_pActive_chunks);
  156.          m_pActive_chunks = NULL;
  157.          
  158.          free_chunk_chain(m_pFree_chunks);
  159.          m_pFree_chunks = NULL;
  160.  
  161.          m_total_free_bytes = 0;
  162.          
  163.          m_cur_grow_size = m_min_chunk_size;
  164.       }
  165.  
  166.       inline size_t get_total_free_bytes() const { return m_total_free_bytes; }
  167.      
  168.       inline uint get_min_chunk_size() const { return m_min_chunk_size; }
  169.       inline size_t get_max_bytes_to_preserve_across_resets() const { return m_max_to_preserve_across_resets; }
  170.  
  171.       inline void set_min_chunk_size(uint s) { m_min_chunk_size = m_cur_grow_size = s; }
  172.       inline void set_max_bytes_to_preserve_across_resets(size_t s) { m_max_to_preserve_across_resets = s; }
  173.  
  174.       inline uint get_cur_grow_size() const { return m_cur_grow_size; }
  175.      
  176.       inline void* Alloc(size_t size)
  177.       {
  178.          size = (size + 3) & ~3;
  179.          if ((!m_pActive_chunks) || ((m_pActive_chunks->m_size - m_pActive_chunks->m_ofs) < size))
  180.          {
  181.             chunk* pNew_chunk = m_pFree_chunks;
  182.             if ((pNew_chunk) && (pNew_chunk->m_size >= size))
  183.             {
  184.                PJSON_ASSERT(m_total_free_bytes >= pNew_chunk->m_size);
  185.                m_total_free_bytes -= pNew_chunk->m_size;
  186.                m_pFree_chunks = pNew_chunk->m_pNext;
  187.                PJSON_ASSERT(!pNew_chunk->m_ofs);
  188.             }
  189.             else
  190.             {
  191.                size_t alloc_size = PJSON_MAX(size, m_cur_grow_size);
  192.                m_cur_grow_size = PJSON_MIN(m_cur_grow_size * 2, PJSON_MAX_CHUNK_GROW_SIZE);
  193.  
  194.                pNew_chunk = static_cast<chunk*>(pjson_malloc(sizeof(chunk) + alloc_size));
  195.                pNew_chunk->m_size = alloc_size;
  196.                pNew_chunk->m_ofs = 0;
  197.             }
  198.  
  199.             pNew_chunk->m_pNext = m_pActive_chunks;
  200.             m_pActive_chunks = pNew_chunk;
  201.          }
  202.          void* pRet = (uint8*)m_pActive_chunks + sizeof(chunk) + m_pActive_chunks->m_ofs;
  203.          m_pActive_chunks->m_ofs += size;
  204.          PJSON_ASSERT(m_pActive_chunks->m_ofs <= m_pActive_chunks->m_size);
  205.          return pRet;
  206.       }
  207.  
  208.       inline void* Realloc(void* p, size_t new_size, size_t cur_size)
  209.       {
  210.          if (!p)
  211.             return Alloc(new_size);
  212.          
  213.          new_size = (new_size + 3) & ~3;
  214.          cur_size = (cur_size + 3) & ~3;
  215.          if (new_size == cur_size)
  216.             return p;
  217.  
  218.          uint8* pTop = (uint8*)m_pActive_chunks + sizeof(chunk) + m_pActive_chunks->m_ofs;
  219.          if ((static_cast<uint8*>(p) + cur_size) == pTop)
  220.          {
  221.             if (new_size > cur_size)
  222.             {
  223.                size_t bytes_needed = new_size - cur_size;
  224.                if ((m_pActive_chunks->m_size - m_pActive_chunks->m_ofs) >= bytes_needed)
  225.                {
  226.                   m_pActive_chunks->m_ofs += bytes_needed;
  227.                   PJSON_ASSERT(m_pActive_chunks->m_ofs <= m_pActive_chunks->m_size);
  228.                   return p;
  229.                }
  230.             }
  231.             else
  232.             {
  233.                PJSON_ASSERT(m_pActive_chunks->m_ofs >= (cur_size - new_size));
  234.                m_pActive_chunks->m_ofs -= (cur_size - new_size);
  235.                return new_size ? p : NULL;
  236.             }
  237.          }
  238.  
  239.          if (!new_size)
  240.             return NULL;
  241.  
  242.          void* pNew_block = Alloc(new_size);
  243.          memcpy(pNew_block, p, cur_size);
  244.          return pNew_block;
  245.       }
  246.  
  247.       // Move all active chunks to the free chunk list, then free any chunks if we're over the preserve limit.
  248.       inline void reset()
  249.       {
  250.          if (!m_pActive_chunks)
  251.             return;
  252.          
  253.          chunk* pCur_active_tail = m_pActive_chunks;
  254.          size_t total_allocated_bytes = 0;
  255.          for ( ; ; )
  256.          {
  257.             total_allocated_bytes += pCur_active_tail->m_size;
  258.             pCur_active_tail->m_ofs = 0;
  259.             if (!pCur_active_tail->m_pNext)
  260.                break;
  261.             pCur_active_tail = pCur_active_tail->m_pNext;
  262.          }
  263.          pCur_active_tail->m_pNext = m_pFree_chunks;
  264.                            
  265.          m_pFree_chunks = m_pActive_chunks;
  266.          m_pActive_chunks = NULL;
  267.  
  268.          m_total_free_bytes += total_allocated_bytes;
  269.          while (m_total_free_bytes > m_max_to_preserve_across_resets)
  270.          {
  271.             PJSON_ASSERT(m_pFree_chunks);
  272.             chunk* pNext_free = m_pFree_chunks->m_pNext;
  273.             PJSON_ASSERT(m_total_free_bytes >= m_pFree_chunks->m_size);
  274.             m_total_free_bytes -= m_pFree_chunks->m_size;
  275.             pjson_free(m_pFree_chunks);
  276.             m_pFree_chunks = pNext_free;
  277.          }
  278.  
  279.          m_cur_grow_size = m_min_chunk_size;
  280.       }
  281.  
  282.       struct stats_t
  283.       {
  284.          size_t m_total_allocated;
  285.  
  286.          uint m_num_active_chunks;
  287.          size_t m_num_active_bytes_allocated;
  288.          size_t m_num_active_bytes_avail;
  289.          size_t m_max_active_chunk_size;
  290.  
  291.          uint m_num_free_chunks;
  292.          size_t m_num_free_chunk_bytes_avail;
  293.          size_t m_max_free_chunk_size;
  294.       };
  295.  
  296.       inline void get_stats(stats_t& s) const
  297.       {
  298.          memset(&s, 0, sizeof(s));
  299.  
  300.          chunk* pChunk = m_pActive_chunks;
  301.          while (pChunk)
  302.          {
  303.             s.m_num_active_chunks++;
  304.             s.m_total_allocated += pChunk->m_size;
  305.             s.m_num_active_bytes_allocated += pChunk->m_ofs;
  306.             s.m_num_active_bytes_avail += (pChunk->m_size - pChunk->m_ofs);
  307.             s.m_max_active_chunk_size = PJSON_MAX(s.m_max_active_chunk_size, pChunk->m_size);
  308.             pChunk = pChunk->m_pNext;
  309.          }
  310.  
  311.          pChunk = m_pFree_chunks;
  312.          while (pChunk)
  313.          {
  314.             s.m_num_free_chunks++;
  315.             s.m_total_allocated += pChunk->m_size;
  316.             PJSON_ASSERT(!pChunk->m_ofs);
  317.             s.m_num_free_chunk_bytes_avail += pChunk->m_size;
  318.             s.m_max_free_chunk_size = PJSON_MAX(s.m_max_free_chunk_size, pChunk->m_size);
  319.             pChunk = pChunk->m_pNext;
  320.          }
  321.  
  322.          PJSON_ASSERT(s.m_num_free_chunk_bytes_avail == m_total_free_bytes);
  323.       }
  324.  
  325.    private:
  326.       pool_allocator(const pool_allocator&);
  327.       pool_allocator& operator= (const pool_allocator&);
  328.  
  329.       struct chunk
  330.       {
  331.          chunk* m_pNext;
  332.          size_t m_size;
  333.          size_t m_ofs;
  334.       };
  335.  
  336.       chunk* m_pActive_chunks;
  337.       chunk* m_pFree_chunks;
  338.       size_t m_total_free_bytes;
  339.  
  340.       uint m_initial_size;
  341.       uint m_min_chunk_size;
  342.       size_t m_max_to_preserve_across_resets;
  343.      
  344.       uint m_cur_grow_size;
  345.  
  346.       inline void free_chunk_chain(chunk* pChunk)
  347.       {
  348.          while (pChunk)
  349.          {
  350.             chunk* pNext_chunk = pChunk->m_pNext;
  351.             pjson_free(pChunk);
  352.             pChunk = pNext_chunk;
  353.          }
  354.       }
  355.    };
  356.  
  357.    // ---- Simple vector (growable array)
  358.  
  359.    template<typename T>
  360.    struct simple_vector_default_copy_construction_policy
  361.    {
  362.       inline static void copy_construct(void *pDst, const T& init, pool_allocator& alloc) { alloc; new (pDst) T(init); }
  363.       inline static void assign(void *pDst, const T& src, pool_allocator& alloc) { alloc; *static_cast<T*>(pDst) = src; }
  364.    };
  365.  
  366.    template<typename T>
  367.    struct simple_vector_allocator_copy_construction_policy
  368.    {
  369.       inline static void copy_construct(void *pDst, const T& init, pool_allocator& alloc) { alloc; new (pDst) T(init, alloc); }
  370.       inline static void assign(void *pDst, const T& src, pool_allocator& alloc) { static_cast<T*>(pDst)->assign(src, alloc); }
  371.    };
  372.  
  373.    template <typename T> inline T* construct(T* p) { return new (static_cast<void*>(p)) T; }
  374.    template <typename T> inline void construct_array(T* p, uint n) { T* q = p + n; for ( ; p != q; ++p) new (static_cast<void*>(p)) T; }
  375.    
  376.    template<typename T>
  377.    struct elemental_vector
  378.    {
  379.       typedef T               value_type;
  380.       typedef T&              reference;
  381.       typedef const T&        const_reference;
  382.       typedef T*              pointer;
  383.       typedef const T*        const_pointer;
  384.  
  385.       T*       m_p;
  386.       uint32   m_size;
  387.    };
  388.  
  389.    template<typename T, bool UseConstructor, typename ConstructionPolicy = simple_vector_default_copy_construction_policy<T> >
  390.    struct simple_vector : elemental_vector<T>
  391.    {
  392.       inline simple_vector() { construct(); }
  393.       inline simple_vector(const simple_vector& other, pool_allocator& alloc) { construct(other, alloc); }
  394.            
  395.       // Manual constructor methods
  396.       inline void construct() { m_p = NULL; m_size = 0; }
  397.       inline void construct(uint size, pool_allocator& alloc) { construct(); enlarge(size, alloc, false); }
  398.       inline void construct(const T* p, uint size, pool_allocator& alloc)
  399.       {
  400.          m_size = size;
  401.          m_p = NULL;
  402.          if (size)
  403.          {
  404.             uint num_bytes = sizeof(T) * size;
  405.             m_p = static_cast<T*>(alloc.Alloc(num_bytes));
  406.             if (UseConstructor)
  407.             {
  408.                T* pDst = m_p;
  409.                T* pDst_end = pDst + size;
  410.                const T* pSrc = p;
  411.                while (pDst != pDst_end)
  412.                   ConstructionPolicy::copy_construct(pDst++, *pSrc++, alloc);
  413.             }
  414.             else
  415.                memcpy(m_p, p, num_bytes);
  416.          }
  417.       }
  418.       inline void construct(const simple_vector& other, pool_allocator& alloc)
  419.       {
  420.          construct(other.m_p, other.m_size, alloc);
  421.       }
  422.      
  423.       inline uint size() const { return m_size; }
  424.       inline uint size_in_bytes() const { return m_size * sizeof(T); }
  425.      
  426.       inline const T& operator[] (uint i) const  { PJSON_ASSERT(i < m_size); return m_p[i]; }
  427.       inline       T& operator[] (uint i)        { PJSON_ASSERT(i < m_size); return m_p[i]; }
  428.            
  429.       inline const T* get_ptr() const   { return m_p; }
  430.       inline       T* get_ptr()         { return m_p; }
  431.  
  432.       inline const T* get_ptr(const T* pDef) const   { return m_p ? m_p : pDef; }
  433.       inline       T* get_ptr(T* pDef)               { return m_p ? m_p : pDef; }
  434.  
  435.       inline void clear() { m_p = NULL; m_size = 0; }
  436.                  
  437.       inline void resize(uint new_size, pool_allocator& alloc)
  438.       {
  439.          if (new_size > m_size)
  440.          {
  441.             grow(new_size, alloc);
  442.            
  443.             if (UseConstructor)
  444.                construct_array(m_p + m_size, new_size - m_size);
  445.          }
  446.          
  447.          m_size = new_size;
  448.       }
  449.  
  450.       inline void shrink(uint new_size)
  451.       {
  452.          m_size = new_size;
  453.       }
  454.          
  455.       inline T* enlarge_no_construct(uint n, pool_allocator& alloc)
  456.       {
  457.          PJSON_ASSERT(n);
  458.          uint cur_size = m_size, new_size = m_size + n;
  459.          grow(new_size, alloc);
  460.          m_size = new_size;
  461.          return m_p + cur_size;
  462.       }
  463.  
  464.       inline T* enlarge(uint n, pool_allocator& alloc)
  465.       {
  466.          T* p = enlarge_no_construct(n, alloc);
  467.          if (UseConstructor)
  468.             construct_array(p, n);
  469.          return p;
  470.       }
  471.  
  472.       inline void push_back(const T& obj, pool_allocator& alloc)
  473.       {
  474.          PJSON_ASSERT(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));
  475.          grow(m_size + 1, alloc);
  476.          if (UseConstructor)
  477.             ConstructionPolicy::copy_construct(m_p + m_size, obj, alloc);
  478.          else
  479.             memcpy(m_p + m_size, &obj, sizeof(T));
  480.          m_size++;
  481.       }
  482.  
  483.       inline void push_back(const T* p, uint n, pool_allocator& alloc)
  484.       {
  485.          PJSON_ASSERT(!m_p || ((p + n) <= m_p) || (p >= (m_p + m_size)));
  486.          T* pDst = enlarge_no_construct(n, alloc);
  487.          if (UseConstructor)
  488.          {
  489.             T* pDst_end = pDst + n;
  490.             const T* pSrc = p;
  491.             while (pDst != pDst_end)
  492.                ConstructionPolicy::copy_construct(pDst, *pSrc++, alloc);
  493.          }
  494.          else
  495.             memcpy(pDst, p, sizeof(T) * n);
  496.       }
  497.  
  498.       inline void assign(const T* p, uint n, pool_allocator& alloc)
  499.       {
  500.          PJSON_ASSERT(!m_p || ((p + n) <= m_p) || (p >= (m_p + m_size)));
  501.          
  502.          const uint num_to_assign = PJSON_MIN(m_size, n);
  503.          if (num_to_assign)
  504.          {
  505.             if (UseConstructor)
  506.             {
  507.                for (uint i = 0; i < num_to_assign; ++i)
  508.                   ConstructionPolicy::assign(&m_p[i], p[i], alloc);
  509.             }
  510.             else
  511.                memcpy(m_p, p, sizeof(T) * num_to_assign);
  512.          }
  513.  
  514.          if (n > m_size)
  515.             push_back(p + num_to_assign, n - num_to_assign, alloc);
  516.          else
  517.             shrink(n);
  518.       }
  519.  
  520.       inline void assign(const simple_vector& other, pool_allocator& alloc)
  521.       {
  522.          assign(other.m_p, other.m_size, alloc);
  523.       }
  524.      
  525.       inline void erase(uint start, uint n)
  526.       {
  527.          PJSON_ASSERT((start + n) <= m_size);
  528.          if ((!n) || ((start + n) > m_size))
  529.             return;
  530.  
  531.          const uint num_to_move = m_size - (start + n);
  532.  
  533.          T* pDst = m_p + start;
  534.  
  535.          memmove(pDst, m_p + start + n, num_to_move * sizeof(T));
  536.  
  537.          m_size -= n;
  538.       }
  539.  
  540.       inline void swap(simple_vector& other)
  541.       {
  542.          pjson::swap(m_p, other.m_p);
  543.          pjson::swap(m_size, other.m_size);
  544.       }
  545.      
  546.       inline void grow(uint new_size, pool_allocator& alloc)
  547.       {
  548.          if (new_size > m_size)
  549.             m_p = static_cast<T*>(alloc.Realloc(m_p, sizeof(T) * new_size, m_size * sizeof(T)));
  550.       }
  551.    };
  552.          
  553.    enum json_value_type_t
  554.    {
  555.       cJSONValueTypeNull = 0,
  556.       cJSONValueTypeBool,
  557.       cJSONValueTypeInt,
  558.       cJSONValueTypeDouble,
  559.  
  560.       // All types that follow require storage. Do not change the relative order of these types.
  561.       cJSONValueTypeString,
  562.       cJSONValueTypeArray,
  563.       cJSONValueTypeObject,
  564.    };
  565.    
  566.    // ---- struct value_variant_data
  567.  
  568.    typedef simple_vector<char, false> string_vec_t;
  569.    typedef simple_vector<key_value_t, true, simple_vector_allocator_copy_construction_policy<key_value_t> > key_value_vec_t;
  570.    typedef simple_vector<value_variant, true, simple_vector_allocator_copy_construction_policy<value_variant> > value_variant_vec_t;
  571.          
  572.    #pragma pack(push, 4)
  573.    struct value_variant_data
  574.    {
  575.       union json_value_data_t
  576.       {
  577.          elemental_vector<key_value_vec_t::value_type> m_object;
  578.          elemental_vector<value_variant_vec_t::value_type> m_array;
  579.          elemental_vector<string_vec_t::value_type> m_string;
  580.          int64 m_nVal;
  581.          double m_flVal;
  582.       };
  583.  
  584.       json_value_data_t m_data;
  585.       json_value_type_t m_type;
  586.  
  587.       inline const string_vec_t& get_string() const  { return (const string_vec_t&)m_data.m_string; }
  588.       inline       string_vec_t& get_string()        { return (string_vec_t&)m_data.m_string; }
  589.       inline const char* get_string_ptr() const { return get_string().get_ptr(""); }
  590.  
  591.       inline const value_variant_vec_t& get_array() const    { return (const value_variant_vec_t&)m_data.m_array; }
  592.       inline       value_variant_vec_t& get_array()          { return (value_variant_vec_t&)m_data.m_array; }
  593.  
  594.       inline const key_value_vec_t& get_object() const  { return (const key_value_vec_t&)m_data.m_object; }
  595.       inline       key_value_vec_t& get_object()        { return (key_value_vec_t&)m_data.m_object; }
  596.    };
  597.          
  598.    // ---- struct key_value_t
  599.  
  600.    struct key_value_t
  601.    {
  602.       inline key_value_t() { }
  603.       inline key_value_t(const key_value_t& other, pool_allocator& alloc);
  604.      
  605.       inline void assign(const key_value_t& src, pool_allocator& alloc);
  606.      
  607.       inline const string_vec_t& get_key() const  { return m_key; }
  608.       inline       string_vec_t& get_key()        { return m_key; }
  609.  
  610.       inline const value_variant& get_value() const  { return (const value_variant&)m_value_data; }
  611.       inline       value_variant& get_value()        { return (value_variant&)m_value_data; }
  612.  
  613.       string_vec_t m_key;
  614.       value_variant_data m_value_data;
  615.    };
  616.    #pragma pack(pop)
  617.  
  618.    // ---- class char_vector_print_helper
  619.    
  620.    class char_vector_print_helper
  621.    {
  622.       char_vector_print_helper(const char_vector_print_helper&);
  623.       char_vector_print_helper& operator= (const char_vector_print_helper&);
  624.  
  625.    public:
  626.       inline char_vector_print_helper(char_vec_t& buf) : m_buf(buf) { }
  627.  
  628.       inline void resize(size_t new_size) { m_buf.resize(new_size); }
  629.       inline size_t size() const { return m_buf.size(); }
  630.       inline char* get_ptr() const { return &m_buf[0]; }
  631.      
  632.       inline const char_vec_t& get_buf() const  { return m_buf; }
  633.       inline       char_vec_t& get_buf()        { return m_buf; }
  634.  
  635.       inline void puts(const char* pStr, size_t l) { m_buf.insert(m_buf.end(), pStr, pStr + l); }
  636.       inline void print_tabs(size_t n) { m_buf.insert(m_buf.end(), n, '\t'); }
  637.       inline void print_char(char c) { m_buf.push_back(c); }
  638.  
  639.       void print_escaped(const string_vec_t& str)
  640.       {
  641.          const char* pStr = str.m_p;
  642.          uint len = str.m_size; len;
  643.      
  644.          static const char* s_to_hex = "0123456789abcdef";
  645.          print_char('\"');
  646.          while (*pStr)
  647.          {
  648.             uint8 c = *pStr++;
  649.             if ((c >= ' ') && (c != '\"') && (c != '\\'))
  650.                print_char(c);
  651.             else
  652.             {
  653.                print_char('\\');
  654.                switch (c)
  655.                {
  656.                   case '\b':    print_char('b'); break;
  657.                   case '\r':    print_char('r'); break;
  658.                   case '\t':    print_char('t'); break;
  659.                   case '\f':    print_char('f'); break;
  660.                   case '\n':    print_char('n'); break;
  661.                   case '\\':    print_char('\\'); break;
  662.                   case '\"':    print_char('\"'); break;
  663.                   default: puts("u00", 3); print_char(s_to_hex[c >> 4]); print_char(s_to_hex[c & 0xF]); break;
  664.                }
  665.             }
  666.          }
  667.          print_char('\"');
  668.       }
  669.            
  670.    private:
  671.       char_vec_t& m_buf;
  672.    };
  673.  
  674.    // ---- class char_buf_print_helper
  675.  
  676.    class char_buf_print_helper
  677.    {
  678.       char_buf_print_helper(const char_buf_print_helper&);
  679.       char_buf_print_helper& operator= (const char_buf_print_helper&);
  680.  
  681.    public:
  682.       inline char_buf_print_helper(char* pBuf, size_t buf_size) : m_pDst(pBuf), m_pStart(pBuf), m_pEnd(pBuf + buf_size) { }
  683.  
  684.       inline void resize(size_t new_size) { PJSON_ASSERT(new_size <= (size_t)(m_pEnd - m_pStart)); m_pDst = m_pStart + new_size; }
  685.       inline size_t size() const { return m_pDst - m_pStart; }
  686.       inline char* get_ptr() const { return m_pStart; }
  687.      
  688.       inline void puts(const char* pStr, size_t l) { memcpy(m_pDst, pStr, l = PJSON_MIN(l, (size_t)(m_pEnd - m_pDst))); m_pDst += l; }
  689.       inline void print_tabs(size_t n) { n = PJSON_MIN(n, (size_t)(m_pEnd - m_pDst)); memset(m_pDst, '\t', n); m_pDst += n; }
  690.       inline void print_char(char c) { if (m_pDst < m_pEnd) *m_pDst++ = c; }
  691.  
  692.       void print_escaped(const string_vec_t& str)
  693.       {
  694.          static const char* s_to_hex = "0123456789abcdef";
  695.  
  696.          const char* pStr = str.m_p;
  697.          char* pDst = m_pDst;
  698.          char* pEnd = m_pEnd;
  699.          uint len = str.m_size;
  700.          
  701.          // If len!=0, it includes the terminating null, so this expression is conservative.
  702.          if (static_cast<size_t>(pEnd - pDst) < (len + 2)) { m_pDst = pEnd; return; }
  703.                                    
  704.          *pDst++ = '\"';
  705.  
  706.          uint8 c = 0; if (pStr) c = pStr[0];
  707.          while (!globals::s_str_serialize_flags[c])
  708.          {
  709.             pDst[0] = c; c = pStr[1]; if (globals::s_str_serialize_flags[c]) { ++pStr, ++pDst; break; }
  710.             pDst[1] = c; c = pStr[2]; if (globals::s_str_serialize_flags[c]) { pStr += 2, pDst += 2; break; }
  711.             pDst[2] = c; c = pStr[3]; if (globals::s_str_serialize_flags[c]) { pStr += 3, pDst += 3; break; }
  712.             pDst[3] = c; c = pStr[4]; pStr += 4, pDst += 4;
  713.          }
  714.          
  715.          while (c)
  716.          {
  717.             if ((pEnd - pDst) < 7)
  718.             {
  719.                m_pDst = pEnd;
  720.                return;
  721.             }
  722.             if (!globals::s_str_serialize_flags[c])
  723.                *pDst++ = c;
  724.             else
  725.             {
  726.                pDst[0] = '\\';
  727.                switch (c)
  728.                {
  729.                   case '\b':    pDst[1] = 'b'; break;
  730.                   case '\r':    pDst[1] = 'r'; break;
  731.                   case '\t':    pDst[1] = 't'; break;
  732.                   case '\f':    pDst[1] = 'f'; break;
  733.                   case '\n':    pDst[1] = 'n'; break;
  734.                   case '\\':    pDst[1] = '\\'; break;
  735.                   case '\"':    pDst[1] = '\"'; break;
  736.                   default: pDst[1] = 'u', pDst[2] = '0', pDst[3] = '0', pDst[4] = s_to_hex[c >> 4], pDst[5] = s_to_hex[c & 0xF]; pDst += 3; break;
  737.                }
  738.                pDst += 2;
  739.             }
  740.             c = *pStr++;
  741.          }
  742.  
  743.          *pDst++ = '\"';
  744.          PJSON_ASSERT(pDst <= pEnd);
  745.          m_pDst = pDst;
  746.       }
  747.  
  748.    private:
  749.       char* m_pDst, *m_pStart, *m_pEnd;
  750.    };
  751.  
  752.    // ---- class serialize_helper
  753.  
  754.    template<typename T>
  755.    class serialize_helper : public T
  756.    {
  757.    public:
  758.       typedef T base;
  759.  
  760.       template<typename I> inline serialize_helper(I& init) : T(init) { }
  761.       template<typename I, typename J> inline serialize_helper(I& init1, J& init2) : T(init1, init2) { }
  762.  
  763.       inline void puts(const char* pStr) { T::puts(pStr, strlen(pStr)); }
  764.       inline void puts(const char* pStr, size_t l) { T::puts(pStr, l); }
  765.    };
  766.  
  767.    // ---- class value_variant
  768.    
  769.    #pragma pack(push, 4)
  770.    class value_variant : public value_variant_data
  771.    {
  772.       friend document;
  773.       friend key_value_t;
  774.  
  775.       value_variant(const value_variant&);
  776.       value_variant& operator= (const value_variant&);
  777.  
  778.    public:
  779.       inline value_variant() { m_type = cJSONValueTypeNull; m_data.m_nVal = 0; }
  780.       inline value_variant(bool val) { m_type = cJSONValueTypeBool; m_data.m_nVal = val; }
  781.       inline value_variant(int32 nVal) { m_type = cJSONValueTypeInt; m_data.m_nVal = nVal; }
  782.       inline value_variant(uint32 nVal) { m_type = cJSONValueTypeInt; m_data.m_nVal = nVal; }
  783.       inline value_variant(int64 nVal) { m_type = cJSONValueTypeInt; m_data.m_nVal = nVal; }
  784.       inline value_variant(double flVal) { m_type = cJSONValueTypeDouble; m_data.m_flVal = flVal; }
  785.      
  786.       inline value_variant(const char* pStr, pool_allocator& alloc)
  787.       {
  788.          m_type = cJSONValueTypeString;
  789.          if (!pStr) pStr = "";
  790.          get_string().construct(pStr, static_cast<uint>(strlen(pStr)) + 1, alloc);
  791.       }
  792.  
  793.       inline value_variant(json_value_type_t type)
  794.       {
  795.          construct(type);
  796.       }
  797.  
  798.       inline value_variant(const value_variant& other, pool_allocator& alloc)
  799.       {
  800.          construct(other, alloc);
  801.       }
  802.  
  803.       inline value_variant &assign(const value_variant& rhs, pool_allocator& alloc)
  804.       {
  805.          if (this == &rhs)
  806.             return *this;
  807.          if ((m_type >= cJSONValueTypeString) && (m_type == rhs.m_type))
  808.          {
  809.             if (is_string())
  810.                get_string().assign(rhs.get_string(), alloc);
  811.             else if (is_object())
  812.                get_object().assign(rhs.get_object(), alloc);
  813.             else
  814.                get_array().assign(rhs.get_array(), alloc);
  815.          }
  816.          else
  817.          {
  818.             construct(rhs, alloc);
  819.          }
  820.          return *this;
  821.       }
  822.  
  823.       inline json_value_type_t get_type() const { return m_type; }
  824.  
  825.       inline bool is_null() const { return m_type == cJSONValueTypeNull; }
  826.       inline bool is_valid() const { return m_type != cJSONValueTypeNull; }
  827.       inline bool is_bool() const { return m_type == cJSONValueTypeBool; }
  828.       inline bool is_int() const { return m_type == cJSONValueTypeInt; }
  829.       inline bool is_double() const { return m_type == cJSONValueTypeDouble; }
  830.       inline bool is_numeric() const { return (m_type == cJSONValueTypeInt) || (m_type == cJSONValueTypeDouble); }
  831.       inline bool is_string() const { return m_type == cJSONValueTypeString; }
  832.       inline bool is_object_or_array() const { return m_type >= cJSONValueTypeArray; }
  833.       inline bool is_object() const { return m_type == cJSONValueTypeObject; }
  834.       inline bool is_array() const { return m_type == cJSONValueTypeArray; }
  835.            
  836.       inline void clear() { set_to_null(); }
  837.  
  838.       inline void assume_ownership(value_variant& src_val) { set_to_null(); swap(src_val); }
  839.       inline void release_ownership(value_variant& dst_value) { dst_value.set_to_null(); dst_value.swap(*this); }
  840.  
  841.       inline value_variant& set_to_object() { construct(cJSONValueTypeObject); return *this; }
  842.       inline value_variant& set_to_array() { construct(cJSONValueTypeArray); return *this; }
  843.       inline value_variant& set_to_node(bool is_object) { construct(is_object ? cJSONValueTypeObject : cJSONValueTypeArray); return *this; }
  844.  
  845.       inline value_variant& set_to_null() { m_data.m_nVal = 0; m_type = cJSONValueTypeNull; return *this; }
  846.       inline value_variant& set(bool val) { m_data.m_nVal = val; m_type = cJSONValueTypeBool; return *this; }
  847.       inline value_variant& set(int32 nVal) { m_data.m_nVal = nVal; m_type = cJSONValueTypeInt; return *this; }
  848.       inline value_variant& set(int64 nVal) { m_data.m_nVal = nVal; m_type = cJSONValueTypeInt; return *this; }
  849.       inline value_variant& set(uint32 nVal) { set(static_cast<int64>(nVal)); return *this; }
  850.       inline value_variant& set(double flVal) { m_data.m_flVal = flVal; m_type = cJSONValueTypeDouble; return *this; }
  851.      
  852.       inline value_variant& set(const char* pStr, pool_allocator& alloc)
  853.       {
  854.          if (!pStr) pStr = "";
  855.          uint l = static_cast<uint>(strlen(pStr)) + 1;
  856.          if (!is_string())
  857.          {
  858.             m_type = cJSONValueTypeString;
  859.             get_string().construct(pStr, l, alloc);
  860.          }
  861.          else
  862.             get_string().assign(pStr, l, alloc);
  863.          return *this;
  864.       }
  865.  
  866.       inline value_variant& set_assume_ownership(char* pStr, uint len)
  867.       {
  868.          m_type = cJSONValueTypeString;
  869.          string_vec_t& str = get_string();
  870.          str.m_p = pStr;
  871.          str.m_size = len;
  872.          return *this;
  873.       }
  874.  
  875.       inline value_variant& set(const value_variant* pVals, uint n, pool_allocator& alloc)
  876.       {
  877.          if (!is_array())
  878.          {
  879.             m_type = cJSONValueTypeArray;
  880.             get_array().construct(pVals, n, alloc);
  881.          }
  882.          else
  883.             get_array().assign(pVals, n, alloc);
  884.          return *this;
  885.       }
  886.  
  887.       inline value_variant& set_assume_ownership(value_variant* pVals, uint n)
  888.       {
  889.          m_type = cJSONValueTypeArray;
  890.          value_variant_vec_t& arr = get_array();
  891.          arr.m_p = pVals;
  892.          arr.m_size = n;
  893.          return *this;
  894.       }
  895.  
  896.       inline value_variant& set(const key_value_t* pKey_values, uint n, pool_allocator& alloc)
  897.       {
  898.          if (!is_object())
  899.          {
  900.             m_type = cJSONValueTypeObject;
  901.             get_object().construct(pKey_values, n, alloc);
  902.          }
  903.          else
  904.             get_object().assign(pKey_values, n, alloc);
  905.          return *this;
  906.       }
  907.  
  908.       inline value_variant& set_assume_ownership(key_value_t* pKey_values, uint n)
  909.       {
  910.          m_type = cJSONValueTypeObject;
  911.          key_value_vec_t& obj = get_object();
  912.          obj.m_p = pKey_values;
  913.          obj.m_size = n;
  914.          return *this;
  915.       }
  916.  
  917.       inline value_variant &operator=(bool val) { set(val); return *this; }
  918.       inline value_variant &operator=(int32 nVal) { set(nVal); return *this; }
  919.       inline value_variant &operator=(uint32 nVal) { set(nVal); return *this; }
  920.       inline value_variant &operator=(int64 nVal) { set(nVal); return *this; }
  921.       inline value_variant &operator=(double flVal) { set(flVal); return *this; }
  922.  
  923.       inline bool get_bool_value(bool& val, bool def = false) const { if (is_bool()) { val = (m_data.m_nVal != 0); return true; } else return convert_to_bool(val, def); }
  924.       inline bool get_numeric_value(int32& val, int32 def = 0) const { if ((is_int()) && (m_data.m_nVal == static_cast<int32>(m_data.m_nVal))) { val = static_cast<int32>(m_data.m_nVal); return true; } else return convert_to_int32(val, def); }
  925.       inline bool get_numeric_value(int64& val, int64 def = 0) const { if (is_int()) { val = m_data.m_nVal; return true; } else return convert_to_int64(val, def); }
  926.       inline bool get_numeric_value(float& val, float def = 0.0f) const { if (is_double()) { val = static_cast<float>(m_data.m_flVal); return true; } else return convert_to_float(val, def); }
  927.       inline bool get_numeric_value(double& val, double def = 0.0f) const { if (is_double()) { val = m_data.m_flVal; return true; } else return convert_to_double(val, def); }
  928.       inline bool get_string_value(string_t& val, const char* pDef = "") const { if (is_string()) { val = get_string_ptr(); return true; } else return convert_to_string(val, pDef); }
  929.      
  930.       inline bool as_bool(bool def = false) const { bool result; get_bool_value(result, def); return result; }
  931.       inline int as_int32(int32 def = 0) const { int32 result; get_numeric_value(result, def); return result; }
  932.       inline int64 as_int64(int64 def = 0) const { int64 result; get_numeric_value(result, def); return result; }
  933.       inline float as_float(float def = 0.0f) const { float result; get_numeric_value(result, def); return result; }
  934.       inline double as_double(double def = 0.0f) const { double result; get_numeric_value(result, def); return result; }
  935.  
  936.       // Returns value as a string, or the default string if the value cannot be converted.
  937.       inline string_t as_string(const char* pDef = "") const { string_t result; get_string_value(result, pDef); return result; }
  938.  
  939.       // Returns pointer to null terminated string or NULL if the value is not a string.
  940.       inline const char* as_string_ptr() const { return is_string() ? get_string_ptr() : NULL; }
  941.  
  942.       inline void swap(value_variant& other)
  943.       {
  944.          pjson::swap(m_type, other.m_type);
  945.          get_object().swap(other.get_object());
  946.       }
  947.  
  948.       inline uint size() const { PJSON_ASSERT(is_object_or_array()); return is_object_or_array() ? get_array().size() : 0; }
  949.  
  950.       inline const char *get_key_name_at_index(uint index) const { PJSON_ASSERT(is_object()); return get_object()[index].get_key().get_ptr(""); }
  951.  
  952.       inline const value_variant *find_child_array(const char *pName) const
  953.       {
  954.          int index = find_key(pName);
  955.          if ((index >= 0) && (get_object()[index].get_value().is_array()))
  956.             return &get_object()[index].get_value();
  957.          return NULL;
  958.       }
  959.  
  960.       inline const value_variant *find_child_object(const char *pName) const
  961.       {
  962.          int index = find_key(pName);
  963.          if ((index >= 0) && (get_object()[index].get_value().is_object()))
  964.             return &get_object()[index].get_value();
  965.          return NULL;
  966.       }
  967.  
  968.       inline const value_variant *find_value_variant(const char *pName) const
  969.       {
  970.          int index = find_key(pName);
  971.          return (index < 0) ? NULL : &get_object()[index].get_value();
  972.       }
  973.  
  974.       inline int find_key(const char *pName) const
  975.       {
  976.          if (!is_object())
  977.          {
  978.             PJSON_ASSERT(0);
  979.             return -1;
  980.          }
  981.          
  982.          const uint n = get_array().size();
  983.          const key_value_vec_t &obj = get_object();
  984.  
  985.          for (uint i = 0; i < n; i++)
  986.             if (strcmp(pName, obj[i].get_key().get_ptr("")) == 0)
  987.                return i;
  988.  
  989.          return -1;
  990.       }
  991.  
  992.       inline bool has_key(const char *pName) const
  993.       {
  994.          return find_key(pName) >= 0;
  995.       }
  996.  
  997.       inline bool as_bool(const char *pName, bool def = false) const
  998.       {
  999.          int index = find_key(pName);
  1000.          return (index < 0) ? def : get_object()[index].get_value().as_bool(def);
  1001.       }
  1002.      
  1003.       inline int as_int32(const char *pName, int32 def = 0) const
  1004.       {  
  1005.          int index = find_key(pName);
  1006.          return (index < 0) ? def : get_object()[index].get_value().as_int32(def);
  1007.       }
  1008.      
  1009.       inline int64 as_int64(const char *pName, int64 def = 0) const
  1010.       {
  1011.          int index = find_key(pName);
  1012.          return (index < 0) ? def : get_object()[index].get_value().as_int64(def);
  1013.       }
  1014.      
  1015.       inline float as_float(const char *pName, float def = 0.0f) const
  1016.       {
  1017.          int index = find_key(pName);
  1018.          return (index < 0) ? def : get_object()[index].get_value().as_float(def);
  1019.       }
  1020.  
  1021.       inline double as_double(const char *pName, double def = 0.0f) const
  1022.       {
  1023.          int index = find_key(pName);
  1024.          return (index < 0) ? def : get_object()[index].get_value().as_double(def);
  1025.       }
  1026.      
  1027.       inline const char* as_string_ptr(const char *pName, const char *pDef = "") const
  1028.       {
  1029.          int index = find_key(pName);
  1030.          if (index < 0)
  1031.             return pDef;
  1032.          const char *p = get_object()[index].get_value().as_string_ptr();
  1033.          return p ? p : pDef;
  1034.       }
  1035.      
  1036.       inline       value_variant& get_value_at_index(uint index)        { PJSON_ASSERT(is_object_or_array()); return is_object() ? get_object()[index].get_value() : get_array()[index]; }
  1037.       inline const value_variant& get_value_at_index(uint index) const  { PJSON_ASSERT(is_object_or_array()); return is_object() ? get_object()[index].get_value() : get_array()[index]; }
  1038.  
  1039.       inline       value_variant& operator[](uint index)        { PJSON_ASSERT(is_object_or_array()); return is_object() ? get_object()[index].get_value() : get_array()[index]; }
  1040.       inline const value_variant& operator[](uint index) const  { PJSON_ASSERT(is_object_or_array()); return is_object() ? get_object()[index].get_value() : get_array()[index]; }
  1041.  
  1042.       inline json_value_type_t get_value_type_at_index(uint index) const { return get_value_at_index(index).get_type(); }
  1043.  
  1044.       inline bool is_child_at_index(uint index) const { return get_value_type_at_index(index) >= cJSONValueTypeArray; }
  1045.      
  1046.       inline bool has_children() const
  1047.       {
  1048.          if (is_object())
  1049.          {
  1050.             const key_value_vec_t& obj = get_object();
  1051.             const uint s = obj.size();
  1052.             for (uint i = 0; i < s; ++i)
  1053.                if (obj[i].get_value().is_object_or_array())
  1054.                   return true;
  1055.          }
  1056.          else if (is_array())
  1057.          {
  1058.             const value_variant_vec_t& arr = get_array();
  1059.             const uint s = arr.size();
  1060.             for (uint i = 0; i < s; ++i)
  1061.                if (arr[i].is_object_or_array())
  1062.                   return true;
  1063.          }
  1064.          return false;
  1065.       }
  1066.      
  1067.       inline void clear_object_or_array()
  1068.       {
  1069.          PJSON_ASSERT(is_object_or_array());
  1070.          if (is_object())
  1071.             get_object().clear();
  1072.          else if (is_array())
  1073.             get_array().clear();
  1074.       }
  1075.  
  1076.       inline void resize(uint n, pool_allocator& alloc)
  1077.       {
  1078.          PJSON_ASSERT(is_object_or_array());
  1079.          if (is_object())
  1080.             get_object().resize(n, alloc);
  1081.          else if (is_array())
  1082.             get_array().resize(n, alloc);
  1083.       }
  1084.  
  1085.       inline void set_key_name_at_index(uint index, const char *pKey, uint key_len, pool_allocator& alloc)
  1086.       {
  1087.          PJSON_ASSERT(is_object());
  1088.          string_vec_t& str = get_object()[index].get_key();
  1089.          str.assign(pKey, key_len + 1, alloc);
  1090.       }
  1091.  
  1092.       inline void set_key_name_at_index(uint index, const char *pKey, pool_allocator& alloc)
  1093.       {
  1094.          set_key_name_at_index(index, pKey, static_cast<uint>(strlen(pKey)) + 1, alloc);
  1095.       }
  1096.      
  1097.       inline value_variant& add_key_value(const char* pKey, uint key_len, const value_variant& val, pool_allocator& alloc)
  1098.       {
  1099.          PJSON_ASSERT(is_object());
  1100.          key_value_vec_t& obj = get_object();
  1101.          key_value_t* pKey_value = obj.enlarge_no_construct(1, alloc);
  1102.          pKey_value->get_key().construct(pKey, key_len + 1, alloc);
  1103.          pKey_value->get_value().construct(val, alloc);
  1104.          return *this;
  1105.       }
  1106.  
  1107.       inline value_variant& add_key_value(const char* pKey, const value_variant& val, pool_allocator& alloc)
  1108.       {
  1109.          return add_key_value(pKey, static_cast<uint>(strlen(pKey)), val, alloc);
  1110.       }
  1111.  
  1112.       inline value_variant& add_value(const value_variant& val, pool_allocator& alloc)
  1113.       {
  1114.          PJSON_ASSERT(is_array());
  1115.          get_array().enlarge_no_construct(1, alloc)->construct(val, alloc);
  1116.          return *this;
  1117.       }
  1118.      
  1119.       bool serialize(char* pBuf, size_t buf_size, size_t* pSize = NULL, bool formatted = true, bool null_terminate = true) const
  1120.       {
  1121.          serialize_helper<char_buf_print_helper> helper(pBuf, buf_size);
  1122.          serialize_internal(helper, formatted, null_terminate, 0);
  1123.          if (pSize)
  1124.             *pSize = helper.size();
  1125.          return (helper.size() < buf_size);
  1126.       }
  1127.  
  1128.       bool serialize(char_vec_t& buf, bool formatted = true, bool null_terminate = true) const
  1129.       {
  1130.          serialize_helper<char_vector_print_helper> helper(buf);
  1131.          serialize_internal(helper, formatted, null_terminate, 0);
  1132.          return true;
  1133.       }
  1134.      
  1135.    protected:
  1136.       // Manual constructor
  1137.       inline void construct(json_value_type_t type)
  1138.       {
  1139.          m_type = type;
  1140.          memset(&m_data, 0, sizeof(m_data));
  1141.       }
  1142.  
  1143.       // Assumes variant has NOT been constructed yet.
  1144.       inline void construct(const value_variant& other, pool_allocator& alloc)
  1145.       {
  1146.          m_type = other.m_type;
  1147.          m_data.m_nVal = other.m_data.m_nVal;
  1148.          if (m_type >= cJSONValueTypeString)
  1149.          {
  1150.             if (m_type == cJSONValueTypeObject)
  1151.                get_object().construct(other.get_object(), alloc);
  1152.             else if (m_type == cJSONValueTypeArray)
  1153.                get_array().construct(other.get_array(), alloc);
  1154.             else
  1155.                get_string().construct(other.get_string(), alloc);
  1156.          }
  1157.       }
  1158.  
  1159.       inline bool convert_to_bool(bool& val, bool def) const
  1160.       {
  1161.          switch (m_type)
  1162.          {
  1163.             case cJSONValueTypeBool:
  1164.             case cJSONValueTypeInt:
  1165.             {
  1166.                val = (m_data.m_nVal != 0);
  1167.                return true;
  1168.             }
  1169.             case cJSONValueTypeDouble:
  1170.             {
  1171.                val = (m_data.m_flVal != 0);
  1172.                return true;
  1173.             }
  1174.             case cJSONValueTypeString:
  1175.             {
  1176.                if (!pjson_stricmp(get_string_ptr(), "false"))
  1177.                {
  1178.                   val = false;
  1179.                   return true;
  1180.                }
  1181.                else if (!pjson_stricmp(get_string_ptr(), "true"))
  1182.                {
  1183.                   val = true;
  1184.                   return true;
  1185.                }
  1186.                val = (atof(get_string_ptr()) != 0.0f);
  1187.                return true;
  1188.             }
  1189.          }
  1190.          val = def;
  1191.          return false;
  1192.       }
  1193.  
  1194.       inline bool convert_to_int32(int32& val, int32 def) const
  1195.       {
  1196.          val = def;
  1197.          int64 val64;
  1198.          if (!convert_to_int64(val64, def))
  1199.             return false;
  1200.          if ((val64 < std::numeric_limits<int32>::min()) || (val64 > std::numeric_limits<int32>::max()))
  1201.             return false;
  1202.          val = static_cast<int32>(val64);
  1203.          return true;
  1204.       }
  1205.  
  1206.       inline bool convert_to_int64(int64& val, int64 def) const
  1207.       {
  1208.          switch (m_type)
  1209.          {
  1210.             case cJSONValueTypeBool:
  1211.             case cJSONValueTypeInt:
  1212.             {
  1213.                val = m_data.m_nVal;
  1214.                return true;
  1215.             }
  1216.             case cJSONValueTypeDouble:
  1217.             {
  1218.                val = static_cast<int64>(m_data.m_flVal);
  1219.                return true;
  1220.             }
  1221.             case cJSONValueTypeString:
  1222.             {
  1223.                if (!pjson_stricmp(get_string_ptr(), "false"))
  1224.                {
  1225.                   val = 0;
  1226.                   return true;
  1227.                }
  1228.                else if (!pjson_stricmp(get_string_ptr(), "true"))
  1229.                {
  1230.                   val = 1;
  1231.                   return true;
  1232.                }
  1233.                double flVal = floor(atof(get_string_ptr()));
  1234.                if ((flVal >= std::numeric_limits<int64>::min()) && (flVal <= std::numeric_limits<int64>::max()))
  1235.                {
  1236.                   val = static_cast<int64>(flVal);
  1237.                   return true;
  1238.                }
  1239.                break;
  1240.             }
  1241.          }
  1242.          val = def;
  1243.          return false;
  1244.       }
  1245.  
  1246.       inline bool convert_to_float(float& val, float def) const
  1247.       {
  1248.          switch (m_type)
  1249.          {
  1250.             case cJSONValueTypeBool:
  1251.             case cJSONValueTypeInt:
  1252.             {
  1253.                val = static_cast<float>(m_data.m_nVal);
  1254.                return true;
  1255.             }
  1256.             case cJSONValueTypeDouble:
  1257.             {
  1258.                val = static_cast<float>(m_data.m_flVal);
  1259.                return true;
  1260.             }
  1261.             case cJSONValueTypeString:
  1262.             {
  1263.                if (!pjson_stricmp(get_string_ptr(), "false"))
  1264.                {
  1265.                   val = 0;
  1266.                   return true;
  1267.                }
  1268.                else if (!pjson_stricmp(get_string_ptr(), "true"))
  1269.                {
  1270.                   val = 1;
  1271.                   return true;
  1272.                }
  1273.                val = static_cast<float>(atof(get_string_ptr()));
  1274.                return true;
  1275.             }
  1276.          }
  1277.          val = def;
  1278.          return false;
  1279.       }
  1280.  
  1281.       inline bool convert_to_double(double& val, double def) const
  1282.       {
  1283.          switch (m_type)
  1284.          {
  1285.             case cJSONValueTypeBool:
  1286.             case cJSONValueTypeInt:
  1287.             {
  1288.                val = static_cast<double>(m_data.m_nVal);
  1289.                return true;
  1290.             }
  1291.             case cJSONValueTypeDouble:
  1292.             {
  1293.                val = m_data.m_flVal;
  1294.                return true;
  1295.             }
  1296.             case cJSONValueTypeString:
  1297.             {
  1298.                if (!pjson_stricmp(get_string_ptr(), "false"))
  1299.                {
  1300.                   val = 0;
  1301.                   return true;
  1302.                }
  1303.                else if (!pjson_stricmp(get_string_ptr(), "true"))
  1304.                {
  1305.                   val = 1;
  1306.                   return true;
  1307.                }
  1308.                val = atof(get_string_ptr());
  1309.                return true;
  1310.             }
  1311.          }
  1312.          val = def;
  1313.          return false;
  1314.       }
  1315.      
  1316.       inline bool convert_to_string(char* pBuf, size_t buf_size) const
  1317.       {
  1318.          switch (m_type)
  1319.          {
  1320.             case cJSONValueTypeNull:
  1321.             {
  1322.                pBuf[0] = 'n', pBuf[1] = 'u', pBuf[2] = 'l', pBuf[3] = 'l', pBuf[4] = '\0';
  1323.                return true;
  1324.             }
  1325.             case cJSONValueTypeBool:
  1326.             {
  1327.                if (m_data.m_nVal)
  1328.                   pBuf[0] = 't', pBuf[1] = 'r', pBuf[2] = 'u', pBuf[3] = 'e', pBuf[4] = '\0';
  1329.                else
  1330.                   pBuf[0] = 'f', pBuf[1] = 'a', pBuf[2] = 'l', pBuf[3] = 's', pBuf[4] = 'e', pBuf[5] = '\0';
  1331.                return true;
  1332.             }
  1333.             case cJSONValueTypeInt:
  1334.             {
  1335.                char* pDst = pBuf;
  1336.                int64 n = m_data.m_nVal;
  1337.                
  1338.                uint64 s = static_cast<uint64>(n >> 63);
  1339.                *pDst = '-';
  1340.                pDst -= s;
  1341.                n = (n ^ s) - s;
  1342.                
  1343.                char* pLeft = pDst;
  1344.  
  1345.                do
  1346.                {
  1347.                   *pDst++ = '0' + (n % 10);
  1348.                   n /= 10;
  1349.                } while (n);
  1350.                
  1351.                *pDst = '\0';
  1352.                              
  1353.                do
  1354.                {
  1355.                   char c = *--pDst;
  1356.                   *pDst = *pLeft;
  1357.                   *pLeft++ = c;
  1358.                } while (pDst > pLeft);
  1359.                return true;
  1360.             }
  1361.             case cJSONValueTypeDouble:
  1362.             {
  1363.                return 0 == _gcvt_s(pBuf, buf_size, m_data.m_flVal, 15);
  1364.             }
  1365.          }
  1366.          return false;
  1367.       }
  1368.  
  1369.       inline bool convert_to_string(string_t& val, const char* pDef) const
  1370.       {
  1371.          char buf[64];
  1372.          if (m_type == cJSONValueTypeString)
  1373.             val = get_string_ptr();
  1374.          else
  1375.          {
  1376.             if (!convert_to_string(buf, sizeof(buf)))
  1377.             {
  1378.                val.assign(pDef);
  1379.                return false;
  1380.             }
  1381.             val.assign(buf);
  1382.          }
  1383.          return true;
  1384.       }
  1385.  
  1386.       inline uint8 get_end_char() const { return (m_type == cJSONValueTypeArray) ? ']' : '}'; }
  1387.  
  1388.       template<typename serializer>
  1389.       void serialize_node(serializer& out, bool formatted, uint cur_indent) const
  1390.       {
  1391.          char buf[64];
  1392.          const uint size = get_array().size();
  1393.          
  1394.          if (!size)
  1395.          {
  1396.             static const char* g_empty_object_strs[4] = { "[]", "[ ]", "{}", "{ }" };
  1397.             out.puts(g_empty_object_strs[is_object() * 2 + formatted], 2 + formatted);
  1398.             return;
  1399.          }
  1400.  
  1401.          if (formatted && is_array() && !has_children())
  1402.          {
  1403.             size_t start_of_line_ofs = out.size();
  1404.             out.puts("[ ", 2);
  1405.  
  1406.             const uint cMaxLineLen = 100;
  1407.            
  1408.             for (uint i = 0; i < size; i++)
  1409.             {
  1410.                const value_variant& child_val = get_value_at_index(i);
  1411.                if (child_val.is_string())
  1412.                   out.print_escaped(child_val.get_string());
  1413.                else
  1414.                {
  1415.                   child_val.convert_to_string(buf, sizeof(buf));
  1416.                   out.puts(buf);
  1417.                }
  1418.  
  1419.                if (i != size - 1)
  1420.                   out.puts(", ", 2);
  1421.  
  1422.                if (((out.size() - start_of_line_ofs) > cMaxLineLen) && (i != size - 1))
  1423.                {
  1424.                   out.print_char('\n');
  1425.                   out.print_tabs(cur_indent + 1);
  1426.  
  1427.                   start_of_line_ofs = out.size();
  1428.                }
  1429.             }
  1430.  
  1431.             out.puts(" ]", 2);
  1432.             return;
  1433.          }
  1434.  
  1435.          out.print_char(is_object() ? '{' : '[');
  1436.          if (formatted)
  1437.             out.print_char('\n');
  1438.  
  1439.          cur_indent++;
  1440.  
  1441.          for (uint i = 0; i < size; i++)
  1442.          {
  1443.             const value_variant& child_val = get_value_at_index(i);
  1444.  
  1445.             if (formatted)
  1446.                out.print_tabs(cur_indent);
  1447.  
  1448.             if (is_object())
  1449.             {
  1450.                out.print_escaped(get_object()[i].get_key());
  1451.                if (formatted)
  1452.                   out.puts(" : ", 3);
  1453.                else
  1454.                   out.print_char(':');
  1455.             }
  1456.  
  1457.             json_value_type_t val_type = child_val.get_type();
  1458.             if (val_type >= cJSONValueTypeArray)
  1459.                child_val.serialize_node(out, formatted, cur_indent);
  1460.             else if (val_type == cJSONValueTypeString)
  1461.                out.print_escaped(child_val.get_string());
  1462.             else
  1463.             {
  1464.                child_val.convert_to_string(buf, sizeof(buf));
  1465.                out.puts(buf);
  1466.             }
  1467.  
  1468.             if (i != size - 1)
  1469.                out.print_char(',');
  1470.             if (formatted)
  1471.                out.print_char('\n');
  1472.          }
  1473.  
  1474.          cur_indent--;
  1475.  
  1476.          if (formatted)
  1477.             out.print_tabs(cur_indent);
  1478.          out.print_char(is_object() ? '}' : ']');
  1479.       }
  1480.  
  1481.       template<typename serializer>
  1482.       void serialize_internal(serializer& out, bool formatted, bool null_terminate, uint cur_indent) const
  1483.       {
  1484.          if (formatted)
  1485.             out.print_tabs(cur_indent);
  1486.          if (is_object_or_array())
  1487.          {
  1488.             serialize_node(out, formatted, cur_indent);
  1489.             if (formatted)
  1490.                out.print_char('\n');
  1491.          }
  1492.          else
  1493.          {
  1494.             if (is_string())
  1495.                out.print_escaped(get_string());
  1496.             else
  1497.             {
  1498.                string_t str;
  1499.                if (get_string_value(str))
  1500.                   out.puts(str.c_str(), str.length());
  1501.             }
  1502.          }
  1503.          if (null_terminate)
  1504.             out.print_char('\0');
  1505.       }
  1506.      
  1507.       template<typename T> value_variant(T*);
  1508.       template<typename T> value_variant(const T*);
  1509.       template<typename T> value_variant& operator= (T*);
  1510.       template<typename T> value_variant& operator= (const T*);
  1511.    };
  1512.    #pragma pack(pop)
  1513.  
  1514.    inline key_value_t::key_value_t(const key_value_t& other, pool_allocator& alloc) :
  1515.       m_key(other.get_key(), alloc)
  1516.    {
  1517.       get_value().construct(other.get_value(), alloc);
  1518.    }
  1519.  
  1520.    inline void key_value_t::assign(const key_value_t& src, pool_allocator& alloc)
  1521.    {
  1522.       get_key().assign(src.get_key(), alloc);
  1523.       get_value().assign(src.get_value(), alloc);
  1524.    }
  1525.  
  1526.    // ---- class error_info
  1527.    
  1528.    class error_info
  1529.    {
  1530.    public:
  1531.       inline error_info() : m_ofs(0), m_pError_message(NULL) { }
  1532.       inline void set(size_t ofs, const char* pMsg) { m_ofs = ofs; m_pError_message = pMsg; }
  1533.  
  1534.       size_t m_ofs;
  1535.       const char* m_pError_message;
  1536.    };
  1537.  
  1538.    // ---- class growable_stack
  1539.      
  1540.    class growable_stack
  1541.    {
  1542.    public:
  1543.       inline growable_stack(uint initial_size) :
  1544.          m_pBuf(NULL),
  1545.          m_size(initial_size),
  1546.          m_ofs(0)
  1547.       {
  1548.          if (initial_size)
  1549.             m_pBuf = static_cast<uint8*>(pjson_malloc(initial_size));
  1550.       }
  1551.  
  1552.       inline ~growable_stack()
  1553.       {
  1554.          pjson_free(m_pBuf);
  1555.       }
  1556.  
  1557.       inline void clear()
  1558.       {
  1559.          pjson_free(m_pBuf);
  1560.          m_pBuf = NULL;
  1561.          m_size = 0;
  1562.          m_ofs = 0;
  1563.       }
  1564.  
  1565.       inline uint8* get_top_ptr() { return reinterpret_cast<uint8*>(m_pBuf) + m_ofs; }
  1566.  
  1567.       template<typename T> inline T* get_top_obj() { return reinterpret_cast<T*>(m_pBuf + m_ofs - sizeof(T)); }
  1568.  
  1569.       inline void reset() { m_ofs = 0; }
  1570.  
  1571.       inline size_t get_ofs() { return m_ofs; }
  1572.  
  1573.       template<typename T>
  1574.       PJSON_FORCEINLINE T* push(uint num)
  1575.       {
  1576.          const size_t bytes_needed = sizeof(T) * num;
  1577.          T* pResult = reinterpret_cast<T*>(m_pBuf + m_ofs);
  1578.          m_ofs += bytes_needed;
  1579.          
  1580.          if (m_ofs > m_size)
  1581.          {
  1582.             m_ofs -= bytes_needed;
  1583.            
  1584.             m_size = PJSON_MAX(1, m_size * 2);
  1585.             while(m_size <= (m_ofs + bytes_needed))
  1586.                m_size *= 2;
  1587.             m_pBuf = static_cast<uint8*>(pjson_realloc(m_pBuf, m_size));
  1588.  
  1589.             pResult = reinterpret_cast<T*>(m_pBuf + m_ofs);
  1590.             m_ofs += bytes_needed;
  1591.          }
  1592.          
  1593.          PJSON_ASSERT(m_ofs <= m_size);
  1594.          return pResult;
  1595.       }
  1596.  
  1597.       template<typename T>
  1598.       inline T* pop(uint num)
  1599.       {
  1600.          size_t bytes_needed = sizeof(T) * num;
  1601.          PJSON_ASSERT(bytes_needed <= m_ofs);
  1602.          m_ofs -= bytes_needed;
  1603.          return reinterpret_cast<T*>(m_pBuf + m_ofs);
  1604.       }
  1605.      
  1606.    private:
  1607.       uint8* m_pBuf;
  1608.       size_t m_size;
  1609.       size_t m_ofs;
  1610.    };
  1611.  
  1612.    // ---- class document
  1613.      
  1614.    class document : public value_variant
  1615.    {
  1616.       document(const document&);
  1617.       document& operator= (const document&);
  1618.  
  1619.    public:
  1620.       inline document(uint initial_pool_size = 0, uint min_pool_chunk_size = PJSON_DEFAULT_MIN_CHUNK_SIZE, uint initial_stack_size = 0) :
  1621.          m_allocator(initial_pool_size, min_pool_chunk_size),
  1622.          m_initial_stack_size(initial_stack_size),
  1623.          m_stack(initial_stack_size)
  1624.       {
  1625. #if PJSON_PARSE_STATS
  1626.          m_parse_stats.clear();
  1627. #endif
  1628.       }
  1629.  
  1630.       inline ~document()
  1631.       {
  1632.       }
  1633.  
  1634.       const pool_allocator& get_allocator() const  { return m_allocator; }
  1635.             pool_allocator& get_allocator()        { return m_allocator; }
  1636.  
  1637.       void clear()
  1638.       {
  1639.          set_to_null();
  1640.          m_allocator.clear();
  1641.          m_stack.clear();
  1642. #if PJSON_PARSE_STATS
  1643.          m_parse_stats.clear();
  1644. #endif
  1645.       }
  1646.      
  1647.       bool deserialize_in_place(char* pStr)
  1648.       {
  1649.          return deserialize_start((uint8*)pStr);
  1650.       }
  1651.      
  1652. #if PJSON_PARSE_STATS      
  1653.       struct parse_stats_t
  1654.       {
  1655.          size_t m_num_string, m_num_string_chars;
  1656.          size_t m_num_numeric, m_num_numeric_chars;
  1657.          size_t m_num_whitespace_blocks, m_num_whitespace_chars;
  1658.          size_t m_num_control;
  1659.          size_t m_num_comment, m_num_comment_chars;
  1660.          size_t m_num_value_pop, m_value_pop_bytes;
  1661.          size_t m_num_bool_chars;
  1662.          size_t m_num_escape_breaks;
  1663.          size_t m_num_unicode_escapes;
  1664.  
  1665.          void clear() { memset(this, 0, sizeof(*this)); }
  1666.       };
  1667.  
  1668.       const parse_stats_t& get_parse_stats() const { return m_parse_stats; }
  1669.             parse_stats_t& get_parse_stats()       { return m_parse_stats; }
  1670. #endif
  1671.            
  1672.    private:
  1673.       pool_allocator m_allocator;
  1674.       uint m_initial_stack_size;
  1675.       growable_stack m_stack;
  1676.       error_info m_error_info;
  1677.       const uint8* m_pStart;
  1678.       const uint8* m_pStr;
  1679.      
  1680.       inline bool set_error(const uint8* pStr, const char* pMsg)
  1681.       {
  1682.          m_pStr = pStr;
  1683.          m_error_info.set(m_pStr - m_pStart, pMsg);
  1684.          return false;
  1685.       }
  1686.  
  1687. #if PJSON_PARSE_STATS      
  1688.       parse_stats_t m_parse_stats;
  1689. #endif
  1690.  
  1691. #if PJSON_PARSE_STATS
  1692.    #define PJSON_INCREMENT_STAT(x) do { ++m_parse_stats.x; } while(0)
  1693.    #define PJSON_UPDATE_STAT(x, n) do { m_parse_stats.x += n; } while(0)
  1694. #else
  1695.    #define PJSON_INCREMENT_STAT(x) do { } while(0)
  1696.    #define PJSON_UPDATE_STAT(x, n) do { } while(0)
  1697. #endif
  1698.      
  1699. #define PJSON_SKIP_WHITESPACE \
  1700.    while (globals::s_parse_flags[*pStr] & 4) \
  1701.    { \
  1702.       PJSON_INCREMENT_STAT(m_num_whitespace_blocks); \
  1703.       do { \
  1704.          if (!(globals::s_parse_flags[pStr[1]] & 4)) { ++pStr; PJSON_INCREMENT_STAT(m_num_whitespace_chars); break; } \
  1705.          if (!(globals::s_parse_flags[pStr[2]] & 4)) { pStr += 2; PJSON_UPDATE_STAT(m_num_whitespace_chars, 2); break; } \
  1706.          if (!(globals::s_parse_flags[pStr[3]] & 4)) { pStr += 3; PJSON_UPDATE_STAT(m_num_whitespace_chars, 3); break; } \
  1707.          pStr += 4; PJSON_UPDATE_STAT(m_num_whitespace_chars, 4); \
  1708.       } while (globals::s_parse_flags[*pStr] & 4); \
  1709.       if ((*pStr != '/') || (pStr[1] != '/')) break; \
  1710.       pStr += 2; PJSON_INCREMENT_STAT(m_num_comment); PJSON_UPDATE_STAT(m_num_comment_chars, 2); \
  1711.       while ((*pStr) && (*pStr != '\n') && (*pStr != '\r')) { PJSON_INCREMENT_STAT(m_num_comment_chars); ++pStr; } \
  1712.    }
  1713.  
  1714.       inline const uint8* skip_whitespace(const uint8* p)
  1715.       {
  1716.          uint8 c;
  1717.          while ((c = *p) != '\0')
  1718.          {
  1719.             if ((c == ' ') || (c == '\t'))
  1720.             {
  1721.                do
  1722.                {
  1723.                   PJSON_INCREMENT_STAT(m_num_whitespace_chars);
  1724.                } while (*++p == c);
  1725.                continue;
  1726.             }
  1727.  
  1728.             if ((c == '/') && (p[1] == '/'))
  1729.             {
  1730.                p += 2; PJSON_INCREMENT_STAT(m_num_comment); PJSON_UPDATE_STAT(m_num_comment_chars, 2);
  1731.                while ((*p) && (*p != '\n') && (*p != '\r'))
  1732.                {
  1733.                   PJSON_UPDATE_STAT(m_num_comment_chars, 2);
  1734.                   ++p;
  1735.                }
  1736.                continue;
  1737.             }
  1738.             else if (c > ' ')
  1739.                break;
  1740.  
  1741.             PJSON_INCREMENT_STAT(m_num_whitespace_chars);
  1742.             ++p;
  1743.          }
  1744.          return p;
  1745.       }
  1746.            
  1747.       bool deserialize_internal()
  1748.       {
  1749.          static const uint8 g_utf8_first_byte[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  1750.          
  1751.          m_stack.reset();
  1752.          memcpy(m_stack.push<value_variant>(1), static_cast<value_variant*>(this), sizeof(value_variant));
  1753.  
  1754.          const uint8* pStr = ++m_pStr;
  1755.          PJSON_UPDATE_STAT(m_num_control, 1);
  1756.                  
  1757.          bool cur_is_object = is_object();
  1758.          uint8 cur_end_char = get_end_char();
  1759.          uint cur_num_elements = 0;
  1760.                  
  1761.          for ( ; ; )
  1762.          {
  1763.             PJSON_SKIP_WHITESPACE;
  1764.  
  1765.             uint8 c = *pStr;
  1766.            
  1767.             if (c == ',')
  1768.             {
  1769.                if (!cur_num_elements)
  1770.                   return set_error(pStr, "Unexpected comma");
  1771.  
  1772.                ++pStr;
  1773.                PJSON_UPDATE_STAT(m_num_control, 1);
  1774.                PJSON_SKIP_WHITESPACE;
  1775.                c = *pStr;
  1776.             }
  1777.             else if ((cur_num_elements) && (c != cur_end_char))
  1778.                return set_error(pStr, "Expected comma or object/array end character");
  1779.            
  1780.             while (c == cur_end_char)
  1781.             {
  1782.                PJSON_UPDATE_STAT(m_num_control, 1);
  1783.                ++pStr;
  1784.                              
  1785.                for ( ; ; )
  1786.                {
  1787.                   uint n = cur_num_elements, num_bytes = cur_num_elements * (cur_is_object ? sizeof(key_value_t) : sizeof(value_variant));
  1788.                   void* pSrc = m_stack.pop<uint8>(num_bytes);
  1789.                   PJSON_INCREMENT_STAT(m_num_value_pop);
  1790.                   PJSON_UPDATE_STAT(m_value_pop_bytes, num_bytes);
  1791.  
  1792.                   // The top of the stack (after popping the current array/object) could contain either a value_variant (if cur_is_object is set),
  1793.                   // or a key_value_t, which ends in a value_variant. So all we need to do is look at the very end, which always has a value_variant.
  1794.                   value_variant* pCur_variant = m_stack.get_top_obj<value_variant>();
  1795.  
  1796.                   value_variant_vec_t& arr = pCur_variant->get_array();
  1797.                   cur_is_object = (arr.m_p != NULL);
  1798.                   cur_end_char = cur_is_object ? '}' : ']';
  1799.                   cur_num_elements = arr.m_size;
  1800.                  
  1801.                   arr.m_size = n;
  1802.                   arr.m_p = NULL;
  1803.                   if (num_bytes)
  1804.                      memcpy(arr.m_p = static_cast<value_variant*>(m_allocator.Alloc(num_bytes)), pSrc, num_bytes);
  1805.                  
  1806.                   if (m_stack.get_ofs() <= sizeof(value_variant))
  1807.                   {
  1808.                      PJSON_ASSERT(m_stack.get_ofs() == sizeof(value_variant));
  1809.                      memcpy(static_cast<value_variant*>(this), m_stack.pop<value_variant>(1), sizeof(value_variant));
  1810.                      m_pStr = pStr;
  1811.                      return true;
  1812.                   }
  1813.                                    
  1814.                   PJSON_SKIP_WHITESPACE;                  
  1815.  
  1816.                   if (*pStr == ',')
  1817.                   {
  1818.                      PJSON_UPDATE_STAT(m_num_control, 1);
  1819.                      ++pStr;
  1820.                      
  1821.                      PJSON_SKIP_WHITESPACE;
  1822.  
  1823.                      c = *pStr;
  1824.                      break;
  1825.                   }
  1826.                                    
  1827.                   if (*pStr++ != cur_end_char)
  1828.                      return set_error(pStr, "Unexpected character within object or array");
  1829.                   PJSON_UPDATE_STAT(m_num_control, 1);
  1830.                }
  1831.             }
  1832.  
  1833.             ++cur_num_elements;
  1834.  
  1835.             value_variant* pChild_variant;
  1836.            
  1837.             if (!cur_is_object)
  1838.                pChild_variant = m_stack.push<value_variant>(1);
  1839.             else
  1840.             {
  1841.                if (c != '\"')
  1842.                   return set_error(pStr, "Expected quoted key string");
  1843.                
  1844.                ++pStr; PJSON_INCREMENT_STAT(m_num_string); PJSON_INCREMENT_STAT(m_num_string_chars);
  1845.  
  1846.                uint8* pBuf = (uint8*)pStr;
  1847.  
  1848.                c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1849.                if (!(globals::s_parse_flags[c] & 1))
  1850.                {
  1851.                   do
  1852.                   {
  1853.                      c = pStr[0]; if (globals::s_parse_flags[c] & 1) { ++pStr; PJSON_UPDATE_STAT(m_num_string_chars, 1); break; }
  1854.                      c = pStr[1]; if (globals::s_parse_flags[c] & 1) { pStr += 2; PJSON_UPDATE_STAT(m_num_string_chars, 2); break; }
  1855.                      c = pStr[2]; if (globals::s_parse_flags[c] & 1) { pStr += 3; PJSON_UPDATE_STAT(m_num_string_chars, 3); break; }
  1856.                      c = pStr[3];
  1857.                      pStr += 4; PJSON_UPDATE_STAT(m_num_string_chars, 4);
  1858.                   } while (!(globals::s_parse_flags[c] & 1));
  1859.                }
  1860.  
  1861.                uint8* pDst = (uint8*)pStr - 1;
  1862.  
  1863.                if (c != '\"') PJSON_INCREMENT_STAT(m_num_escape_breaks);
  1864.  
  1865.                while (c != '\"')
  1866.                {
  1867.                   if (globals::s_parse_flags[c] & 2)
  1868.                      return set_error(pStr, "Missing end quote");
  1869.  
  1870.                   c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1871.                   if (c == 'u')
  1872.                   {
  1873.                      PJSON_INCREMENT_STAT(m_num_unicode_escapes);
  1874.                      uint u = 0;
  1875.                      for (uint i = 0; i < 4; i++)
  1876.                      {
  1877.                         u <<= 4;
  1878.                         int cc = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1879.                         if ((cc >= 'A') && (cc <= 'F'))
  1880.                            u += cc - 'A' + 10;
  1881.                         else if ((cc >= 'a') && (cc <= 'f'))
  1882.                            u += cc - 'a' + 10;
  1883.                         else if ((cc >= '0') && (cc <= '9'))
  1884.                            u += cc - '0';
  1885.                         else
  1886.                            return set_error(pStr, "Invalid Unicode escape");
  1887.                      }
  1888.  
  1889.                      uint len = 3; if ((u) && (u < 0x80)) len = 1; else if (u < 0x800) len = 2;
  1890.  
  1891.                      pDst += len;
  1892.                      uint8* q = pDst;
  1893.                      switch (len)
  1894.                      {
  1895.                         case 3: *--q = static_cast<uint8>((u | 0x80) & 0xBF); u >>= 6; // falls through
  1896.                         case 2: *--q = static_cast<uint8>((u | 0x80) & 0xBF); u >>= 6; // falls through
  1897.                         case 1: *--q = static_cast<uint8>(u | g_utf8_first_byte[len]);
  1898.                      }
  1899.                   }
  1900.                   else
  1901.                   {
  1902.                      switch (c)
  1903.                      {
  1904.                         case 'b': c = '\b'; break;
  1905.                         case 'f': c = '\f'; break;
  1906.                         case 'n': c = '\n'; break;
  1907.                         case 'r': c = '\r'; break;
  1908.                         case 't': c = '\t'; break;
  1909.                         case '\\': case '\"': case '/': break;
  1910.                         case '\0': return set_error(pStr, "Incomplete string escape");
  1911.                         default: { *pDst++ = '\\'; break; } // unrecognized escape, so forcefully escape the backslash (not standard)
  1912.                      }
  1913.  
  1914.                      *pDst++ = c;
  1915.                   }
  1916.  
  1917.                   c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1918.                   while (!(globals::s_parse_flags[c] & 1))
  1919.                   {
  1920.                      pDst[0] = c;
  1921.                      c = pStr[0]; if (globals::s_parse_flags[c] & 1) { ++pDst; ++pStr; PJSON_INCREMENT_STAT(m_num_string_chars); break; }
  1922.                      pDst[1] = c;
  1923.                      c = pStr[1]; if (globals::s_parse_flags[c] & 1) { pDst += 2; pStr += 2; PJSON_UPDATE_STAT(m_num_string_chars, 2); break; }
  1924.                      pDst[2] = c;
  1925.                      c = pStr[2]; if (globals::s_parse_flags[c] & 1) { pDst += 3; pStr += 3; PJSON_UPDATE_STAT(m_num_string_chars, 3); break; }
  1926.                      pDst[3] = c;
  1927.                      pDst += 4;
  1928.                      c = pStr[3];
  1929.                      pStr += 4; PJSON_UPDATE_STAT(m_num_string_chars, 4);
  1930.                   }
  1931.                }
  1932.                
  1933.                *pDst++ = '\0';
  1934.  
  1935.                key_value_t* pKey_value = m_stack.push<key_value_t>(1);
  1936.                pChild_variant = &pKey_value->get_value();
  1937.                pKey_value->get_key().m_p = (char*)pBuf;
  1938.                pKey_value->get_key().m_size = static_cast<uint>(pDst - pBuf);
  1939.                
  1940.                PJSON_SKIP_WHITESPACE;
  1941.  
  1942.                if (*pStr != ':')
  1943.                   return set_error(pStr, "Missing colon after key");
  1944.  
  1945.                ++pStr; PJSON_INCREMENT_STAT(m_num_control);
  1946.                PJSON_SKIP_WHITESPACE;
  1947.                
  1948.                c = *pStr;
  1949.             }
  1950.                                                
  1951.             switch (c)
  1952.             {
  1953.                case '{':
  1954.                case '[':
  1955.                {
  1956.                   ++pStr; PJSON_INCREMENT_STAT(m_num_control);
  1957.  
  1958.                   pChild_variant->m_type = (c == '{') ? cJSONValueTypeObject : cJSONValueTypeArray;
  1959.                   pChild_variant->m_data.m_object.m_size = cur_num_elements;
  1960.                   pChild_variant->m_data.m_object.m_p = (key_value_t*)cur_is_object;
  1961.                  
  1962.                   cur_is_object = (c == '{');
  1963.                   cur_num_elements = 0;
  1964.                   cur_end_char = c + 2;
  1965.                   break;
  1966.                }
  1967.                case '\"':
  1968.                {
  1969.                   ++pStr; PJSON_INCREMENT_STAT(m_num_string); PJSON_INCREMENT_STAT(m_num_string_chars);
  1970.                  
  1971.                   uint8* pBuf = (uint8*)pStr;
  1972.                  
  1973.                   c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1974.                   if (!(globals::s_parse_flags[c] & 1))
  1975.                   {
  1976.                      do
  1977.                      {
  1978.                         c = pStr[0]; if (globals::s_parse_flags[c] & 1) { ++pStr; PJSON_INCREMENT_STAT(m_num_string_chars); break; }
  1979.                         c = pStr[1]; if (globals::s_parse_flags[c] & 1) { pStr += 2; PJSON_UPDATE_STAT(m_num_string_chars, 2); break; }
  1980.                         c = pStr[2]; if (globals::s_parse_flags[c] & 1) { pStr += 3; PJSON_UPDATE_STAT(m_num_string_chars, 3); break; }
  1981.                         c = pStr[3];
  1982.                         pStr += 4; PJSON_UPDATE_STAT(m_num_string_chars, 4);
  1983.                      } while (!(globals::s_parse_flags[c] & 1));
  1984.                   }
  1985.  
  1986.                   uint8* pDst = (uint8*)pStr - 1;
  1987.  
  1988.                   if (c != '\"') PJSON_INCREMENT_STAT(m_num_escape_breaks);
  1989.  
  1990.                   while (c != '\"')
  1991.                   {
  1992.                      if (globals::s_parse_flags[c] & 2)
  1993.                         return set_error(pStr, "Missing end quote");
  1994.                      
  1995.                      c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  1996.                      if (c == 'u')
  1997.                      {
  1998.                         PJSON_INCREMENT_STAT(m_num_unicode_escapes);
  1999.                         uint u = 0;
  2000.                         for (uint i = 0; i < 4; i++)
  2001.                         {
  2002.                            u <<= 4;
  2003.                            int cc = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  2004.                            if ((cc >= 'A') && (cc <= 'F'))
  2005.                               u += cc - 'A' + 10;
  2006.                            else if ((cc >= 'a') && (cc <= 'f'))
  2007.                               u += cc - 'a' + 10;
  2008.                            else if ((cc >= '0') && (cc <= '9'))
  2009.                               u += cc - '0';
  2010.                            else
  2011.                               return set_error(pStr, "Invalid Unicode escape");
  2012.                         }
  2013.  
  2014.                         uint len = 3; if ((u) && (u < 0x80)) len = 1; else if (u < 0x800) len = 2;
  2015.  
  2016.                         pDst += len;
  2017.                         uint8* q = pDst;
  2018.                         switch (len)
  2019.                         {
  2020.                            case 3: *--q = static_cast<uint8>((u | 0x80) & 0xBF); u >>= 6; // falls through
  2021.                            case 2: *--q = static_cast<uint8>((u | 0x80) & 0xBF); u >>= 6; // falls through
  2022.                            case 1: *--q = static_cast<uint8>(u | g_utf8_first_byte[len]);
  2023.                         }
  2024.                      }
  2025.                      else
  2026.                      {
  2027.                         switch (c)
  2028.                         {
  2029.                            case 'b': c = '\b'; break;
  2030.                            case 'f': c = '\f'; break;
  2031.                            case 'n': c = '\n'; break;
  2032.                            case 'r': c = '\r'; break;
  2033.                            case 't': c = '\t'; break;
  2034.                            case '\\': case '\"': case '/': break;
  2035.                            case '\0': return set_error(pStr, "Incomplete string escape");
  2036.                            default: { *pDst++ = '\\'; break; } // unrecognized escape, so forcefully escape the backslash (not standard)
  2037.                         }
  2038.  
  2039.                         *pDst++ = c;
  2040.                      }
  2041.  
  2042.                      c = *pStr++; PJSON_INCREMENT_STAT(m_num_string_chars);
  2043.                      while (!(globals::s_parse_flags[c] & 1))
  2044.                      {
  2045.                         pDst[0] = c;
  2046.                         c = pStr[0]; if (globals::s_parse_flags[c] & 1) { ++pDst; ++pStr; PJSON_INCREMENT_STAT(m_num_string_chars); break; }
  2047.                         pDst[1] = c;
  2048.                         c = pStr[1]; if (globals::s_parse_flags[c] & 1) { pDst += 2; pStr += 2; PJSON_UPDATE_STAT(m_num_string_chars, 2); break; }
  2049.                         pDst[2] = c;
  2050.                         c = pStr[2]; if (globals::s_parse_flags[c] & 1) { pDst += 3; pStr += 3; PJSON_UPDATE_STAT(m_num_string_chars, 3); break; }
  2051.                         pDst[3] = c;
  2052.                         pDst += 4;
  2053.                         c = pStr[3];
  2054.                         pStr += 4; PJSON_UPDATE_STAT(m_num_string_chars, 4);
  2055.                      }
  2056.                   }
  2057.  
  2058.                   *pDst++ = '\0';
  2059.  
  2060.                   pChild_variant->m_type = cJSONValueTypeString;
  2061.  
  2062.                   string_vec_t& str = pChild_variant->get_string();
  2063.                   str.m_p = (char*)pBuf;
  2064.                   str.m_size = static_cast<uint>(pDst - pBuf);
  2065.  
  2066.                   break;
  2067.                }
  2068.                case 'n':
  2069.                {
  2070.                   if ((pStr[1] == 'u') && (pStr[2] == 'l') && (pStr[3] == 'l'))
  2071.                   {
  2072.                      pStr += 4; PJSON_UPDATE_STAT(m_num_bool_chars, 4);
  2073.                      pChild_variant->construct(cJSONValueTypeNull);
  2074.                   }
  2075.                   else
  2076.                      return set_error(pStr, "Unrecognized character");
  2077.                   break;
  2078.                }
  2079.                case 't':
  2080.                {
  2081.                   if ((pStr[1] == 'r') && (pStr[2] == 'u') && (pStr[3] == 'e'))
  2082.                   {
  2083.                      pStr += 4; PJSON_UPDATE_STAT(m_num_bool_chars, 4);
  2084.                      pChild_variant->construct(cJSONValueTypeBool);
  2085.                      pChild_variant->m_data.m_nVal = 1;
  2086.                   }
  2087.                   else
  2088.                      return set_error(pStr, "Unrecognized character");
  2089.                   break;
  2090.                }
  2091.                case 'f':
  2092.                {
  2093.                   if ((pStr[1] == 'a') && (pStr[2] == 'l') && (pStr[3] == 's') && (pStr[4] == 'e'))
  2094.                   {
  2095.                      pStr += 5; PJSON_UPDATE_STAT(m_num_bool_chars, 5);
  2096.                      pChild_variant->construct(cJSONValueTypeBool);
  2097.                   }
  2098.                   else
  2099.                      return set_error(pStr, "Unrecognized character");
  2100.                   break;
  2101.                }
  2102.                case '0': case '1': case '2': case '3': case '4': case '5':
  2103.                case '6': case '7': case '8': case '9': case '-': case '.':
  2104.                {
  2105.                   PJSON_INCREMENT_STAT(m_num_numeric);
  2106.                   if (c == '-') PJSON_INCREMENT_STAT(m_num_numeric_chars);
  2107.                  
  2108.                   uint32 n32 = 0;
  2109.                   int is_neg = (c == '-');
  2110.                   c = *(pStr += is_neg);
  2111.                  
  2112.                   if (globals::s_parse_flags[c] & 8)
  2113.                   {
  2114.                      n32 = c - '0'; c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2115.                      if (globals::s_parse_flags[c] & 8)
  2116.                      {
  2117.                         n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2118.                         if (globals::s_parse_flags[c] & 8)
  2119.                         {
  2120.                            n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2121.                            if (globals::s_parse_flags[c] & 8)
  2122.                            {
  2123.                               n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2124.                               if (globals::s_parse_flags[c] & 8)
  2125.                               {
  2126.                                  n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2127.                                  if (globals::s_parse_flags[c] & 8)
  2128.                                  {
  2129.                                     n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2130.                                     if (globals::s_parse_flags[c] & 8)
  2131.                                     {
  2132.                                        n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2133.                                        if (globals::s_parse_flags[c] & 8)
  2134.                                        {
  2135.                                           n32 = (n32 * 10U) + (c - '0'); c = *++pStr; PJSON_UPDATE_STAT(m_num_numeric_chars, 1);
  2136.                                        }
  2137.                                     }
  2138.                                  }
  2139.                               }
  2140.                            }
  2141.                         }
  2142.                      }
  2143.                   }
  2144.  
  2145.                   if (!(globals::s_parse_flags[c] & 0x10))
  2146.                   {
  2147.                      pChild_variant->m_type = cJSONValueTypeInt;
  2148.                      pChild_variant->m_data.m_nVal = is_neg + (static_cast<int32>(n32) ^ (-is_neg));
  2149.                   }
  2150.                   else
  2151.                   {
  2152.                      uint64 n64 = n32;
  2153.                      while (globals::s_parse_flags[c] & 8)
  2154.                      {
  2155.                         n64 = n64 * 10U + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2156.                        
  2157.                         if ((!(globals::s_parse_flags[c] & 8)) || (n64 > 0xCCCCCCCCCCCCCCBULL))
  2158.                            break;
  2159.                        
  2160.                         n64 = n64 * 10U + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2161.  
  2162.                         if (n64 > 0xCCCCCCCCCCCCCCBULL)
  2163.                            break;
  2164.                      }
  2165.  
  2166.                      if (!(globals::s_parse_flags[c] & 0x10))
  2167.                      {
  2168.                         pChild_variant->m_type = cJSONValueTypeInt;
  2169.                         pChild_variant->m_data.m_nVal = is_neg + (static_cast<int64>(n64) ^ (-is_neg));
  2170.                      }
  2171.                      else
  2172.                      {
  2173.                         double f = static_cast<double>(n64);
  2174.                         int scale = 0, escalesign = 1, escale = 0;
  2175.  
  2176.                         while (globals::s_parse_flags[c] & 8)
  2177.                         {
  2178.                            f = f * 10.0f + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2179.                            if (!(globals::s_parse_flags[c] & 8))
  2180.                               break;
  2181.                            
  2182.                            f = f * 10.0f + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2183.                         }
  2184.  
  2185.                         if (c == '.')
  2186.                         {
  2187.                            PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2188.                            while (globals::s_parse_flags[c] & 8)
  2189.                            {
  2190.                               scale--; f = f * 10.0f + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2191.  
  2192.                               if (!(globals::s_parse_flags[c] & 8))
  2193.                                  break;
  2194.                              
  2195.                               scale--; f = f * 10.0f + (c - '0'); PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2196.                            }
  2197.                         }
  2198.  
  2199.                         if ((c == 'e') || (c == 'E'))
  2200.                         {
  2201.                            PJSON_INCREMENT_STAT(m_num_numeric_chars);
  2202.                            c = *++pStr;
  2203.                            if (c == '-')
  2204.                            {
  2205.                               escalesign = -1;
  2206.                               PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2207.                            }
  2208.                            else if (c == '+')
  2209.                            {
  2210.                               PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2211.                            }
  2212.                            while (globals::s_parse_flags[c] & 8)
  2213.                            {
  2214.                               if (escale > 0xCCCCCCB)
  2215.                                  return set_error(pStr, "Failed parsing numeric value");
  2216.                               escale = escale * 10 + (c - '0');
  2217.                               PJSON_INCREMENT_STAT(m_num_numeric_chars); c = *++pStr;
  2218.                            }
  2219.                         }
  2220.  
  2221.                         static const float s_neg[2] = { 1.0f, -1.0f };
  2222.                         double v = f * s_neg[is_neg];
  2223.                         int64 final_scale = scale + escale * escalesign;
  2224.                         if (static_cast<uint64>(final_scale + 31) <= 62)
  2225.                            v *= globals::s_pow10_table[static_cast<int>(final_scale) + 31];
  2226.                         else
  2227.                         {
  2228.                            if ((final_scale < INT32_MIN) || (final_scale > INT32_MAX))
  2229.                               return set_error(pStr, "Failed parsing numeric value");
  2230.                            v *= pow(10.0, static_cast<int>(final_scale));
  2231.                         }
  2232.  
  2233.                         pChild_variant->m_type = cJSONValueTypeDouble;
  2234.                         pChild_variant->m_data.m_flVal = v;
  2235.                      }
  2236.                   }
  2237.                  
  2238.                   break;
  2239.                }
  2240.                case '\0':
  2241.                   return set_error(pStr, "Premature end of string (expected name or value)");
  2242.                default:
  2243.                   return set_error(pStr, "Unrecognized character");
  2244.             }
  2245.          }
  2246.       }
  2247.  
  2248.       bool deserialize_start(uint8* pStr)
  2249.       {
  2250.          set_to_null();
  2251.  
  2252. #if PJSON_PARSE_STATS
  2253.          m_parse_stats.clear();
  2254. #endif
  2255.  
  2256.          m_allocator.reset();
  2257.  
  2258.          m_pStart = pStr;
  2259.          
  2260.          m_pStr = skip_whitespace(pStr);
  2261.          
  2262.          if (!*m_pStr)
  2263.             return set_error(m_pStr, "Nothing to deserialize");
  2264.  
  2265.          bool success = false;
  2266.  
  2267.          uint8 c = *m_pStr;
  2268.          if ((c == '{') || (c == '['))
  2269.          {
  2270.             set_to_node(c == '{'); PJSON_INCREMENT_STAT(m_num_control);
  2271.             success = deserialize_internal();
  2272.          }
  2273.          else
  2274.             return set_error(m_pStr, "Root value must be an object or array");
  2275.  
  2276.          if (success)
  2277.          {
  2278.             m_pStr = skip_whitespace(m_pStr);
  2279.             success = !*m_pStr;
  2280.             if (!success)
  2281.                set_error(m_pStr, "Unknown data at end of document");
  2282.          }
  2283.  
  2284.          return success;
  2285.       }
  2286.    };
  2287.  
  2288. } // namespace pjson
  2289.  
  2290. #endif // PJSON_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement