gen-rack

Create VCV Rack modules from gen~ exports
Log | Files | Refs | README | LICENSE

json_builder.c (24809B)


      1 
      2 /* vim: set et ts=3 sw=3 sts=3 ft=c:
      3  *
      4  * Copyright (C) 2014 James McLaughlin.  All rights reserved.
      5  * https://github.com/udp/json-builder
      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 #include "json_builder.h"
     32 
     33 #include <string.h>
     34 #include <assert.h>
     35 #include <stdio.h>
     36 #include <math.h>
     37 
     38 #ifdef _MSC_VER
     39     #define snprintf _snprintf
     40 #endif
     41 
     42 const static json_serialize_opts default_opts =
     43 {
     44    json_serialize_mode_single_line,
     45    0,
     46    3  /* indent_size */
     47 };
     48 
     49 typedef struct json_builder_value
     50 {
     51    json_value value;
     52 
     53    int is_builder_value;
     54 
     55    size_t additional_length_allocated;
     56    size_t length_iterated;
     57 
     58 } json_builder_value;
     59 
     60 static int builderize (json_value * value)
     61 {
     62    if (((json_builder_value *) value)->is_builder_value)
     63       return 1;
     64 
     65    if (value->type == json_object)
     66    {
     67       unsigned int i;
     68 
     69       /* Values straight out of the parser have the names of object entries
     70        * allocated in the same allocation as the values array itself.  This is
     71        * not desirable when manipulating values because the names would be easy
     72        * to clobber.
     73        */
     74       for (i = 0; i < value->u.object.length; ++ i)
     75       {
     76          json_char * name_copy;
     77          json_object_entry * entry = &value->u.object.values [i];
     78 
     79          if (! (name_copy = (json_char *) malloc ((entry->name_length + 1) * sizeof (json_char))))
     80             return 0;
     81 
     82          memcpy (name_copy, entry->name, entry->name_length + 1);
     83          entry->name = name_copy;
     84       }
     85    }
     86 
     87    ((json_builder_value *) value)->is_builder_value = 1;
     88 
     89    return 1;
     90 }
     91 
     92 const size_t json_builder_extra = sizeof(json_builder_value) - sizeof(json_value);
     93 
     94 /* These flags are set up from the opts before serializing to make the
     95  * serializer conditions simpler.
     96  */
     97 const int f_spaces_around_brackets = (1 << 0);
     98 const int f_spaces_after_commas    = (1 << 1);
     99 const int f_spaces_after_colons    = (1 << 2);
    100 const int f_tabs                   = (1 << 3);
    101 
    102 int get_serialize_flags (json_serialize_opts opts)
    103 {
    104    int flags = 0;
    105 
    106    if (opts.mode == json_serialize_mode_packed)
    107       return 0;
    108 
    109    if (opts.mode == json_serialize_mode_multiline)
    110    {
    111       if (opts.opts & json_serialize_opt_use_tabs)
    112          flags |= f_tabs;
    113    }
    114    else
    115    {
    116       if (! (opts.opts & json_serialize_opt_pack_brackets))
    117          flags |= f_spaces_around_brackets;
    118 
    119       if (! (opts.opts & json_serialize_opt_no_space_after_comma))
    120          flags |= f_spaces_after_commas;
    121    }
    122 
    123    if (! (opts.opts & json_serialize_opt_no_space_after_colon))
    124       flags |= f_spaces_after_colons;
    125 
    126    return flags;
    127 }
    128 
    129 json_value * json_array_new (size_t length)
    130 {
    131     json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    132 
    133     if (!value)
    134        return NULL;
    135 
    136     ((json_builder_value *) value)->is_builder_value = 1;
    137 
    138     value->type = json_array;
    139 
    140     if (! (value->u.array.values = (json_value **) malloc (length * sizeof (json_value *))))
    141     {
    142        free (value);
    143        return NULL;
    144     }
    145 
    146     ((json_builder_value *) value)->additional_length_allocated = length;
    147 
    148     return value;
    149 }
    150 
    151 json_value * json_array_push (json_value * array, json_value * value)
    152 {
    153    assert (array->type == json_array);
    154 
    155    if (!builderize (array) || !builderize (value))
    156       return NULL;
    157 
    158    if (((json_builder_value *) array)->additional_length_allocated > 0)
    159    {
    160       -- ((json_builder_value *) array)->additional_length_allocated;
    161    }
    162    else
    163    {
    164       json_value ** values_new = (json_value **) realloc
    165             (array->u.array.values, sizeof (json_value *) * (array->u.array.length + 1));
    166 
    167       if (!values_new)
    168          return NULL;
    169 
    170       array->u.array.values = values_new;
    171    }
    172 
    173    array->u.array.values [array->u.array.length] = value;
    174    ++ array->u.array.length;
    175 
    176    value->parent = array;
    177 
    178    return value;
    179 }
    180 
    181 json_value * json_object_new (size_t length)
    182 {
    183     json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    184 
    185     if (!value)
    186        return NULL;
    187 
    188     ((json_builder_value *) value)->is_builder_value = 1;
    189 
    190     value->type = json_object;
    191 
    192     if (! (value->u.object.values = (json_object_entry *) calloc
    193            (length, sizeof (*value->u.object.values))))
    194     {
    195        free (value);
    196        return NULL;
    197     }
    198 
    199     ((json_builder_value *) value)->additional_length_allocated = length;
    200 
    201     return value;
    202 }
    203 
    204 json_value * json_object_push (json_value * object,
    205                                const json_char * name,
    206                                json_value * value)
    207 {
    208    return json_object_push_length (object, strlen (name), name, value);
    209 }
    210 
    211 json_value * json_object_push_length (json_value * object,
    212                                       unsigned int name_length, const json_char * name,
    213                                       json_value * value)
    214 {
    215    json_char * name_copy;
    216 
    217    assert (object->type == json_object);
    218 
    219    if (! (name_copy = (json_char *) malloc ((name_length + 1) * sizeof (json_char))))
    220       return NULL;
    221 
    222    memcpy (name_copy, name, name_length * sizeof (json_char));
    223    name_copy [name_length] = 0;
    224 
    225    if (!json_object_push_nocopy (object, name_length, name_copy, value))
    226    {
    227       free (name_copy);
    228       return NULL;
    229    }
    230 
    231    return value;
    232 }
    233 
    234 json_value * json_object_push_nocopy (json_value * object,
    235                                       unsigned int name_length, json_char * name,
    236                                       json_value * value)
    237 {
    238    json_object_entry * entry;
    239 
    240    assert (object->type == json_object);
    241 
    242    if (!builderize (object) || !builderize (value))
    243       return NULL;
    244 
    245    if (((json_builder_value *) object)->additional_length_allocated > 0)
    246    {
    247       -- ((json_builder_value *) object)->additional_length_allocated;
    248    }
    249    else
    250    {
    251       json_object_entry * values_new = (json_object_entry *)
    252             realloc (object->u.object.values, sizeof (*object->u.object.values)
    253                             * (object->u.object.length + 1));
    254 
    255       if (!values_new)
    256          return NULL;
    257 
    258       object->u.object.values = values_new;
    259    }
    260 
    261    entry = object->u.object.values + object->u.object.length;
    262 
    263    entry->name_length = name_length;
    264    entry->name = name;
    265    entry->value = value;
    266 
    267    ++ object->u.object.length;
    268 
    269    value->parent = object;
    270 
    271    return value;
    272 }
    273 
    274 json_value * json_string_new (const json_char * buf)
    275 {
    276    return json_string_new_length (strlen (buf), buf);
    277 }
    278 
    279 json_value * json_string_new_length (unsigned int length, const json_char * buf)
    280 {
    281    json_value * value;
    282    json_char * copy = (json_char *) malloc ((length + 1) * sizeof (json_char));
    283 
    284    if (!copy)
    285       return NULL;
    286 
    287    memcpy (copy, buf, length * sizeof (json_char));
    288    copy [length] = 0;
    289 
    290    if (! (value = json_string_new_nocopy (length, copy)))
    291    {
    292       free (copy);
    293       return NULL;
    294    }
    295 
    296    return value;
    297 }
    298 
    299 json_value * json_string_new_nocopy (unsigned int length, json_char * buf)
    300 {
    301    json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    302 
    303    if (!value)
    304       return NULL;
    305 
    306    ((json_builder_value *) value)->is_builder_value = 1;
    307 
    308    value->type = json_string;
    309    value->u.string.length = length;
    310    value->u.string.ptr = buf;
    311 
    312    return value;
    313 }
    314 
    315 json_value * json_integer_new (json_int_t integer)
    316 {
    317    json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    318 
    319    if (!value)
    320       return NULL;
    321 
    322    ((json_builder_value *) value)->is_builder_value = 1;
    323 
    324    value->type = json_integer;
    325    value->u.integer = integer;
    326 
    327    return value;
    328 }
    329 
    330 json_value * json_double_new (double dbl)
    331 {
    332    json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    333 
    334    if (!value)
    335       return NULL;
    336 
    337    ((json_builder_value *) value)->is_builder_value = 1;
    338 
    339    value->type = json_double;
    340    value->u.dbl = dbl;
    341 
    342    return value;
    343 }
    344 
    345 json_value * json_boolean_new (int b)
    346 {
    347    json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    348 
    349    if (!value)
    350       return NULL;
    351 
    352    ((json_builder_value *) value)->is_builder_value = 1;
    353 
    354    value->type = json_boolean;
    355    value->u.boolean = b;
    356 
    357    return value;
    358 }
    359 
    360 json_value * json_null_new ()
    361 {
    362    json_value * value = (json_value *) calloc (1, sizeof (json_builder_value));
    363 
    364    if (!value)
    365       return NULL;
    366 
    367    ((json_builder_value *) value)->is_builder_value = 1;
    368 
    369    value->type = json_null;
    370 
    371    return value;
    372 }
    373 
    374 void json_object_sort (json_value * object, json_value * proto)
    375 {
    376    unsigned int i, out_index = 0;
    377 
    378    if (!builderize (object))
    379       return;  /* TODO error */
    380 
    381    assert (object->type == json_object);
    382    assert (proto->type == json_object);
    383 
    384    for (i = 0; i < proto->u.object.length; ++ i)
    385    {
    386       unsigned int j;
    387       json_object_entry proto_entry = proto->u.object.values [i];
    388 
    389       for (j = 0; j < object->u.object.length; ++ j)
    390       {
    391          json_object_entry entry = object->u.object.values [j];
    392 
    393          if (entry.name_length != proto_entry.name_length)
    394             continue;
    395 
    396          if (memcmp (entry.name, proto_entry.name, entry.name_length) != 0)
    397             continue;
    398 
    399          object->u.object.values [j] = object->u.object.values [out_index];
    400          object->u.object.values [out_index] = entry;
    401 
    402          ++ out_index;
    403       }
    404    }
    405 }
    406 
    407 json_value * json_object_merge (json_value * objectA, json_value * objectB)
    408 {
    409    unsigned int i;
    410 
    411    assert (objectA->type == json_object);
    412    assert (objectB->type == json_object);
    413    assert (objectA != objectB);
    414 
    415    if (!builderize (objectA) || !builderize (objectB))
    416       return NULL;
    417 
    418    if (objectB->u.object.length <=
    419         ((json_builder_value *) objectA)->additional_length_allocated)
    420    {
    421       ((json_builder_value *) objectA)->additional_length_allocated
    422           -= objectB->u.object.length;
    423    }
    424    else
    425    {
    426       json_object_entry * values_new;
    427 
    428       unsigned int alloc =
    429           objectA->u.object.length
    430               + ((json_builder_value *) objectA)->additional_length_allocated
    431               + objectB->u.object.length;
    432 
    433       if (! (values_new = (json_object_entry *)
    434             realloc (objectA->u.object.values, sizeof (json_object_entry) * alloc)))
    435       {
    436           return NULL;
    437       }
    438 
    439       objectA->u.object.values = values_new;
    440    }
    441 
    442    for (i = 0; i < objectB->u.object.length; ++ i)
    443    {
    444       json_object_entry * entry = &objectA->u.object.values[objectA->u.object.length + i];
    445 
    446       *entry = objectB->u.object.values[i];
    447       entry->value->parent = objectA;
    448    }
    449 
    450    objectA->u.object.length += objectB->u.object.length;
    451 
    452    free (objectB->u.object.values);
    453    free (objectB);
    454 
    455    return objectA;
    456 }
    457 
    458 static size_t measure_string (unsigned int length,
    459                               const json_char * str)
    460 {
    461    unsigned int i;
    462    size_t measured_length = 0;
    463 
    464    for(i = 0; i < length; ++ i)
    465    {
    466       json_char c = str [i];
    467 
    468       switch (c)
    469       {
    470       case '"':
    471       case '\\':
    472       case '/':
    473       case '\b':
    474       case '\f':
    475       case '\n':
    476       case '\r':
    477       case '\t':
    478 
    479          measured_length += 2;
    480          break;
    481 
    482       default:
    483 
    484          ++ measured_length;
    485          break;
    486       };
    487    };
    488 
    489    return measured_length;
    490 }
    491 
    492 #define PRINT_ESCAPED(c) do {  \
    493    *buf ++ = '\\';             \
    494    *buf ++ = (c);              \
    495 } while(0);                    \
    496 
    497 static size_t serialize_string (json_char * buf,
    498                                 unsigned int length,
    499                                 const json_char * str)
    500 {
    501    json_char * orig_buf = buf;
    502    unsigned int i;
    503 
    504    for(i = 0; i < length; ++ i)
    505    {
    506       json_char c = str [i];
    507 
    508       switch (c)
    509       {
    510       case '"':   PRINT_ESCAPED ('\"');  continue;
    511       case '\\':  PRINT_ESCAPED ('\\');  continue;
    512       case '/':   PRINT_ESCAPED ('/');   continue;
    513       case '\b':  PRINT_ESCAPED ('b');   continue;
    514       case '\f':  PRINT_ESCAPED ('f');   continue;
    515       case '\n':  PRINT_ESCAPED ('n');   continue;
    516       case '\r':  PRINT_ESCAPED ('r');   continue;
    517       case '\t':  PRINT_ESCAPED ('t');   continue;
    518 
    519       default:
    520 
    521          *buf ++ = c;
    522          break;
    523       };
    524    };
    525 
    526    return buf - orig_buf;
    527 }
    528 
    529 size_t json_measure (json_value * value)
    530 {
    531    return json_measure_ex (value, default_opts);
    532 }
    533 
    534 #define MEASURE_NEWLINE() do {                     \
    535    ++ newlines;                                    \
    536    indents += depth;                               \
    537 } while(0);                                        \
    538 
    539 size_t json_measure_ex (json_value * value, json_serialize_opts opts)
    540 {
    541    size_t total = 1;  /* null terminator */
    542    size_t newlines = 0;
    543    size_t depth = 0;
    544    size_t indents = 0;
    545    int flags;
    546    int bracket_size, comma_size, colon_size;
    547 
    548    flags = get_serialize_flags (opts);
    549 
    550    /* to reduce branching
    551     */
    552    bracket_size = flags & f_spaces_around_brackets ? 2 : 1;
    553    comma_size = flags & f_spaces_after_commas ? 2 : 1;
    554    colon_size = flags & f_spaces_after_colons ? 2 : 1;
    555 
    556    while (value)
    557    {
    558       json_int_t integer;
    559       json_object_entry * entry;
    560 
    561       switch (value->type)
    562       {
    563          case json_array:
    564 
    565             if (((json_builder_value *) value)->length_iterated == 0)
    566             {
    567                if (value->u.array.length == 0)
    568                {
    569                   total += 2;  /* `[]` */
    570                   break;
    571                }
    572 
    573                total += bracket_size;  /* `[` */
    574 
    575                ++ depth;
    576                MEASURE_NEWLINE(); /* \n after [ */
    577             }
    578 
    579             if (((json_builder_value *) value)->length_iterated == value->u.array.length)
    580             {
    581                -- depth;
    582                MEASURE_NEWLINE();
    583                total += bracket_size;  /* `]` */
    584 
    585                ((json_builder_value *) value)->length_iterated = 0;
    586                break;
    587             }
    588 
    589             if (((json_builder_value *) value)->length_iterated > 0)
    590             {
    591                total += comma_size;  /* `, ` */
    592 
    593                MEASURE_NEWLINE();
    594             }
    595 
    596             ((json_builder_value *) value)->length_iterated++;
    597             value = value->u.array.values [((json_builder_value *) value)->length_iterated - 1];
    598             continue;
    599 
    600          case json_object:
    601 
    602             if (((json_builder_value *) value)->length_iterated == 0)
    603             {
    604                if (value->u.object.length == 0)
    605                {
    606                   total += 2;  /* `{}` */
    607                   break;
    608                }
    609 
    610                total += bracket_size;  /* `{` */
    611 
    612                ++ depth;
    613                MEASURE_NEWLINE(); /* \n after { */
    614             }
    615 
    616             if (((json_builder_value *) value)->length_iterated == value->u.object.length)
    617             {
    618                -- depth;
    619                MEASURE_NEWLINE();
    620                total += bracket_size;  /* `}` */
    621 
    622                ((json_builder_value *) value)->length_iterated = 0;
    623                break;
    624             }
    625 
    626             if (((json_builder_value *) value)->length_iterated > 0)
    627             {
    628                total += comma_size;  /* `, ` */
    629                MEASURE_NEWLINE();
    630             }
    631 
    632             entry = value->u.object.values + (((json_builder_value *) value)->length_iterated ++);
    633 
    634             total += 2 + colon_size;  /* `"": ` */
    635             total += measure_string (entry->name_length, entry->name);
    636 
    637             value = entry->value;
    638             continue;
    639 
    640          case json_string:
    641 
    642             total += 2;  /* `""` */
    643             total += measure_string (value->u.string.length, value->u.string.ptr);
    644             break;
    645 
    646          case json_integer:
    647 
    648             integer = value->u.integer;
    649 
    650             if (integer < 0)
    651             {
    652                total += 1;  /* `-` */
    653                integer = - integer;
    654             }
    655 
    656             ++ total;  /* first digit */
    657 
    658             while (integer >= 10)
    659             {
    660                ++ total;  /* another digit */
    661                integer /= 10;
    662             }
    663 
    664             break;
    665 
    666          case json_double:
    667 
    668             total += snprintf (NULL, 0, "%g", value->u.dbl);
    669 
    670             if (value->u.dbl - floor (value->u.dbl) < 0.001)
    671                 total += 2;
    672 
    673             break;
    674 
    675          case json_boolean:
    676 
    677             total += value->u.boolean ?
    678                4:  /* `true` */
    679                5;  /* `false` */
    680 
    681             break;
    682 
    683          case json_null:
    684 
    685             total += 4;  /* `null` */
    686             break;
    687 
    688          default:
    689             break;
    690       };
    691 
    692       value = value->parent;
    693    }
    694 
    695    if (opts.mode == json_serialize_mode_multiline)
    696    {
    697       total += newlines * (((opts.opts & json_serialize_opt_CRLF) ? 2 : 1) + opts.indent_size);
    698       total += indents * opts.indent_size;
    699    }
    700 
    701    return total;
    702 }
    703 
    704 void json_serialize (json_char * buf, json_value * value)
    705 {
    706    json_serialize_ex (buf, value, default_opts);
    707 }
    708 
    709 #define PRINT_NEWLINE() do {                          \
    710    if (opts.mode == json_serialize_mode_multiline) {  \
    711       if (opts.opts & json_serialize_opt_CRLF)        \
    712          *buf ++ = '\r';                              \
    713       *buf ++ = '\n';                                 \
    714       for(i = 0; i < indent; ++ i)                    \
    715          *buf ++ = indent_char;                       \
    716    }                                                  \
    717 } while(0);                                           \
    718 
    719 #define PRINT_OPENING_BRACKET(c) do {                 \
    720    *buf ++ = (c);                                     \
    721    if (flags & f_spaces_around_brackets)              \
    722       *buf ++ = ' ';                                  \
    723 } while(0);                                           \
    724 
    725 #define PRINT_CLOSING_BRACKET(c) do {                 \
    726    if (flags & f_spaces_around_brackets)              \
    727       *buf ++ = ' ';                                  \
    728    *buf ++ = (c);                                     \
    729 } while(0);                                           \
    730 
    731 void json_serialize_ex (json_char * buf, json_value * value, json_serialize_opts opts)
    732 {
    733    json_int_t integer, orig_integer;
    734    json_object_entry * entry;
    735    json_char * ptr, * dot;
    736    int indent = 0;
    737    char indent_char;
    738    int i;
    739    int flags;
    740 
    741    flags = get_serialize_flags (opts);
    742 
    743    indent_char = flags & f_tabs ? '\t' : ' ';
    744 
    745    while (value)
    746    {
    747       switch (value->type)
    748       {
    749          case json_array:
    750 
    751             if (((json_builder_value *) value)->length_iterated == 0)
    752             {
    753                if (value->u.array.length == 0)
    754                {
    755                   *buf ++ = '[';
    756                   *buf ++ = ']';
    757 
    758                   break;
    759                }
    760 
    761                PRINT_OPENING_BRACKET ('[');
    762 
    763                indent += opts.indent_size;
    764                PRINT_NEWLINE();
    765             }
    766 
    767             if (((json_builder_value *) value)->length_iterated == value->u.array.length)
    768             {
    769                indent -= opts.indent_size;
    770                PRINT_NEWLINE();
    771                PRINT_CLOSING_BRACKET (']');
    772 
    773                ((json_builder_value *) value)->length_iterated = 0;
    774                break;
    775             }
    776 
    777             if (((json_builder_value *) value)->length_iterated > 0)
    778             {
    779                *buf ++ = ',';
    780 
    781                if (flags & f_spaces_after_commas)
    782                   *buf ++ = ' ';
    783 
    784                PRINT_NEWLINE();
    785             }
    786 
    787             ((json_builder_value *) value)->length_iterated++;
    788             value = value->u.array.values [((json_builder_value *) value)->length_iterated - 1];
    789             continue;
    790 
    791          case json_object:
    792 
    793             if (((json_builder_value *) value)->length_iterated == 0)
    794             {
    795                if (value->u.object.length == 0)
    796                {
    797                   *buf ++ = '{';
    798                   *buf ++ = '}';
    799 
    800                   break;
    801                }
    802 
    803                PRINT_OPENING_BRACKET ('{');
    804 
    805                indent += opts.indent_size;
    806                PRINT_NEWLINE();
    807             }
    808 
    809             if (((json_builder_value *) value)->length_iterated == value->u.object.length)
    810             {
    811                indent -= opts.indent_size;
    812                PRINT_NEWLINE();
    813                PRINT_CLOSING_BRACKET ('}');
    814 
    815                ((json_builder_value *) value)->length_iterated = 0;
    816                break;
    817             }
    818 
    819             if (((json_builder_value *) value)->length_iterated > 0)
    820             {
    821                *buf ++ = ',';
    822 
    823                if (flags & f_spaces_after_commas)
    824                   *buf ++ = ' ';
    825 
    826                PRINT_NEWLINE();
    827             }
    828 
    829             entry = value->u.object.values + (((json_builder_value *) value)->length_iterated ++);
    830 
    831             *buf ++ = '\"';
    832             buf += serialize_string (buf, entry->name_length, entry->name);
    833             *buf ++ = '\"';
    834             *buf ++ = ':';
    835 
    836             if (flags & f_spaces_after_colons)
    837                *buf ++ = ' ';
    838 
    839             value = entry->value;
    840             continue;
    841 
    842          case json_string:
    843 
    844             *buf ++ = '\"';
    845             buf += serialize_string (buf, value->u.string.length, value->u.string.ptr);
    846             *buf ++ = '\"';
    847             break;
    848 
    849          case json_integer:
    850 
    851             integer = value->u.integer;
    852 
    853             if (integer < 0)
    854             {
    855                *buf ++ = '-';
    856                integer = - integer;
    857             }
    858 
    859             orig_integer = integer;
    860 
    861             ++ buf;
    862 
    863             while (integer >= 10)
    864             {
    865                ++ buf;
    866                integer /= 10;
    867             }
    868 
    869             integer = orig_integer;
    870             ptr = buf;
    871 
    872             do
    873             {
    874                *-- ptr = "0123456789"[integer % 10];
    875 
    876             } while ((integer /= 10) > 0);
    877 
    878             break;
    879 
    880          case json_double:
    881 
    882             ptr = buf;
    883 
    884             buf += sprintf (buf, "%g", value->u.dbl);
    885 
    886             if ((dot = strchr (ptr, ',')))
    887             {
    888                *dot = '.';
    889             }
    890             else if (!strchr (ptr, '.'))
    891             {
    892                *buf ++ = '.';
    893                *buf ++ = '0';
    894             }
    895 
    896             break;
    897 
    898          case json_boolean:
    899 
    900             if (value->u.boolean)
    901             {
    902                memcpy (buf, "true", 4);
    903                buf += 4;
    904             }
    905             else
    906             {
    907                memcpy (buf, "false", 5);
    908                buf += 5;
    909             }
    910 
    911             break;
    912 
    913          case json_null:
    914 
    915             memcpy (buf, "null", 4);
    916             buf += 4;
    917             break;
    918 
    919          default:
    920             break;
    921       };
    922 
    923       value = value->parent;
    924    }
    925 
    926    *buf = 0;
    927 }
    928 
    929 void json_builder_free (json_value * value)
    930 {
    931    json_value * cur_value;
    932 
    933    if (!value)
    934       return;
    935 
    936    value->parent = 0;
    937 
    938    while (value)
    939    {
    940       switch (value->type)
    941       {
    942          case json_array:
    943 
    944             if (!value->u.array.length)
    945             {
    946                free (value->u.array.values);
    947                break;
    948             }
    949 
    950             value = value->u.array.values [-- value->u.array.length];
    951             continue;
    952 
    953          case json_object:
    954 
    955             if (!value->u.object.length)
    956             {
    957                free (value->u.object.values);
    958                break;
    959             }
    960 
    961             -- value->u.object.length;
    962 
    963             if (((json_builder_value *) value)->is_builder_value)
    964             {
    965                /* Names are allocated separately for builder values.  In parser
    966                 * values, they are part of the same allocation as the values array
    967                 * itself.
    968                 */
    969                free (value->u.object.values [value->u.object.length].name);
    970             }
    971 
    972             value = value->u.object.values [value->u.object.length].value;
    973             continue;
    974 
    975          case json_string:
    976 
    977             free (value->u.string.ptr);
    978             break;
    979 
    980          default:
    981             break;
    982       };
    983 
    984       cur_value = value;
    985       value = value->parent;
    986       free (cur_value);
    987    }
    988 }
    989 
    990 
    991 
    992 
    993 
    994 
    995 
    996