Fossil

Check-in [130cc65c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:pulled in tonight's libcson changes, which halve the number of allocations needed for creating new JSON values.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json-multitag-test | json
Files: files | file ages | folders
SHA1:130cc65cb575071eb815a57691d15ece631aa245
User & Date: stephan 2011-10-07 02:14:42
Context
2011-10-07
02:16
merged in trunk [4b0f813b8c]. check-in: 39d9f837 user: stephan tags: json-multitag-test, json
02:14
pulled in tonight's libcson changes, which halve the number of allocations needed for creating new JSON values. check-in: 130cc65c user: stephan tags: json-multitag-test, json
2011-10-06
23:29
fixed a bug in the handling of /json/tag/find --raw format (caused by moving code w/o paying attention). Added a warning when the given tag is not found. check-in: be410090 user: stephan tags: json-multitag-test, json
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cson_amalgamation.c.

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
....
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064



2065
2066
2067
2068
2069
2070
2071
....
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
....
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524

2525
2526
2527
2528
2529
2530
2531
2532
2533
2534


2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
....
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
....
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
....
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
....
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
....
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
....
3082
3083
3084
3085
3086
3087
3088
3089

3090
3091
3092
3093
3094
3095
3096

3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128

3129
3130
3131





3132
3133
3134
3135
3136
3137
3138
....
4814
4815
4816
4817
4818
4819
4820

4821
4822
4823
4824
4825
4826
4827
4828
....
4839
4840
4841
4842
4843
4844
4845
























4846
4847
4848
4849
4850
4851
4852
....
4953
4954
4955
4956
4957
4958
4959







4960
4961
4962
4963
4964
4965
4966
const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
const cson_output_opt cson_output_opt_empty = cson_output_opt_empty_m;
const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;

static void cson_value_destroy_zero_it( cson_value * self );
static void cson_value_destroy_free( cson_value * self );
static void cson_value_destroy_object( cson_value * self );
static void cson_value_destroy_integer( cson_value * self );
/**
   If self is-a array then this function destroys its contents,
   else this function does nothing.
*/
static void cson_value_destroy_array( cson_value * self );

/**
   If self is-a string then this function destroys its contents,
   else this function does nothing.
*/
static void cson_value_destroy_string( cson_value * self );

static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_integer };
static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_free };
static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_string };
static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };

static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };

static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
static const cson_value cson_value_object_empty = { &cson_value_api_object, NULL, 0 };


struct cson_string
{
    unsigned int length;
};
#define cson_string_empty_m {0/*length*/}

/**
 
 Holds special shared "constant" (though they are non-const)
 values.
 
*/
static struct CSON_EMPTY_HOLDER_
................................................................................
void cson_value_destroy_zero_it( cson_value * self )
{
    if( self )
    {
        *self = cson_value_undef;
    }
}

/**
   If self is not null, free(self->value) is called.  *self is then
   overwritten to have the undefined type. self is not freed.

*/
void cson_value_destroy_free( cson_value * self )
{
    if(self) {
        if( self->value )
        {
            cson_free(self->value,"cson_value_destroy_free()");
        }
        *self = cson_value_undef;
    }
}



/**
   A key/value pair collection.

   Each of these objects owns its key/value pointers, and they
   are cleaned up by cson_kvp_clean().
*/
struct cson_kvp
{



    cson_string * key;
    cson_value * value;
};
#define cson_kvp_empty_m {NULL,NULL}
static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;

/** @def CSON_OBJECT_PROPS_SORT
................................................................................
#  define VALUE_T_IS_PTR 1
#  define LIST_T cson_kvp_list
#  define VALUE_T cson_kvp *
#  define VALUE_T_IS_PTR 1
#else
#endif

/*
  Reminders to self:

  - 20110126: moved cson_value_new() and cson_value_set_xxx() out of the
  public API because:

  a) They can be easily mis-used to cause memory leaks, even when used in
  a manner which seems relatively intuitive.

  b) Having them in the API prohibits us from eventually doing certain
  allocation optimizations like not allocating Booleans,
  Integer/Doubles with the value 0, or empty Strings. The main problem
  is that cson_value_set_xxx() cannot be implemented properly if we
  add that type of optimization.
*/

