Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. /* vim: set et ts=3 sw=3 sts=3 ft=c:
  3.  *
  4.  * Copyright (C) 2012, 2013, 2014 James McLaughlin et al.  All rights reserved.
  5.  * https://github.com/udp/json-parser
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *   notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *   notice, this list of conditions and the following disclaimer in the
  16.  *   documentation and/or other materials provided with the distribution.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  19.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  22.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28.  * SUCH DAMAGE.
  29.  */
  30.  
  31. #ifndef _JSON_H
  32. #define _JSON_H
  33.  
  34. #ifndef json_char
  35.    #define json_char char
  36. #endif
  37.  
  38. #ifndef json_int_t
  39.    #ifndef _MSC_VER
  40.       #include "inttypes.h"
  41.       #define json_int_t int64_t
  42.    #else
  43.       #define json_int_t __int64
  44.    #endif
  45. #endif
  46.  
  47. #include <stdlib.h>
  48.  
  49. #ifdef __cplusplus
  50.  
  51.    #include <string.h>
  52.  
  53.    extern "C"
  54.    {
  55.  
  56. #endif
  57.  
  58. typedef struct
  59. {
  60.    unsigned long max_memory;
  61.    int settings;
  62.  
  63.    /* Custom allocator support (leave null to use malloc/free)
  64.     */
  65.  
  66.    void * (* mem_alloc) (size_t, int zero, void * user_data);
  67.    void (* mem_free) (void *, void * user_data);
  68.  
  69.    void * user_data;  /* will be passed to mem_alloc and mem_free */
  70.  
  71.    size_t value_extra;  /* how much extra space to allocate for values? */
  72.  
  73. } json_settings;
  74.  
  75. #define json_enable_comments  0x01
  76.  
  77. typedef enum
  78. {
  79.    json_none,
  80.    json_object,
  81.    json_array,
  82.    json_integer,
  83.    json_double,
  84.    json_string,
  85.    json_boolean,
  86.    json_null
  87.  
  88. } json_type;
  89.  
  90. extern const struct _json_value json_value_none;
  91.        
  92. typedef struct _json_object_entry
  93. {
  94.     json_char * name;
  95.     unsigned int name_length;
  96.    
  97.     struct _json_value * value;
  98.    
  99. } json_object_entry;
  100.  
  101. typedef struct _json_value
  102. {
  103.    struct _json_value * parent;
  104.  
  105.    json_type type;
  106.  
  107.    union
  108.    {
  109.       int boolean;
  110.       json_int_t integer;
  111.       double dbl;
  112.  
  113.       struct
  114.       {
  115.          unsigned int length;
  116.          json_char * ptr; /* null terminated */
  117.  
  118.       } string;
  119.  
  120.       struct
  121.       {
  122.          unsigned int length;
  123.  
  124.          json_object_entry * values;
  125.  
  126.          #if defined(__cplusplus) && __cplusplus >= 201103L
  127.          decltype(values) begin () const
  128.          {  return values;
  129.          }
  130.          decltype(values) end () const
  131.          {  return values + length;
  132.          }
  133.          #endif
  134.  
  135.       } object;
  136.  
  137.       struct
  138.       {
  139.          unsigned int length;
  140.          struct _json_value ** values;
  141.  
  142.          #if defined(__cplusplus) && __cplusplus >= 201103L
  143.          decltype(values) begin () const
  144.          {  return values;
  145.          }
  146.          decltype(values) end () const
  147.          {  return values + length;
  148.          }
  149.          #endif
  150.  
  151.       } array;
  152.  
  153.    } u;
  154.  
  155.    union
  156.    {
  157.       struct _json_value * next_alloc;
  158.       void * object_mem;
  159.  
  160.    } _reserved;
  161.  
  162.    #ifdef JSON_TRACK_SOURCE
  163.  
  164.       /* Location of the value in the source JSON
  165.        */
  166.       unsigned int line, col;
  167.  
  168.    #endif
  169.  
  170.  
  171.    /* Some C++ operator sugar */
  172.  
  173.    #ifdef __cplusplus
  174.  
  175.       public:
  176.  
  177.          inline _json_value ()
  178.          {  memset (this, 0, sizeof (_json_value));
  179.          }
  180.  
  181.          inline const struct _json_value &operator [] (int index) const
  182.          {
  183.             if (type != json_array || index < 0
  184.                      || ((unsigned int) index) >= u.array.length)
  185.             {
  186.                return json_value_none;
  187.             }
  188.  
  189.             return *u.array.values [index];
  190.          }
  191.  
  192.          inline const struct _json_value &operator [] (const char * index) const
  193.          {
  194.             if (type != json_object)
  195.                return json_value_none;
  196.  
  197.             for (unsigned int i = 0; i < u.object.length; ++ i)
  198.                if (!strcmp (u.object.values [i].name, index))
  199.                   return *u.object.values [i].value;
  200.  
  201.             return json_value_none;
  202.          }
  203.  
  204.          inline operator const char * () const
  205.          {  
  206.             switch (type)
  207.             {
  208.                case json_string:
  209.                   return u.string.ptr;
  210.  
  211.                default:
  212.                   return "";
  213.             };
  214.          }
  215.  
  216.          inline operator json_int_t () const
  217.          {  
  218.             switch (type)
  219.             {
  220.                case json_integer:
  221.                   return u.integer;
  222.  
  223.                case json_double:
  224.                   return (json_int_t) u.dbl;
  225.  
  226.                default:
  227.                   return 0;
  228.             };
  229.          }
  230.  
  231.          inline operator bool () const
  232.          {  
  233.             if (type != json_boolean)
  234.                return false;
  235.  
  236.             return u.boolean != 0;
  237.          }
  238.  
  239.          inline operator double () const
  240.          {  
  241.             switch (type)
  242.             {
  243.                case json_integer:
  244.                   return (double) u.integer;
  245.  
  246.                case json_double:
  247.                   return u.dbl;
  248.  
  249.                default:
  250.                   return 0;
  251.             };
  252.          }
  253.  
  254.    #endif
  255.  
  256. } json_value;
  257.        
  258. json_value * json_parse (const json_char * json,
  259.                          size_t length);
  260.  
  261. #define json_error_max 128
  262. json_value * json_parse_ex (json_settings * settings,
  263.                             const json_char * json,
  264.                             size_t length,
  265.                             char * error);
  266.  
  267. void json_value_free (json_value *);
  268.  
  269.  
  270. /* Not usually necessary, unless you used a custom mem_alloc and now want to
  271.  * use a custom mem_free.
  272.  */
  273. void json_value_free_ex (json_settings * settings,
  274.                          json_value *);
  275.  
  276.  
  277. #ifdef __cplusplus
  278.    } /* extern "C" */
  279. #endif
  280.  
  281. #endif
  282.  
  283.  
  284.