/**
   Allocates a new value with the "undefined" value and transfers
   ownership of it to the caller. Use The cson_value_set_xxx() family
   of functions to assign a typed value to it. It must eventually be
   destroyed, by the caller or its owning container, by passing it to
   cson_value_free().

   Returns NULL on allocation error.

   @see cson_value_new_array()
   @see cson_value_new_object()
   @see cson_value_new_string()
   @see cson_value_new_integer()
   @see cson_value_new_double()
   @see cson_value_new_bool()
   @see cson_value_free()
*/
static cson_value * cson_value_new();
/**
   Cleans any existing contents of val and sets its new value
   to the special NULL value.

   Returns 0 on success.

*/
#if 0
static int cson_value_set_null( cson_value * val );
#endif
/**
   Cleans any existing contents of val and sets its new value
   to v.

   Returns 0 on success.

*/
#if 0
static int cson_value_set_bool( cson_value * val, char v );
#endif
/**
   Cleans any existing contents of val and sets its new value
   to v.

   Returns 0 on success.

*/
static int cson_value_set_integer( cson_value * val, cson_int_t v );
/**
   Cleans any existing contents of val and sets its new value
   to v.

   Returns 0 on success.
*/
static int cson_value_set_double( cson_value * val, cson_double_t v );

/**
   Cleans any existing contents of val and sets its new value to
   str. On success, ownership of str is passed on to val. On error
   ownership is not changed.

   Returns 0 on success.

   If str is NULL, (!*str), or (!len) then this function does not
   allocate any memory for a new string, and cson_value_fetch_string()
   will return an empty string as opposed to a NULL string.
*/
static int cson_value_set_string( cson_value * val, char const * str, unsigned int len );


cson_value * cson_value_new()
{
    cson_value * v = (cson_value *)cson_malloc(sizeof(cson_value),"cson_value_new");
    if( v ) *v = cson_value_undef;
    return v;
}


void cson_value_free(cson_value *v)
{
    cson_refcount_decr( v );
................................................................................
            cson_counter_t const rc = val->refcount;
            val->api->cleanup(val);
            *val = cson_value_undef;
            val->refcount = rc;
        }
    }
}

static void cson_value_destroy_integer( cson_value * self )
{
    if( self )
    {
#if !CSON_VOID_PTR_IS_BIG
        cson_free(self->value,"cson_int_t");
#endif
        *self = cson_value_empty;
    }    
}
static int cson_value_set_integer( cson_value * val, cson_int_t v )
{
    if( ! val ) return cson_rc.ArgError;
    else
    {
#if CSON_VOID_PTR_IS_BIG
        cson_value_clean( val );
        val->value = (void *)v;
#else
        cson_int_t * iv = NULL;
        iv = (cson_int_t*)cson_malloc(sizeof(cson_int_t), "cson_int_t");
        if( ! iv ) return cson_rc.AllocError;
        cson_value_clean( val );
        *iv = v;
        val->value = iv;
#endif
        val->api = &cson_value_api_integer;
        return 0;
    }
}

static int cson_value_set_double( cson_value * val, cson_double_t v )
{
    if( ! val ) return cson_rc.ArgError;
    else
    {
        cson_double_t * rv = NULL;
        cson_value_clean( val );
        val->api = &cson_value_api_double;
        if( 0.0 != v )
        {
            /*
              Reminder: we can't re-use val if it alreay is-a double
              because we have no reference counting.
            */
            rv = (cson_double_t*)cson_malloc(sizeof(cson_double_t),"double");
            if( ! rv ) return cson_rc.AllocError;
        }
        if(NULL != rv) *rv = v;
        val->value = rv;
        return 0;
    }
}

static cson_string * cson_string_shared_empty()
{
    /**
       We have code in place elsewhere to avoid that
       cson_string_cstr(&bob) and cson_string_str(&bob) will misbehave
       by accessing the bytes directly after bob (which are undefined
       in this case).
    */
#if 0
    static cson_string bob[2] = {cson_string_empty_m,
                                 cson_string_empty_m/*trick to 0-init bob[0]'s tail*/};
    return &bob[0];
#else
    static cson_string bob = cson_string_empty_m;
    return &bob;
#endif
}

static int cson_value_set_string( cson_value * val, char const * str, unsigned int len )
{
    cson_string * jstr = NULL;
    if( ! val ) return cson_rc.ArgError;
    cson_value_clean( val );
    val->api = &cson_value_api_string;
    if( !str || !*str || !len )
    {
        val->value = cson_string_shared_empty();
        return 0;
    }
    else
    {
        jstr = cson_string_alloc( len );
        if( NULL == jstr ) return cson_rc.AllocError;
        else
        {
            if( len )
            {
                char * dest = cson_string_str( jstr );
                val->value = jstr;
                strncpy( dest, str, len );
            }
            /* else it's the empty string special value */
            return 0;
        }
    }
}


static cson_value * cson_value_array_alloc()
{
    cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_array");

    if( NULL != v )
    {
        cson_array * ar = (cson_array *)cson_malloc(sizeof(cson_array),"cson_array");
        if( ! ar )
        {
            cson_free(v,"cson_array");
            v = NULL;
        }
        else
        {


            *ar = cson_array_empty;
            *v = cson_value_array_empty;
            v->value = ar;
        }
    }
    return v;
}

static cson_value * cson_value_object_alloc()
{
    cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_object");
    if( NULL != v )
    {
        cson_object * obj = (cson_object*)cson_malloc(sizeof(cson_object),"cson_value");
        if( ! obj )
        {
            cson_free(v,"cson_value_object");
            v = NULL;
        }
        else
        {
            *obj = cson_object_empty;
            *v = cson_value_object_empty;
            v->value = obj;
        }
    }
    return v;
}

cson_value * cson_value_new_object()
{
    return cson_value_object_alloc();
................................................................................
    if( kvp )
    {
        cson_kvp_clean(kvp);
        cson_free(kvp,"cson_kvp");
    }
}

/**
   cson_value_api::destroy_value() impl for Object
   values. Cleans up self-owned memory and overwrites
   self to have the undefined value, but does not
   free self.

   If self->value == cson_string_shared_empty()
   then this function does not actually free it.
*/
static void cson_value_destroy_string( cson_value * self )
{
    if(self && self->value) {
        cson_string * obj = (cson_string *)self->value;
        if( obj != cson_string_shared_empty() )
        {
            cson_free(self->value,"cson_string");
        }
        *self = cson_value_undef;
    }
}


/**
   cson_value_api::destroy_value() impl for Object
   values. Cleans up self-owned memory and overwrites
   self to have the undefined value, but does not
   free self.
*/
static void cson_value_destroy_object( cson_value * self )
{
    if(self && self->value) {
        cson_object * obj = (cson_object *)self->value;
        assert( self->value == obj );
        cson_kvp_list_clean( &obj->kvp, cson_kvp_free );
        cson_free(self->value,"cson_object");
        *self = cson_value_undef;
    }
}

/**
   Cleans up the contents of ar->list, but does not free ar.

................................................................................
*/
static void cson_value_destroy_array( cson_value * self )
{
    cson_array * ar = cson_value_get_array(self);
    if(ar) {
        assert( self->value == ar );
        cson_array_clean( ar, 1 );
        cson_free(ar,"cson_array");
        *self = cson_value_undef;
    }
}


#if 0
static void cson_kvp_list_item_clean( void * kvp );
................................................................................
            case CSON_TYPE_BOOL: {
              char b = 0;
              cson_value_fetch_bool( val, &b );
              i = b;
              break;
            }
            case CSON_TYPE_INTEGER: {
#if CSON_VOID_PTR_IS_BIG
                i = (cson_int_t)val->value;
#else
                cson_int_t const * x = (cson_int_t const *)val->value;
                i = x ? *x : 0;
#endif
                break;
            }
            case CSON_TYPE_DOUBLE: {
              cson_double_t d = 0.0;
              cson_value_fetch_double( val, &d );
              i = (cson_int_t)d;
              break;
................................................................................
          case CSON_TYPE_INTEGER: {
              cson_int_t i = 0;
              cson_value_fetch_integer( val, &i );
              d = i;
              break;
          }
          case CSON_TYPE_DOUBLE: {
              cson_double_t const* dv = (cson_double_t const *)val->value;
              d = dv ? *dv : 0.0;
              break;
          }
          default:
              rc = cson_rc.TypeError;
              break;
        }
................................................................................

int cson_value_fetch_object( cson_value const * val, cson_object ** obj )
{
    if( ! val ) return cson_rc.ArgError;
    else if( ! cson_value_is_object(val) ) return cson_rc.TypeError;
    else
    {
        if(obj) *obj = (cson_object*)val->value;
        return 0;
    }
}
cson_object * cson_value_get_object( cson_value const * v )
{
    cson_object * obj = NULL;
    cson_value_fetch_object( v, &obj );
    return obj;
}

int cson_value_fetch_array( cson_value const * val, cson_array ** ar)
{
    if( ! val ) return cson_rc.ArgError;
    else if( ! cson_value_is_array(val) ) return cson_rc.TypeError;
    else
    {
        if(ar) *ar = (cson_array*)val->value;
        return 0;
    }
}

cson_array * cson_value_get_array( cson_value const * v )
{
    cson_array * ar = NULL;
................................................................................
}

cson_value * cson_value_new_integer( cson_int_t v )
{
    if( 0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
    else
    {
        cson_value * c = cson_value_new();

        if( c )
        {
            if( 0 != cson_value_set_integer( c, v ) )
            {
                cson_value_free(c);
                c = NULL;
            }

        }
        return c;
    }
}

cson_value * cson_value_new_double( cson_double_t v )
{
    if( 0.0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
    else
    {
        cson_value * c = cson_value_new();
        if( c )
        {
            if( 0 != cson_value_set_double( c, v ) )
            {
                cson_value_free(c);
                c = NULL;
            }
        }
        return c;
    }
}
cson_value * cson_value_new_string( char const * str, unsigned int len )
{
    if( !str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
    else
    {
        cson_value * c = cson_value_new();
        if( c )
        {
            if( 0 != cson_value_set_string( c, str, len ) )
            {

                cson_value_free(c);
                c = NULL;
            }





        }
        return c;
    }
}

int cson_array_value_fetch( cson_array const * ar, unsigned int pos, cson_value ** v )
{
................................................................................
{
    if( NULL == orig ) return NULL;
    else
    {
        switch( orig->api->typeID )
        {
          case CSON_TYPE_UNDEF:

              return cson_value_new();
          case CSON_TYPE_NULL:
              return cson_value_null();
          case CSON_TYPE_BOOL:
              return cson_value_new_bool( cson_value_get_bool( orig ) );
          case CSON_TYPE_INTEGER:
              return cson_value_new_integer( cson_value_get_integer( orig ) );
              break;
................................................................................
          case CSON_TYPE_OBJECT:
              return cson_value_clone_object( orig );
        }
        assert( 0 && "We can't get this far." );
        return NULL;
    }
}

























#if 0
/* i'm not happy with this... */
char * cson_pod_to_string( cson_value const * orig )
{
    if( ! orig ) return NULL;
    else
................................................................................
#if defined(__cplusplus)
} /*extern "C"*/
#endif

#undef MARKER
#undef CSON_OBJECT_PROPS_SORT
#undef CSON_OBJECT_PROPS_SORT_USE_LENGTH







/* end file ./cson.c */
/* begin file ./cson_lists.h */
/* Auto-generated from cson_list.h. Edit at your own risk! */
unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n )
{
    if( !self ) return 0;
    else if(0 == n)







<

<






<
<
<
<
<
<



|
|
|




>













|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









>
>
>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







 








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
>


<
<
<
<
<
<
<
<
>
>
|
<
<
<






|


|
|
<
<
<
<
<
<
|
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













<







 







<







 







|
|
|
|
|
|







 







|







 







|













|


|







 







|
>


<
<
<
<
<
>










|


|
<
<
<
<






|


|


|
<
>
|
|
<
>
>
>
>
>







 







>
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>







1568
1569
1570
1571
1572
1573
1574

1575

1576
1577
1578
1579
1580
1581






1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
....
2024
2025
2026
2027
2028
2029
2030


















2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
....
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330

2331
2332
2333
2334
2335
2336
2337
....
2389
2390
2391
2392
2393
2394
2395
2396






































































































2397
2398

2399
2400
2401








2402
2403
2404



2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415






2416



2417
2418
2419
2420
2421
2422
2423
....
2467
2468
2469
2470
2471
2472
2473





















2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486

2487
2488
2489
2490
2491
2492
2493
....
2534
2535
2536
2537
2538
2539
2540

2541
2542
2543
2544
2545
2546
2547
....
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
....
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
....
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
....
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926





2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941




2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954

2955
2956
2957

2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
....
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
....
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
....
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
const cson_output_opt cson_output_opt_empty = cson_output_opt_empty_m;
const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;

static void cson_value_destroy_zero_it( cson_value * self );

static void cson_value_destroy_object( cson_value * self );

/**
   If self is-a array then this function destroys its contents,
   else this function does nothing.
*/
static void cson_value_destroy_array( cson_value * self );







static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_zero_it };
static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };

static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };
static const cson_value cson_value_null_empty = { &cson_value_api_null, NULL, 0 };
static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
static const cson_value cson_value_object_empty = { &cson_value_api_object, NULL, 0 };


struct cson_string
{
    unsigned int length;
};
#define cson_string_empty_m {0/*length*/}
static const cson_string cson_string_empty = cson_string_empty_m;
/**
 
 Holds special shared "constant" (though they are non-const)
 values.
 
*/
static struct CSON_EMPTY_HOLDER_
................................................................................
void cson_value_destroy_zero_it( cson_value * self )
{
    if( self )
    {
        *self = cson_value_undef;
    }
}



















/**
   A key/value pair collection.

   Each of these objects owns its key/value pointers, and they
   are cleaned up by cson_kvp_clean().
*/
struct cson_kvp
{
    /* FIXME: switch to cson_value keys. Calling cson_string_value()
       on one of these guys will read invalid memory.
     */
    cson_string * key;
    cson_value * value;
};
#define cson_kvp_empty_m {NULL,NULL}
static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;

/** @def CSON_OBJECT_PROPS_SORT
................................................................................
#  define VALUE_T_IS_PTR 1
#  define LIST_T cson_kvp_list
#  define VALUE_T cson_kvp *
#  define VALUE_T_IS_PTR 1
#else
#endif

/**
   Allocates a new value of the specified type ownership of it to the
   caller. It must eventually be destroyed, by the caller or its
   owning container, by passing it to cson_value_free() or transfering
   ownership to a container.

   extra is only valid for type CSON_TYPE_STRING, and must be the length
   of the string to allocate + 1 byte (for the NUL).

   The returned value->api member will be set appropriately and
   val->value will be set to point to the memory allocated to hold the
   native value type. Use the internal CSON_CAST() family of macros to
   convert them.

   Returns NULL on allocation error.

   @see cson_value_new_array()
   @see cson_value_new_object()
   @see cson_value_new_string()
   @see cson_value_new_integer()
   @see cson_value_new_double()
   @see cson_value_new_bool()
   @see cson_value_free()
*/
static cson_value * cson_value_new(cson_type_id t, size_t extra);

#define CSON_CAST(T,V) ((T*)((V)->value))
#define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value)))
#define CSON_INT(V) ((cson_int_t*)(V)->value)
#define CSON_DBL(V) CSON_CAST(cson_double_t,(V))
#define CSON_STR(V) CSON_CAST(cson_string,(V))
#define CSON_OBJ(V) CSON_CAST(cson_object,(V))
#define CSON_ARRAY(V) CSON_CAST(cson_array,(V))

cson_value * cson_value_new(cson_type_id t, size_t extra)
{
    static const size_t vsz = sizeof(cson_value);
    const size_t sz = vsz + extra;
    size_t tx = 0;
    cson_value def = cson_value_undef;
    cson_value * v = NULL;
    char const * reason = "cson_value_new";
    switch(t)
    {
      case CSON_TYPE_ARRAY:
          assert( 0 == extra );
          def = cson_value_array_empty;
          tx = sizeof(cson_array);
          reason = "cson_value:array";
          break;
      case CSON_TYPE_DOUBLE:
          assert( 0 == extra );
          def = cson_value_double_empty;
          tx = sizeof(cson_double_t);
          reason = "cson_value:double";
          break;
      case CSON_TYPE_INTEGER:
          assert( 0 == extra );
          def = cson_value_integer_empty;
          tx = sizeof(cson_int_t);
          reason = "cson_value:int";
          break;
      case CSON_TYPE_STRING:
          assert( 0 != extra );
          def = cson_value_string_empty;
          tx = sizeof(cson_string);
          reason = "cson_value:string";
          break;
      case CSON_TYPE_OBJECT:
          assert( 0 == extra );
          def = cson_value_object_empty;
          tx = sizeof(cson_object);
          reason = "cson_value:object";
          break;
      default:
          assert(0 && "Unhandled type in cson_value_new()!");
          return NULL;
    }
    assert( def.api->typeID != CSON_TYPE_UNDEF );
    v = (cson_value *)cson_malloc(sz+tx, reason);
    if( v ) {
        *v = def;
        if(tx || extra){
            memset(v+1, 0, tx + extra);
            v->value = (void *)(v+1);
        }
    }

    return v;
}


void cson_value_free(cson_value *v)
{
    cson_refcount_decr( v );
................................................................................
            cson_counter_t const rc = val->refcount;
            val->api->cleanup(val);
            *val = cson_value_undef;
            val->refcount = rc;
        }
    }
}







































































































static cson_value * cson_value_array_alloc()
{

    cson_value * v = cson_value_new(CSON_TYPE_ARRAY,0);
    if( NULL != v )
    {








        cson_array * ar = CSON_ARRAY(v);
        assert(NULL != ar);
        *ar = cson_array_empty;



    }
    return v;
}

static cson_value * cson_value_object_alloc()
{
    cson_value * v = cson_value_new(CSON_TYPE_OBJECT,0);
    if( NULL != v )
    {
        cson_object * obj = CSON_OBJ(v);
        assert(NULL != obj);






        *obj = cson_object_empty;



    }
    return v;
}

cson_value * cson_value_new_object()
{
    return cson_value_object_alloc();
................................................................................
    if( kvp )
    {
        cson_kvp_clean(kvp);
        cson_free(kvp,"cson_kvp");
    }
}























/**
   cson_value_api::destroy_value() impl for Object
   values. Cleans up self-owned memory and overwrites
   self to have the undefined value, but does not
   free self.
*/
static void cson_value_destroy_object( cson_value * self )
{
    if(self && self->value) {
        cson_object * obj = (cson_object *)self->value;
        assert( self->value == obj );
        cson_kvp_list_clean( &obj->kvp, cson_kvp_free );

        *self = cson_value_undef;
    }
}

/**
   Cleans up the contents of ar->list, but does not free ar.

................................................................................
*/
static void cson_value_destroy_array( cson_value * self )
{
    cson_array * ar = cson_value_get_array(self);
    if(ar) {
        assert( self->value == ar );
        cson_array_clean( ar, 1 );

        *self = cson_value_undef;
    }
}


#if 0
static void cson_kvp_list_item_clean( void * kvp );
................................................................................
            case CSON_TYPE_BOOL: {
              char b = 0;
              cson_value_fetch_bool( val, &b );
              i = b;
              break;
            }
            case CSON_TYPE_INTEGER: {
                cson_int_t const * x = CSON_INT(val);
                if(!x)
                {
                    assert( val == &CSON_SPECIAL_VALUES[CSON_VAL_INT_0] );
                }
                i = x ? *x : 0;
                break;
            }
            case CSON_TYPE_DOUBLE: {
              cson_double_t d = 0.0;
              cson_value_fetch_double( val, &d );
              i = (cson_int_t)d;
              break;
................................................................................
          case CSON_TYPE_INTEGER: {
              cson_int_t i = 0;
              cson_value_fetch_integer( val, &i );
              d = i;
              break;
          }
          case CSON_TYPE_DOUBLE: {
              cson_double_t const* dv = CSON_DBL(val);
              d = dv ? *dv : 0.0;
              break;
          }
          default:
              rc = cson_rc.TypeError;
              break;
        }
................................................................................

int cson_value_fetch_object( cson_value const * val, cson_object ** obj )
{
    if( ! val ) return cson_rc.ArgError;
    else if( ! cson_value_is_object(val) ) return cson_rc.TypeError;
    else
    {
        if(obj) *obj = CSON_OBJ(val);
        return 0;
    }
}
cson_object * cson_value_get_object( cson_value const * v )
{
    cson_object * obj = NULL;
    cson_value_fetch_object( v, &obj );
    return obj;
}

int cson_value_fetch_array( cson_value const * val, cson_array ** ar)
{
    if( ! val ) return cson_rc.ArgError;
    else if( !cson_value_is_array(val) ) return cson_rc.TypeError;
    else
    {
        if(ar) *ar = CSON_ARRAY(val);
        return 0;
    }
}

cson_array * cson_value_get_array( cson_value const * v )
{
    cson_array * ar = NULL;
................................................................................
}

cson_value * cson_value_new_integer( cson_int_t v )
{
    if( 0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
    else
    {
        cson_value * c = cson_value_new(CSON_TYPE_INTEGER,0);

        if( c )
        {





            *CSON_INT(c) = v;
        }
        return c;
    }
}

cson_value * cson_value_new_double( cson_double_t v )
{
    if( 0.0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
    else
    {
        cson_value * c = cson_value_new(CSON_TYPE_DOUBLE,0);
        if( c )
        {
            *CSON_DBL(c) = v;




        }
        return c;
    }
}
cson_value * cson_value_new_string( char const * str, unsigned int len )
{
    if( !str || !*str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
    else
    {
        cson_value * c = cson_value_new(CSON_TYPE_STRING, len + 1/*NUL byte*/);
        if( c )
        {
            char * dest = NULL;

            cson_string * s = CSON_STR(c);
            *s = cson_string_empty;
            assert( NULL != s );

            s->length = len;
            dest = cson_string_str(s);
            assert( NULL != dest );
            memcpy( dest, str, len );
            dest[len] = 0;
        }
        return c;
    }
}

int cson_array_value_fetch( cson_array const * ar, unsigned int pos, cson_value ** v )
{
................................................................................
{
    if( NULL == orig ) return NULL;
    else
    {
        switch( orig->api->typeID )
        {
          case CSON_TYPE_UNDEF:
              assert(0 && "This should never happen.");
              return NULL;
          case CSON_TYPE_NULL:
              return cson_value_null();
          case CSON_TYPE_BOOL:
              return cson_value_new_bool( cson_value_get_bool( orig ) );
          case CSON_TYPE_INTEGER:
              return cson_value_new_integer( cson_value_get_integer( orig ) );
              break;
................................................................................
          case CSON_TYPE_OBJECT:
              return cson_value_clone_object( orig );
        }
        assert( 0 && "We can't get this far." );
        return NULL;
    }
}

cson_value * cson_string_value(cson_string const * s)
{
    return s
        ? CSON_VCAST(s)
        : NULL;
}

cson_value * cson_object_value(cson_object const * s)
{
    return s
        ? CSON_VCAST(s)
        : NULL;
}


cson_value * cson_array_value(cson_array const * s)
{
    return s
        ? CSON_VCAST(s)
        : NULL;
}



#if 0
/* i'm not happy with this... */
char * cson_pod_to_string( cson_value const * orig )
{
    if( ! orig ) return NULL;
    else
................................................................................
#if defined(__cplusplus)
} /*extern "C"*/
#endif

#undef MARKER
#undef CSON_OBJECT_PROPS_SORT
#undef CSON_OBJECT_PROPS_SORT_USE_LENGTH
#undef CSON_CAST
#undef CSON_INT
#undef CSON_DBL
#undef CSON_STR
#undef CSON_OBJ
#undef CSON_ARRAY
#undef CSON_VCAST
/* end file ./cson.c */
/* begin file ./cson_lists.h */
/* Auto-generated from cson_list.h. Edit at your own risk! */
unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n )
{
    if( !self ) return 0;
    else if(0 == n)

Changes to src/cson_amalgamation.h.

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
841
842
843
844
845
846
847


848
849
850
851
852

853
854
855
856
857
858
859
...
863
864
865
866
867
868
869

870
871
872
873
874
875
876
....
1938
1939
1940
1941
1942
1943
1944
























1945
1946
1947
1948
1949
1950
1951
#define CSON_INT_T_PFMT "lld"
#else 
typedef long cson_int_t;
#define CSON_INT_T_SFMT "ld"
#define CSON_INT_T_PFMT "ld"
#endif

/** @def CSON_VOID_PTR_IS_BIG

ONLY define this to a true value if you know that

(sizeof(cson_int_t) <= sizeof(void*))

If that is the case, cson does not need to dynamically
allocate integers. However, enabling this may cause
compilation warnings in 32-bit builds even though the code
being warned about cannot ever be called. To get around such
warnings, when building on a 64-bit environment you can define
this to 1 to get "big" integer support. HOWEVER, all clients must
also use the same value for this macro. If i knew a halfway reliable
way to determine this automatically at preprocessor-time, i would
automate this. We might be able to do halfway reliably by looking
for a large INT_MAX value?
*/
#if !defined(CSON_VOID_PTR_IS_BIG)

/* Largely taken from http://predef.sourceforge.net/prearch.html

See also: http://poshlib.hookatooka.com/poshlib/trac.cgi/browser/posh.h
*/
#  if defined(_WIN64) || defined(__LP64__)/*gcc*/ \
    || defined(_M_X64) || defined(__amd64__) || defined(__amd64) \
    ||  defined(__x86_64__) || defined(__x86_64) \
    || defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) \
    || defined(_M_IA64) \
    || defined(__sparc_v9__) || defined(__sparcv9) || defined(_ADDR64) \
    || defined(__64BIT__)
#    define CSON_VOID_PTR_IS_BIG 1
#  else
#    define CSON_VOID_PTR_IS_BIG 0
#  endif
#endif

/** @typedef double_or_long_double cson_double_t

This is the type of double value used by the library.
It is only lightly tested with long double, and when using
long double the memory requirements for such values goes
up.
*/
................................................................................
   undef or null: false
   
   boolean: same
   
   integer, double: 0 or 0.0 == false, else true
   
   object, array: true



   Returns 0 on success and assigns *v (if v is not NULL) to either 0 or 1.
   On error (val is NULL) then v is not modified.
*/
int cson_value_fetch_bool( cson_value const * val, char * v );

/**
   Similar to cson_value_fetch_bool(), but fetches an integer value.

   The conversion, if any, depends on the concrete type of val:

   NULL, null, undefined: *v is set to 0 and 0 is returned.
   
................................................................................
   conversion was possible.

   integer: *v is set to the int value and 0 is returned.
   
   double: *v is set to the value truncated to int and 0 is returned.
*/
int cson_value_fetch_integer( cson_value const * val, cson_int_t * v );

/**
   The same conversions and return values as
   cson_value_fetch_integer(), except that the roles of int/double are
   swapped.
*/
int cson_value_fetch_double( cson_value const * val, cson_double_t * v );

................................................................................
   Returns NULL if orig is NULL or if cloning fails. Assuming that
   orig is in a valid state, the only "likely" error case is that an
   allocation fails while constructing the clone. In other words, if
   cloning fails due to something other than an allocation error then
   either orig is in an invalid state or there is a bug.
*/
cson_value * cson_value_clone( cson_value const * orig );

























/* LICENSE

This software's source code, including accompanying documentation and
demonstration applications, are licensed under the following
conditions...








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>





>







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







55
56
57
58
59
60
61




































62
63
64
65
66
67
68
...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
....
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
#define CSON_INT_T_PFMT "lld"
#else 
typedef long cson_int_t;
#define CSON_INT_T_SFMT "ld"
#define CSON_INT_T_PFMT "ld"
#endif





































/** @typedef double_or_long_double cson_double_t

This is the type of double value used by the library.
It is only lightly tested with long double, and when using
long double the memory requirements for such values goes
up.
*/
................................................................................
   undef or null: false
   
   boolean: same
   
   integer, double: 0 or 0.0 == false, else true
   
   object, array: true

   string: length-0 string is false, else true.

   Returns 0 on success and assigns *v (if v is not NULL) to either 0 or 1.
   On error (val is NULL) then v is not modified.
*/
int cson_value_fetch_bool( cson_value const * val, char * v );

/**
   Similar to cson_value_fetch_bool(), but fetches an integer value.

   The conversion, if any, depends on the concrete type of val:

   NULL, null, undefined: *v is set to 0 and 0 is returned.
   
................................................................................
   conversion was possible.

   integer: *v is set to the int value and 0 is returned.
   
   double: *v is set to the value truncated to int and 0 is returned.
*/
int cson_value_fetch_integer( cson_value const * val, cson_int_t * v );

/**
   The same conversions and return values as
   cson_value_fetch_integer(), except that the roles of int/double are
   swapped.
*/
int cson_value_fetch_double( cson_value const * val, cson_double_t * v );

................................................................................
   Returns NULL if orig is NULL or if cloning fails. Assuming that
   orig is in a valid state, the only "likely" error case is that an
   allocation fails while constructing the clone. In other words, if
   cloning fails due to something other than an allocation error then
   either orig is in an invalid state or there is a bug.
*/
cson_value * cson_value_clone( cson_value const * orig );

/**
   Returns the value handle associated with s. The handle itself owns
   s, and ownership of the handle is not changed by calling this
   function. If the returned handle is part of a container, calling
   cson_value_free() on the returned handle invoked undefined
   behaviour (quite possibly downstream when the container tries to
   use it).

   This function only returns NULL if s. is NULL.
*/
cson_value * cson_string_value(cson_string const * s);
/**
   The Object form of cson_string_value(). See that function
   for full details.
*/
cson_value * cson_object_value(cson_object const * s);

/**
   The Array form of cson_string_value(). See that function
   for full details.
*/
cson_value * cson_array_value(cson_array const * s);


/* LICENSE

This software's source code, including accompanying documentation and
demonstration applications, are licensed under the following
conditions...