Fossil SCM

pulled in tonight's libcson changes, which halve the number of allocations needed for creating new JSON values.

stephan 2011-10-07 02:14 UTC json-multitag-test
Commit 130cc65cb575071eb815a57691d15ece631aa245
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1570,35 +1570,28 @@
15701570
const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
15711571
const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
15721572
const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
15731573
15741574
static void cson_value_destroy_zero_it( cson_value * self );
1575
-static void cson_value_destroy_free( cson_value * self );
15761575
static void cson_value_destroy_object( cson_value * self );
1577
-static void cson_value_destroy_integer( cson_value * self );
15781576
/**
15791577
If self is-a array then this function destroys its contents,
15801578
else this function does nothing.
15811579
*/
15821580
static void cson_value_destroy_array( cson_value * self );
15831581
1584
-/**
1585
- If self is-a string then this function destroys its contents,
1586
- else this function does nothing.
1587
-*/
1588
-static void cson_value_destroy_string( cson_value * self );
1589
-
15901582
static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
15911583
static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
15921584
static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
1593
-static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_integer };
1594
-static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_free };
1595
-static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_string };
1585
+static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_zero_it };
1586
+static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_zero_it };
1587
+static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_zero_it };
15961588
static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
15971589
static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };
15981590
15991591
static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };
1592
+static const cson_value cson_value_null_empty = { &cson_value_api_null, NULL, 0 };
16001593
static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
16011594
static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
16021595
static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
16031596
static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
16041597
static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
@@ -1608,11 +1601,11 @@
16081601
struct cson_string
16091602
{
16101603
unsigned int length;
16111604
};
16121605
#define cson_string_empty_m {0/*length*/}
1613
-
1606
+static const cson_string cson_string_empty = cson_string_empty_m;
16141607
/**
16151608
16161609
Holds special shared "constant" (though they are non-const)
16171610
values.
16181611
@@ -2033,37 +2026,22 @@
20332026
if( self )
20342027
{
20352028
*self = cson_value_undef;
20362029
}
20372030
}
2038
-
2039
-/**
2040
- If self is not null, free(self->value) is called. *self is then
2041
- overwritten to have the undefined type. self is not freed.
2042
-
2043
-*/
2044
-void cson_value_destroy_free( cson_value * self )
2045
-{
2046
- if(self) {
2047
- if( self->value )
2048
- {
2049
- cson_free(self->value,"cson_value_destroy_free()");
2050
- }
2051
- *self = cson_value_undef;
2052
- }
2053
-}
2054
-
2055
-
20562031
20572032
/**
20582033
A key/value pair collection.
20592034
20602035
Each of these objects owns its key/value pointers, and they
20612036
are cleaned up by cson_kvp_clean().
20622037
*/
20632038
struct cson_kvp
20642039
{
2040
+ /* FIXME: switch to cson_value keys. Calling cson_string_value()
2041
+ on one of these guys will read invalid memory.
2042
+ */
20652043
cson_string * key;
20662044
cson_value * value;
20672045
};
20682046
#define cson_kvp_empty_m {NULL,NULL}
20692047
static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;
@@ -2261,32 +2239,23 @@
22612239
# define VALUE_T cson_kvp *
22622240
# define VALUE_T_IS_PTR 1
22632241
#else
22642242
#endif
22652243
2266
-/*
2267
- Reminders to self:
2268
-
2269
- - 20110126: moved cson_value_new() and cson_value_set_xxx() out of the
2270
- public API because:
2271
-
2272
- a) They can be easily mis-used to cause memory leaks, even when used in
2273
- a manner which seems relatively intuitive.
2274
-
2275
- b) Having them in the API prohibits us from eventually doing certain
2276
- allocation optimizations like not allocating Booleans,
2277
- Integer/Doubles with the value 0, or empty Strings. The main problem
2278
- is that cson_value_set_xxx() cannot be implemented properly if we
2279
- add that type of optimization.
2280
-*/
2281
-
22822244
/**
2283
- Allocates a new value with the "undefined" value and transfers
2284
- ownership of it to the caller. Use The cson_value_set_xxx() family
2285
- of functions to assign a typed value to it. It must eventually be
2286
- destroyed, by the caller or its owning container, by passing it to
2287
- cson_value_free().
2245
+ Allocates a new value of the specified type ownership of it to the
2246
+ caller. It must eventually be destroyed, by the caller or its
2247
+ owning container, by passing it to cson_value_free() or transfering
2248
+ ownership to a container.
2249
+
2250
+ extra is only valid for type CSON_TYPE_STRING, and must be the length
2251
+ of the string to allocate + 1 byte (for the NUL).
2252
+
2253
+ The returned value->api member will be set appropriately and
2254
+ val->value will be set to point to the memory allocated to hold the
2255
+ native value type. Use the internal CSON_CAST() family of macros to
2256
+ convert them.
22882257
22892258
Returns NULL on allocation error.
22902259
22912260
@see cson_value_new_array()
22922261
@see cson_value_new_object()
@@ -2294,65 +2263,73 @@
22942263
@see cson_value_new_integer()
22952264
@see cson_value_new_double()
22962265
@see cson_value_new_bool()
22972266
@see cson_value_free()
22982267
*/
2299
-static cson_value * cson_value_new();
2300
-/**
2301
- Cleans any existing contents of val and sets its new value
2302
- to the special NULL value.
2303
-
2304
- Returns 0 on success.
2305
-
2306
-*/
2307
-#if 0
2308
-static int cson_value_set_null( cson_value * val );
2309
-#endif
2310
-/**
2311
- Cleans any existing contents of val and sets its new value
2312
- to v.
2313
-
2314
- Returns 0 on success.
2315
-
2316
-*/
2317
-#if 0
2318
-static int cson_value_set_bool( cson_value * val, char v );
2319
-#endif
2320
-/**
2321
- Cleans any existing contents of val and sets its new value
2322
- to v.
2323
-
2324
- Returns 0 on success.
2325
-
2326
-*/
2327
-static int cson_value_set_integer( cson_value * val, cson_int_t v );
2328
-/**
2329
- Cleans any existing contents of val and sets its new value
2330
- to v.
2331
-
2332
- Returns 0 on success.
2333
-*/
2334
-static int cson_value_set_double( cson_value * val, cson_double_t v );
2335
-
2336
-/**
2337
- Cleans any existing contents of val and sets its new value to
2338
- str. On success, ownership of str is passed on to val. On error
2339
- ownership is not changed.
2340
-
2341
- Returns 0 on success.
2342
-
2343
- If str is NULL, (!*str), or (!len) then this function does not
2344
- allocate any memory for a new string, and cson_value_fetch_string()
2345
- will return an empty string as opposed to a NULL string.
2346
-*/
2347
-static int cson_value_set_string( cson_value * val, char const * str, unsigned int len );
2348
-
2349
-
2350
-cson_value * cson_value_new()
2351
-{
2352
- cson_value * v = (cson_value *)cson_malloc(sizeof(cson_value),"cson_value_new");
2353
- if( v ) *v = cson_value_undef;
2268
+static cson_value * cson_value_new(cson_type_id t, size_t extra);
2269
+
2270
+#define CSON_CAST(T,V) ((T*)((V)->value))
2271
+#define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value)))
2272
+#define CSON_INT(V) ((cson_int_t*)(V)->value)
2273
+#define CSON_DBL(V) CSON_CAST(cson_double_t,(V))
2274
+#define CSON_STR(V) CSON_CAST(cson_string,(V))
2275
+#define CSON_OBJ(V) CSON_CAST(cson_object,(V))
2276
+#define CSON_ARRAY(V) CSON_CAST(cson_array,(V))
2277
+
2278
+cson_value * cson_value_new(cson_type_id t, size_t extra)
2279
+{
2280
+ static const size_t vsz = sizeof(cson_value);
2281
+ const size_t sz = vsz + extra;
2282
+ size_t tx = 0;
2283
+ cson_value def = cson_value_undef;
2284
+ cson_value * v = NULL;
2285
+ char const * reason = "cson_value_new";
2286
+ switch(t)
2287
+ {
2288
+ case CSON_TYPE_ARRAY:
2289
+ assert( 0 == extra );
2290
+ def = cson_value_array_empty;
2291
+ tx = sizeof(cson_array);
2292
+ reason = "cson_value:array";
2293
+ break;
2294
+ case CSON_TYPE_DOUBLE:
2295
+ assert( 0 == extra );
2296
+ def = cson_value_double_empty;
2297
+ tx = sizeof(cson_double_t);
2298
+ reason = "cson_value:double";
2299
+ break;
2300
+ case CSON_TYPE_INTEGER:
2301
+ assert( 0 == extra );
2302
+ def = cson_value_integer_empty;
2303
+ tx = sizeof(cson_int_t);
2304
+ reason = "cson_value:int";
2305
+ break;
2306
+ case CSON_TYPE_STRING:
2307
+ assert( 0 != extra );
2308
+ def = cson_value_string_empty;
2309
+ tx = sizeof(cson_string);
2310
+ reason = "cson_value:string";
2311
+ break;
2312
+ case CSON_TYPE_OBJECT:
2313
+ assert( 0 == extra );
2314
+ def = cson_value_object_empty;
2315
+ tx = sizeof(cson_object);
2316
+ reason = "cson_value:object";
2317
+ break;
2318
+ default:
2319
+ assert(0 && "Unhandled type in cson_value_new()!");
2320
+ return NULL;
2321
+ }
2322
+ assert( def.api->typeID != CSON_TYPE_UNDEF );
2323
+ v = (cson_value *)cson_malloc(sz+tx, reason);
2324
+ if( v ) {
2325
+ *v = def;
2326
+ if(tx || extra){
2327
+ memset(v+1, 0, tx + extra);
2328
+ v->value = (void *)(v+1);
2329
+ }
2330
+ }
23542331
return v;
23552332
}
23562333
23572334
23582335
void cson_value_free(cson_value *v)
@@ -2414,151 +2391,31 @@
24142391
*val = cson_value_undef;
24152392
val->refcount = rc;
24162393
}
24172394
}
24182395
}
2419
-
2420
-static void cson_value_destroy_integer( cson_value * self )
2421
-{
2422
- if( self )
2423
- {
2424
-#if !CSON_VOID_PTR_IS_BIG
2425
- cson_free(self->value,"cson_int_t");
2426
-#endif
2427
- *self = cson_value_empty;
2428
- }
2429
-}
2430
-static int cson_value_set_integer( cson_value * val, cson_int_t v )
2431
-{
2432
- if( ! val ) return cson_rc.ArgError;
2433
- else
2434
- {
2435
-#if CSON_VOID_PTR_IS_BIG
2436
- cson_value_clean( val );
2437
- val->value = (void *)v;
2438
-#else
2439
- cson_int_t * iv = NULL;
2440
- iv = (cson_int_t*)cson_malloc(sizeof(cson_int_t), "cson_int_t");
2441
- if( ! iv ) return cson_rc.AllocError;
2442
- cson_value_clean( val );
2443
- *iv = v;
2444
- val->value = iv;
2445
-#endif
2446
- val->api = &cson_value_api_integer;
2447
- return 0;
2448
- }
2449
-}
2450
-
2451
-static int cson_value_set_double( cson_value * val, cson_double_t v )
2452
-{
2453
- if( ! val ) return cson_rc.ArgError;
2454
- else
2455
- {
2456
- cson_double_t * rv = NULL;
2457
- cson_value_clean( val );
2458
- val->api = &cson_value_api_double;
2459
- if( 0.0 != v )
2460
- {
2461
- /*
2462
- Reminder: we can't re-use val if it alreay is-a double
2463
- because we have no reference counting.
2464
- */
2465
- rv = (cson_double_t*)cson_malloc(sizeof(cson_double_t),"double");
2466
- if( ! rv ) return cson_rc.AllocError;
2467
- }
2468
- if(NULL != rv) *rv = v;
2469
- val->value = rv;
2470
- return 0;
2471
- }
2472
-}
2473
-
2474
-static cson_string * cson_string_shared_empty()
2475
-{
2476
- /**
2477
- We have code in place elsewhere to avoid that
2478
- cson_string_cstr(&bob) and cson_string_str(&bob) will misbehave
2479
- by accessing the bytes directly after bob (which are undefined
2480
- in this case).
2481
- */
2482
-#if 0
2483
- static cson_string bob[2] = {cson_string_empty_m,
2484
- cson_string_empty_m/*trick to 0-init bob[0]'s tail*/};
2485
- return &bob[0];
2486
-#else
2487
- static cson_string bob = cson_string_empty_m;
2488
- return &bob;
2489
-#endif
2490
-}
2491
-
2492
-static int cson_value_set_string( cson_value * val, char const * str, unsigned int len )
2493
-{
2494
- cson_string * jstr = NULL;
2495
- if( ! val ) return cson_rc.ArgError;
2496
- cson_value_clean( val );
2497
- val->api = &cson_value_api_string;
2498
- if( !str || !*str || !len )
2499
- {
2500
- val->value = cson_string_shared_empty();
2501
- return 0;
2502
- }
2503
- else
2504
- {
2505
- jstr = cson_string_alloc( len );
2506
- if( NULL == jstr ) return cson_rc.AllocError;
2507
- else
2508
- {
2509
- if( len )
2510
- {
2511
- char * dest = cson_string_str( jstr );
2512
- val->value = jstr;
2513
- strncpy( dest, str, len );
2514
- }
2515
- /* else it's the empty string special value */
2516
- return 0;
2517
- }
2518
- }
2519
-}
2520
-
25212396
25222397
static cson_value * cson_value_array_alloc()
25232398
{
2524
- cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_array");
2399
+ cson_value * v = cson_value_new(CSON_TYPE_ARRAY,0);
25252400
if( NULL != v )
25262401
{
2527
- cson_array * ar = (cson_array *)cson_malloc(sizeof(cson_array),"cson_array");
2528
- if( ! ar )
2529
- {
2530
- cson_free(v,"cson_array");
2531
- v = NULL;
2532
- }
2533
- else
2534
- {
2535
- *ar = cson_array_empty;
2536
- *v = cson_value_array_empty;
2537
- v->value = ar;
2538
- }
2402
+ cson_array * ar = CSON_ARRAY(v);
2403
+ assert(NULL != ar);
2404
+ *ar = cson_array_empty;
25392405
}
25402406
return v;
25412407
}
25422408
25432409
static cson_value * cson_value_object_alloc()
25442410
{
2545
- cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_object");
2411
+ cson_value * v = cson_value_new(CSON_TYPE_OBJECT,0);
25462412
if( NULL != v )
25472413
{
2548
- cson_object * obj = (cson_object*)cson_malloc(sizeof(cson_object),"cson_value");
2549
- if( ! obj )
2550
- {
2551
- cson_free(v,"cson_value_object");
2552
- v = NULL;
2553
- }
2554
- else
2555
- {
2556
- *obj = cson_object_empty;
2557
- *v = cson_value_object_empty;
2558
- v->value = obj;
2559
- }
2414
+ cson_object * obj = CSON_OBJ(v);
2415
+ assert(NULL != obj);
2416
+ *obj = cson_object_empty;
25602417
}
25612418
return v;
25622419
}
25632420
25642421
cson_value * cson_value_new_object()
@@ -2612,31 +2469,10 @@
26122469
cson_kvp_clean(kvp);
26132470
cson_free(kvp,"cson_kvp");
26142471
}
26152472
}
26162473
2617
-/**
2618
- cson_value_api::destroy_value() impl for Object
2619
- values. Cleans up self-owned memory and overwrites
2620
- self to have the undefined value, but does not
2621
- free self.
2622
-
2623
- If self->value == cson_string_shared_empty()
2624
- then this function does not actually free it.
2625
-*/
2626
-static void cson_value_destroy_string( cson_value * self )
2627
-{
2628
- if(self && self->value) {
2629
- cson_string * obj = (cson_string *)self->value;
2630
- if( obj != cson_string_shared_empty() )
2631
- {
2632
- cson_free(self->value,"cson_string");
2633
- }
2634
- *self = cson_value_undef;
2635
- }
2636
-}
2637
-
26382474
26392475
/**
26402476
cson_value_api::destroy_value() impl for Object
26412477
values. Cleans up self-owned memory and overwrites
26422478
self to have the undefined value, but does not
@@ -2646,11 +2482,10 @@
26462482
{
26472483
if(self && self->value) {
26482484
cson_object * obj = (cson_object *)self->value;
26492485
assert( self->value == obj );
26502486
cson_kvp_list_clean( &obj->kvp, cson_kvp_free );
2651
- cson_free(self->value,"cson_object");
26522487
*self = cson_value_undef;
26532488
}
26542489
}
26552490
26562491
/**
@@ -2701,11 +2536,10 @@
27012536
{
27022537
cson_array * ar = cson_value_get_array(self);
27032538
if(ar) {
27042539
assert( self->value == ar );
27052540
cson_array_clean( ar, 1 );
2706
- cson_free(ar,"cson_array");
27072541
*self = cson_value_undef;
27082542
}
27092543
}
27102544
27112545
@@ -2857,16 +2691,16 @@
28572691
cson_value_fetch_bool( val, &b );
28582692
i = b;
28592693
break;
28602694
}
28612695
case CSON_TYPE_INTEGER: {
2862
-#if CSON_VOID_PTR_IS_BIG
2863
- i = (cson_int_t)val->value;
2864
-#else
2865
- cson_int_t const * x = (cson_int_t const *)val->value;
2696
+ cson_int_t const * x = CSON_INT(val);
2697
+ if(!x)
2698
+ {
2699
+ assert( val == &CSON_SPECIAL_VALUES[CSON_VAL_INT_0] );
2700
+ }
28662701
i = x ? *x : 0;
2867
-#endif
28682702
break;
28692703
}
28702704
case CSON_TYPE_DOUBLE: {
28712705
cson_double_t d = 0.0;
28722706
cson_value_fetch_double( val, &d );
@@ -2915,11 +2749,11 @@
29152749
cson_value_fetch_integer( val, &i );
29162750
d = i;
29172751
break;
29182752
}
29192753
case CSON_TYPE_DOUBLE: {
2920
- cson_double_t const* dv = (cson_double_t const *)val->value;
2754
+ cson_double_t const* dv = CSON_DBL(val);
29212755
d = dv ? *dv : 0.0;
29222756
break;
29232757
}
29242758
default:
29252759
rc = cson_rc.TypeError;
@@ -2964,11 +2798,11 @@
29642798
{
29652799
if( ! val ) return cson_rc.ArgError;
29662800
else if( ! cson_value_is_object(val) ) return cson_rc.TypeError;
29672801
else
29682802
{
2969
- if(obj) *obj = (cson_object*)val->value;
2803
+ if(obj) *obj = CSON_OBJ(val);
29702804
return 0;
29712805
}
29722806
}
29732807
cson_object * cson_value_get_object( cson_value const * v )
29742808
{
@@ -2978,14 +2812,14 @@
29782812
}
29792813
29802814
int cson_value_fetch_array( cson_value const * val, cson_array ** ar)
29812815
{
29822816
if( ! val ) return cson_rc.ArgError;
2983
- else if( ! cson_value_is_array(val) ) return cson_rc.TypeError;
2817
+ else if( !cson_value_is_array(val) ) return cson_rc.TypeError;
29842818
else
29852819
{
2986
- if(ar) *ar = (cson_array*)val->value;
2820
+ if(ar) *ar = CSON_ARRAY(val);
29872821
return 0;
29882822
}
29892823
}
29902824
29912825
cson_array * cson_value_get_array( cson_value const * v )
@@ -3084,18 +2918,15 @@
30842918
cson_value * cson_value_new_integer( cson_int_t v )
30852919
{
30862920
if( 0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
30872921
else
30882922
{
3089
- cson_value * c = cson_value_new();
2923
+ cson_value * c = cson_value_new(CSON_TYPE_INTEGER,0);
2924
+
30902925
if( c )
30912926
{
3092
- if( 0 != cson_value_set_integer( c, v ) )
3093
- {
3094
- cson_value_free(c);
3095
- c = NULL;
3096
- }
2927
+ *CSON_INT(c) = v;
30972928
}
30982929
return c;
30992930
}
31002931
}
31012932
@@ -3102,35 +2933,35 @@
31022933
cson_value * cson_value_new_double( cson_double_t v )
31032934
{
31042935
if( 0.0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
31052936
else
31062937
{
3107
- cson_value * c = cson_value_new();
2938
+ cson_value * c = cson_value_new(CSON_TYPE_DOUBLE,0);
31082939
if( c )
31092940
{
3110
- if( 0 != cson_value_set_double( c, v ) )
3111
- {
3112
- cson_value_free(c);
3113
- c = NULL;
3114
- }
2941
+ *CSON_DBL(c) = v;
31152942
}
31162943
return c;
31172944
}
31182945
}
31192946
cson_value * cson_value_new_string( char const * str, unsigned int len )
31202947
{
3121
- if( !str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
2948
+ if( !str || !*str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
31222949
else
31232950
{
3124
- cson_value * c = cson_value_new();
2951
+ cson_value * c = cson_value_new(CSON_TYPE_STRING, len + 1/*NUL byte*/);
31252952
if( c )
31262953
{
3127
- if( 0 != cson_value_set_string( c, str, len ) )
3128
- {
3129
- cson_value_free(c);
3130
- c = NULL;
3131
- }
2954
+ char * dest = NULL;
2955
+ cson_string * s = CSON_STR(c);
2956
+ *s = cson_string_empty;
2957
+ assert( NULL != s );
2958
+ s->length = len;
2959
+ dest = cson_string_str(s);
2960
+ assert( NULL != dest );
2961
+ memcpy( dest, str, len );
2962
+ dest[len] = 0;
31322963
}
31332964
return c;
31342965
}
31352966
}
31362967
@@ -4816,11 +4647,12 @@
48164647
else
48174648
{
48184649
switch( orig->api->typeID )
48194650
{
48204651
case CSON_TYPE_UNDEF:
4821
- return cson_value_new();
4652
+ assert(0 && "This should never happen.");
4653
+ return NULL;
48224654
case CSON_TYPE_NULL:
48234655
return cson_value_null();
48244656
case CSON_TYPE_BOOL:
48254657
return cson_value_new_bool( cson_value_get_bool( orig ) );
48264658
case CSON_TYPE_INTEGER:
@@ -4841,10 +4673,34 @@
48414673
}
48424674
assert( 0 && "We can't get this far." );
48434675
return NULL;
48444676
}
48454677
}
4678
+
4679
+cson_value * cson_string_value(cson_string const * s)
4680
+{
4681
+ return s
4682
+ ? CSON_VCAST(s)
4683
+ : NULL;
4684
+}
4685
+
4686
+cson_value * cson_object_value(cson_object const * s)
4687
+{
4688
+ return s
4689
+ ? CSON_VCAST(s)
4690
+ : NULL;
4691
+}
4692
+
4693
+
4694
+cson_value * cson_array_value(cson_array const * s)
4695
+{
4696
+ return s
4697
+ ? CSON_VCAST(s)
4698
+ : NULL;
4699
+}
4700
+
4701
+
48464702
48474703
#if 0
48484704
/* i'm not happy with this... */
48494705
char * cson_pod_to_string( cson_value const * orig )
48504706
{
@@ -4955,10 +4811,17 @@
49554811
#endif
49564812
49574813
#undef MARKER
49584814
#undef CSON_OBJECT_PROPS_SORT
49594815
#undef CSON_OBJECT_PROPS_SORT_USE_LENGTH
4816
+#undef CSON_CAST
4817
+#undef CSON_INT
4818
+#undef CSON_DBL
4819
+#undef CSON_STR
4820
+#undef CSON_OBJ
4821
+#undef CSON_ARRAY
4822
+#undef CSON_VCAST
49604823
/* end file ./cson.c */
49614824
/* begin file ./cson_lists.h */
49624825
/* Auto-generated from cson_list.h. Edit at your own risk! */
49634826
unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n )
49644827
{
49654828
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1570,35 +1570,28 @@
1570 const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
1571 const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
1572 const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
1573
1574 static void cson_value_destroy_zero_it( cson_value * self );
1575 static void cson_value_destroy_free( cson_value * self );
1576 static void cson_value_destroy_object( cson_value * self );
1577 static void cson_value_destroy_integer( cson_value * self );
1578 /**
1579 If self is-a array then this function destroys its contents,
1580 else this function does nothing.
1581 */
1582 static void cson_value_destroy_array( cson_value * self );
1583
1584 /**
1585 If self is-a string then this function destroys its contents,
1586 else this function does nothing.
1587 */
1588 static void cson_value_destroy_string( cson_value * self );
1589
1590 static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
1591 static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
1592 static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
1593 static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_integer };
1594 static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_free };
1595 static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_string };
1596 static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
1597 static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };
1598
1599 static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };
 
1600 static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
1601 static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
1602 static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
1603 static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
1604 static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
@@ -1608,11 +1601,11 @@
1608 struct cson_string
1609 {
1610 unsigned int length;
1611 };
1612 #define cson_string_empty_m {0/*length*/}
1613
1614 /**
1615
1616 Holds special shared "constant" (though they are non-const)
1617 values.
1618
@@ -2033,37 +2026,22 @@
2033 if( self )
2034 {
2035 *self = cson_value_undef;
2036 }
2037 }
2038
2039 /**
2040 If self is not null, free(self->value) is called. *self is then
2041 overwritten to have the undefined type. self is not freed.
2042
2043 */
2044 void cson_value_destroy_free( cson_value * self )
2045 {
2046 if(self) {
2047 if( self->value )
2048 {
2049 cson_free(self->value,"cson_value_destroy_free()");
2050 }
2051 *self = cson_value_undef;
2052 }
2053 }
2054
2055
2056
2057 /**
2058 A key/value pair collection.
2059
2060 Each of these objects owns its key/value pointers, and they
2061 are cleaned up by cson_kvp_clean().
2062 */
2063 struct cson_kvp
2064 {
 
 
 
2065 cson_string * key;
2066 cson_value * value;
2067 };
2068 #define cson_kvp_empty_m {NULL,NULL}
2069 static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;
@@ -2261,32 +2239,23 @@
2261 # define VALUE_T cson_kvp *
2262 # define VALUE_T_IS_PTR 1
2263 #else
2264 #endif
2265
2266 /*
2267 Reminders to self:
2268
2269 - 20110126: moved cson_value_new() and cson_value_set_xxx() out of the
2270 public API because:
2271
2272 a) They can be easily mis-used to cause memory leaks, even when used in
2273 a manner which seems relatively intuitive.
2274
2275 b) Having them in the API prohibits us from eventually doing certain
2276 allocation optimizations like not allocating Booleans,
2277 Integer/Doubles with the value 0, or empty Strings. The main problem
2278 is that cson_value_set_xxx() cannot be implemented properly if we
2279 add that type of optimization.
2280 */
2281
2282 /**
2283 Allocates a new value with the "undefined" value and transfers
2284 ownership of it to the caller. Use The cson_value_set_xxx() family
2285 of functions to assign a typed value to it. It must eventually be
2286 destroyed, by the caller or its owning container, by passing it to
2287 cson_value_free().
 
 
 
 
 
 
 
2288
2289 Returns NULL on allocation error.
2290
2291 @see cson_value_new_array()
2292 @see cson_value_new_object()
@@ -2294,65 +2263,73 @@
2294 @see cson_value_new_integer()
2295 @see cson_value_new_double()
2296 @see cson_value_new_bool()
2297 @see cson_value_free()
2298 */
2299 static cson_value * cson_value_new();
2300 /**
2301 Cleans any existing contents of val and sets its new value
2302 to the special NULL value.
2303
2304 Returns 0 on success.
2305
2306 */
2307 #if 0
2308 static int cson_value_set_null( cson_value * val );
2309 #endif
2310 /**
2311 Cleans any existing contents of val and sets its new value
2312 to v.
2313
2314 Returns 0 on success.
2315
2316 */
2317 #if 0
2318 static int cson_value_set_bool( cson_value * val, char v );
2319 #endif
2320 /**
2321 Cleans any existing contents of val and sets its new value
2322 to v.
2323
2324 Returns 0 on success.
2325
2326 */
2327 static int cson_value_set_integer( cson_value * val, cson_int_t v );
2328 /**
2329 Cleans any existing contents of val and sets its new value
2330 to v.
2331
2332 Returns 0 on success.
2333 */
2334 static int cson_value_set_double( cson_value * val, cson_double_t v );
2335
2336 /**
2337 Cleans any existing contents of val and sets its new value to
2338 str. On success, ownership of str is passed on to val. On error
2339 ownership is not changed.
2340
2341 Returns 0 on success.
2342
2343 If str is NULL, (!*str), or (!len) then this function does not
2344 allocate any memory for a new string, and cson_value_fetch_string()
2345 will return an empty string as opposed to a NULL string.
2346 */
2347 static int cson_value_set_string( cson_value * val, char const * str, unsigned int len );
2348
2349
2350 cson_value * cson_value_new()
2351 {
2352 cson_value * v = (cson_value *)cson_malloc(sizeof(cson_value),"cson_value_new");
2353 if( v ) *v = cson_value_undef;
 
 
 
 
 
 
 
 
2354 return v;
2355 }
2356
2357
2358 void cson_value_free(cson_value *v)
@@ -2414,151 +2391,31 @@
2414 *val = cson_value_undef;
2415 val->refcount = rc;
2416 }
2417 }
2418 }
2419
2420 static void cson_value_destroy_integer( cson_value * self )
2421 {
2422 if( self )
2423 {
2424 #if !CSON_VOID_PTR_IS_BIG
2425 cson_free(self->value,"cson_int_t");
2426 #endif
2427 *self = cson_value_empty;
2428 }
2429 }
2430 static int cson_value_set_integer( cson_value * val, cson_int_t v )
2431 {
2432 if( ! val ) return cson_rc.ArgError;
2433 else
2434 {
2435 #if CSON_VOID_PTR_IS_BIG
2436 cson_value_clean( val );
2437 val->value = (void *)v;
2438 #else
2439 cson_int_t * iv = NULL;
2440 iv = (cson_int_t*)cson_malloc(sizeof(cson_int_t), "cson_int_t");
2441 if( ! iv ) return cson_rc.AllocError;
2442 cson_value_clean( val );
2443 *iv = v;
2444 val->value = iv;
2445 #endif
2446 val->api = &cson_value_api_integer;
2447 return 0;
2448 }
2449 }
2450
2451 static int cson_value_set_double( cson_value * val, cson_double_t v )
2452 {
2453 if( ! val ) return cson_rc.ArgError;
2454 else
2455 {
2456 cson_double_t * rv = NULL;
2457 cson_value_clean( val );
2458 val->api = &cson_value_api_double;
2459 if( 0.0 != v )
2460 {
2461 /*
2462 Reminder: we can't re-use val if it alreay is-a double
2463 because we have no reference counting.
2464 */
2465 rv = (cson_double_t*)cson_malloc(sizeof(cson_double_t),"double");
2466 if( ! rv ) return cson_rc.AllocError;
2467 }
2468 if(NULL != rv) *rv = v;
2469 val->value = rv;
2470 return 0;
2471 }
2472 }
2473
2474 static cson_string * cson_string_shared_empty()
2475 {
2476 /**
2477 We have code in place elsewhere to avoid that
2478 cson_string_cstr(&bob) and cson_string_str(&bob) will misbehave
2479 by accessing the bytes directly after bob (which are undefined
2480 in this case).
2481 */
2482 #if 0
2483 static cson_string bob[2] = {cson_string_empty_m,
2484 cson_string_empty_m/*trick to 0-init bob[0]'s tail*/};
2485 return &bob[0];
2486 #else
2487 static cson_string bob = cson_string_empty_m;
2488 return &bob;
2489 #endif
2490 }
2491
2492 static int cson_value_set_string( cson_value * val, char const * str, unsigned int len )
2493 {
2494 cson_string * jstr = NULL;
2495 if( ! val ) return cson_rc.ArgError;
2496 cson_value_clean( val );
2497 val->api = &cson_value_api_string;
2498 if( !str || !*str || !len )
2499 {
2500 val->value = cson_string_shared_empty();
2501 return 0;
2502 }
2503 else
2504 {
2505 jstr = cson_string_alloc( len );
2506 if( NULL == jstr ) return cson_rc.AllocError;
2507 else
2508 {
2509 if( len )
2510 {
2511 char * dest = cson_string_str( jstr );
2512 val->value = jstr;
2513 strncpy( dest, str, len );
2514 }
2515 /* else it's the empty string special value */
2516 return 0;
2517 }
2518 }
2519 }
2520
2521
2522 static cson_value * cson_value_array_alloc()
2523 {
2524 cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_array");
2525 if( NULL != v )
2526 {
2527 cson_array * ar = (cson_array *)cson_malloc(sizeof(cson_array),"cson_array");
2528 if( ! ar )
2529 {
2530 cson_free(v,"cson_array");
2531 v = NULL;
2532 }
2533 else
2534 {
2535 *ar = cson_array_empty;
2536 *v = cson_value_array_empty;
2537 v->value = ar;
2538 }
2539 }
2540 return v;
2541 }
2542
2543 static cson_value * cson_value_object_alloc()
2544 {
2545 cson_value * v = (cson_value*)cson_malloc(sizeof(cson_value),"cson_value_object");
2546 if( NULL != v )
2547 {
2548 cson_object * obj = (cson_object*)cson_malloc(sizeof(cson_object),"cson_value");
2549 if( ! obj )
2550 {
2551 cson_free(v,"cson_value_object");
2552 v = NULL;
2553 }
2554 else
2555 {
2556 *obj = cson_object_empty;
2557 *v = cson_value_object_empty;
2558 v->value = obj;
2559 }
2560 }
2561 return v;
2562 }
2563
2564 cson_value * cson_value_new_object()
@@ -2612,31 +2469,10 @@
2612 cson_kvp_clean(kvp);
2613 cson_free(kvp,"cson_kvp");
2614 }
2615 }
2616
2617 /**
2618 cson_value_api::destroy_value() impl for Object
2619 values. Cleans up self-owned memory and overwrites
2620 self to have the undefined value, but does not
2621 free self.
2622
2623 If self->value == cson_string_shared_empty()
2624 then this function does not actually free it.
2625 */
2626 static void cson_value_destroy_string( cson_value * self )
2627 {
2628 if(self && self->value) {
2629 cson_string * obj = (cson_string *)self->value;
2630 if( obj != cson_string_shared_empty() )
2631 {
2632 cson_free(self->value,"cson_string");
2633 }
2634 *self = cson_value_undef;
2635 }
2636 }
2637
2638
2639 /**
2640 cson_value_api::destroy_value() impl for Object
2641 values. Cleans up self-owned memory and overwrites
2642 self to have the undefined value, but does not
@@ -2646,11 +2482,10 @@
2646 {
2647 if(self && self->value) {
2648 cson_object * obj = (cson_object *)self->value;
2649 assert( self->value == obj );
2650 cson_kvp_list_clean( &obj->kvp, cson_kvp_free );
2651 cson_free(self->value,"cson_object");
2652 *self = cson_value_undef;
2653 }
2654 }
2655
2656 /**
@@ -2701,11 +2536,10 @@
2701 {
2702 cson_array * ar = cson_value_get_array(self);
2703 if(ar) {
2704 assert( self->value == ar );
2705 cson_array_clean( ar, 1 );
2706 cson_free(ar,"cson_array");
2707 *self = cson_value_undef;
2708 }
2709 }
2710
2711
@@ -2857,16 +2691,16 @@
2857 cson_value_fetch_bool( val, &b );
2858 i = b;
2859 break;
2860 }
2861 case CSON_TYPE_INTEGER: {
2862 #if CSON_VOID_PTR_IS_BIG
2863 i = (cson_int_t)val->value;
2864 #else
2865 cson_int_t const * x = (cson_int_t const *)val->value;
 
2866 i = x ? *x : 0;
2867 #endif
2868 break;
2869 }
2870 case CSON_TYPE_DOUBLE: {
2871 cson_double_t d = 0.0;
2872 cson_value_fetch_double( val, &d );
@@ -2915,11 +2749,11 @@
2915 cson_value_fetch_integer( val, &i );
2916 d = i;
2917 break;
2918 }
2919 case CSON_TYPE_DOUBLE: {
2920 cson_double_t const* dv = (cson_double_t const *)val->value;
2921 d = dv ? *dv : 0.0;
2922 break;
2923 }
2924 default:
2925 rc = cson_rc.TypeError;
@@ -2964,11 +2798,11 @@
2964 {
2965 if( ! val ) return cson_rc.ArgError;
2966 else if( ! cson_value_is_object(val) ) return cson_rc.TypeError;
2967 else
2968 {
2969 if(obj) *obj = (cson_object*)val->value;
2970 return 0;
2971 }
2972 }
2973 cson_object * cson_value_get_object( cson_value const * v )
2974 {
@@ -2978,14 +2812,14 @@
2978 }
2979
2980 int cson_value_fetch_array( cson_value const * val, cson_array ** ar)
2981 {
2982 if( ! val ) return cson_rc.ArgError;
2983 else if( ! cson_value_is_array(val) ) return cson_rc.TypeError;
2984 else
2985 {
2986 if(ar) *ar = (cson_array*)val->value;
2987 return 0;
2988 }
2989 }
2990
2991 cson_array * cson_value_get_array( cson_value const * v )
@@ -3084,18 +2918,15 @@
3084 cson_value * cson_value_new_integer( cson_int_t v )
3085 {
3086 if( 0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
3087 else
3088 {
3089 cson_value * c = cson_value_new();
 
3090 if( c )
3091 {
3092 if( 0 != cson_value_set_integer( c, v ) )
3093 {
3094 cson_value_free(c);
3095 c = NULL;
3096 }
3097 }
3098 return c;
3099 }
3100 }
3101
@@ -3102,35 +2933,35 @@
3102 cson_value * cson_value_new_double( cson_double_t v )
3103 {
3104 if( 0.0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
3105 else
3106 {
3107 cson_value * c = cson_value_new();
3108 if( c )
3109 {
3110 if( 0 != cson_value_set_double( c, v ) )
3111 {
3112 cson_value_free(c);
3113 c = NULL;
3114 }
3115 }
3116 return c;
3117 }
3118 }
3119 cson_value * cson_value_new_string( char const * str, unsigned int len )
3120 {
3121 if( !str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
3122 else
3123 {
3124 cson_value * c = cson_value_new();
3125 if( c )
3126 {
3127 if( 0 != cson_value_set_string( c, str, len ) )
3128 {
3129 cson_value_free(c);
3130 c = NULL;
3131 }
 
 
 
 
3132 }
3133 return c;
3134 }
3135 }
3136
@@ -4816,11 +4647,12 @@
4816 else
4817 {
4818 switch( orig->api->typeID )
4819 {
4820 case CSON_TYPE_UNDEF:
4821 return cson_value_new();
 
4822 case CSON_TYPE_NULL:
4823 return cson_value_null();
4824 case CSON_TYPE_BOOL:
4825 return cson_value_new_bool( cson_value_get_bool( orig ) );
4826 case CSON_TYPE_INTEGER:
@@ -4841,10 +4673,34 @@
4841 }
4842 assert( 0 && "We can't get this far." );
4843 return NULL;
4844 }
4845 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4846
4847 #if 0
4848 /* i'm not happy with this... */
4849 char * cson_pod_to_string( cson_value const * orig )
4850 {
@@ -4955,10 +4811,17 @@
4955 #endif
4956
4957 #undef MARKER
4958 #undef CSON_OBJECT_PROPS_SORT
4959 #undef CSON_OBJECT_PROPS_SORT_USE_LENGTH
 
 
 
 
 
 
 
4960 /* end file ./cson.c */
4961 /* begin file ./cson_lists.h */
4962 /* Auto-generated from cson_list.h. Edit at your own risk! */
4963 unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n )
4964 {
4965
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1570,35 +1570,28 @@
1570 const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
1571 const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
1572 const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
1573
1574 static void cson_value_destroy_zero_it( cson_value * self );
 
1575 static void cson_value_destroy_object( cson_value * self );
 
1576 /**
1577 If self is-a array then this function destroys its contents,
1578 else this function does nothing.
1579 */
1580 static void cson_value_destroy_array( cson_value * self );
1581
 
 
 
 
 
 
1582 static const cson_value_api cson_value_api_null = { CSON_TYPE_NULL, cson_value_destroy_zero_it };
1583 static const cson_value_api cson_value_api_undef = { CSON_TYPE_UNDEF, cson_value_destroy_zero_it };
1584 static const cson_value_api cson_value_api_bool = { CSON_TYPE_BOOL, cson_value_destroy_zero_it };
1585 static const cson_value_api cson_value_api_integer = { CSON_TYPE_INTEGER, cson_value_destroy_zero_it };
1586 static const cson_value_api cson_value_api_double = { CSON_TYPE_DOUBLE, cson_value_destroy_zero_it };
1587 static const cson_value_api cson_value_api_string = { CSON_TYPE_STRING, cson_value_destroy_zero_it };
1588 static const cson_value_api cson_value_api_array = { CSON_TYPE_ARRAY, cson_value_destroy_array };
1589 static const cson_value_api cson_value_api_object = { CSON_TYPE_OBJECT, cson_value_destroy_object };
1590
1591 static const cson_value cson_value_undef = { &cson_value_api_undef, NULL, 0 };
1592 static const cson_value cson_value_null_empty = { &cson_value_api_null, NULL, 0 };
1593 static const cson_value cson_value_bool_empty = { &cson_value_api_bool, NULL, 0 };
1594 static const cson_value cson_value_integer_empty = { &cson_value_api_integer, NULL, 0 };
1595 static const cson_value cson_value_double_empty = { &cson_value_api_double, NULL, 0 };
1596 static const cson_value cson_value_string_empty = { &cson_value_api_string, NULL, 0 };
1597 static const cson_value cson_value_array_empty = { &cson_value_api_array, NULL, 0 };
@@ -1608,11 +1601,11 @@
1601 struct cson_string
1602 {
1603 unsigned int length;
1604 };
1605 #define cson_string_empty_m {0/*length*/}
1606 static const cson_string cson_string_empty = cson_string_empty_m;
1607 /**
1608
1609 Holds special shared "constant" (though they are non-const)
1610 values.
1611
@@ -2033,37 +2026,22 @@
2026 if( self )
2027 {
2028 *self = cson_value_undef;
2029 }
2030 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2031
2032 /**
2033 A key/value pair collection.
2034
2035 Each of these objects owns its key/value pointers, and they
2036 are cleaned up by cson_kvp_clean().
2037 */
2038 struct cson_kvp
2039 {
2040 /* FIXME: switch to cson_value keys. Calling cson_string_value()
2041 on one of these guys will read invalid memory.
2042 */
2043 cson_string * key;
2044 cson_value * value;
2045 };
2046 #define cson_kvp_empty_m {NULL,NULL}
2047 static const cson_kvp cson_kvp_empty = cson_kvp_empty_m;
@@ -2261,32 +2239,23 @@
2239 # define VALUE_T cson_kvp *
2240 # define VALUE_T_IS_PTR 1
2241 #else
2242 #endif
2243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2244 /**
2245 Allocates a new value of the specified type ownership of it to the
2246 caller. It must eventually be destroyed, by the caller or its
2247 owning container, by passing it to cson_value_free() or transfering
2248 ownership to a container.
2249
2250 extra is only valid for type CSON_TYPE_STRING, and must be the length
2251 of the string to allocate + 1 byte (for the NUL).
2252
2253 The returned value->api member will be set appropriately and
2254 val->value will be set to point to the memory allocated to hold the
2255 native value type. Use the internal CSON_CAST() family of macros to
2256 convert them.
2257
2258 Returns NULL on allocation error.
2259
2260 @see cson_value_new_array()
2261 @see cson_value_new_object()
@@ -2294,65 +2263,73 @@
2263 @see cson_value_new_integer()
2264 @see cson_value_new_double()
2265 @see cson_value_new_bool()
2266 @see cson_value_free()
2267 */
2268 static cson_value * cson_value_new(cson_type_id t, size_t extra);
2269
2270 #define CSON_CAST(T,V) ((T*)((V)->value))
2271 #define CSON_VCAST(V) ((cson_value *)(((unsigned char *)(V))-sizeof(cson_value)))
2272 #define CSON_INT(V) ((cson_int_t*)(V)->value)
2273 #define CSON_DBL(V) CSON_CAST(cson_double_t,(V))
2274 #define CSON_STR(V) CSON_CAST(cson_string,(V))
2275 #define CSON_OBJ(V) CSON_CAST(cson_object,(V))
2276 #define CSON_ARRAY(V) CSON_CAST(cson_array,(V))
2277
2278 cson_value * cson_value_new(cson_type_id t, size_t extra)
2279 {
2280 static const size_t vsz = sizeof(cson_value);
2281 const size_t sz = vsz + extra;
2282 size_t tx = 0;
2283 cson_value def = cson_value_undef;
2284 cson_value * v = NULL;
2285 char const * reason = "cson_value_new";
2286 switch(t)
2287 {
2288 case CSON_TYPE_ARRAY:
2289 assert( 0 == extra );
2290 def = cson_value_array_empty;
2291 tx = sizeof(cson_array);
2292 reason = "cson_value:array";
2293 break;
2294 case CSON_TYPE_DOUBLE:
2295 assert( 0 == extra );
2296 def = cson_value_double_empty;
2297 tx = sizeof(cson_double_t);
2298 reason = "cson_value:double";
2299 break;
2300 case CSON_TYPE_INTEGER:
2301 assert( 0 == extra );
2302 def = cson_value_integer_empty;
2303 tx = sizeof(cson_int_t);
2304 reason = "cson_value:int";
2305 break;
2306 case CSON_TYPE_STRING:
2307 assert( 0 != extra );
2308 def = cson_value_string_empty;
2309 tx = sizeof(cson_string);
2310 reason = "cson_value:string";
2311 break;
2312 case CSON_TYPE_OBJECT:
2313 assert( 0 == extra );
2314 def = cson_value_object_empty;
2315 tx = sizeof(cson_object);
2316 reason = "cson_value:object";
2317 break;
2318 default:
2319 assert(0 && "Unhandled type in cson_value_new()!");
2320 return NULL;
2321 }
2322 assert( def.api->typeID != CSON_TYPE_UNDEF );
2323 v = (cson_value *)cson_malloc(sz+tx, reason);
2324 if( v ) {
2325 *v = def;
2326 if(tx || extra){
2327 memset(v+1, 0, tx + extra);
2328 v->value = (void *)(v+1);
2329 }
2330 }
2331 return v;
2332 }
2333
2334
2335 void cson_value_free(cson_value *v)
@@ -2414,151 +2391,31 @@
2391 *val = cson_value_undef;
2392 val->refcount = rc;
2393 }
2394 }
2395 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2396
2397 static cson_value * cson_value_array_alloc()
2398 {
2399 cson_value * v = cson_value_new(CSON_TYPE_ARRAY,0);
2400 if( NULL != v )
2401 {
2402 cson_array * ar = CSON_ARRAY(v);
2403 assert(NULL != ar);
2404 *ar = cson_array_empty;
 
 
 
 
 
 
 
 
 
2405 }
2406 return v;
2407 }
2408
2409 static cson_value * cson_value_object_alloc()
2410 {
2411 cson_value * v = cson_value_new(CSON_TYPE_OBJECT,0);
2412 if( NULL != v )
2413 {
2414 cson_object * obj = CSON_OBJ(v);
2415 assert(NULL != obj);
2416 *obj = cson_object_empty;
 
 
 
 
 
 
 
 
 
2417 }
2418 return v;
2419 }
2420
2421 cson_value * cson_value_new_object()
@@ -2612,31 +2469,10 @@
2469 cson_kvp_clean(kvp);
2470 cson_free(kvp,"cson_kvp");
2471 }
2472 }
2473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2474
2475 /**
2476 cson_value_api::destroy_value() impl for Object
2477 values. Cleans up self-owned memory and overwrites
2478 self to have the undefined value, but does not
@@ -2646,11 +2482,10 @@
2482 {
2483 if(self && self->value) {
2484 cson_object * obj = (cson_object *)self->value;
2485 assert( self->value == obj );
2486 cson_kvp_list_clean( &obj->kvp, cson_kvp_free );
 
2487 *self = cson_value_undef;
2488 }
2489 }
2490
2491 /**
@@ -2701,11 +2536,10 @@
2536 {
2537 cson_array * ar = cson_value_get_array(self);
2538 if(ar) {
2539 assert( self->value == ar );
2540 cson_array_clean( ar, 1 );
 
2541 *self = cson_value_undef;
2542 }
2543 }
2544
2545
@@ -2857,16 +2691,16 @@
2691 cson_value_fetch_bool( val, &b );
2692 i = b;
2693 break;
2694 }
2695 case CSON_TYPE_INTEGER: {
2696 cson_int_t const * x = CSON_INT(val);
2697 if(!x)
2698 {
2699 assert( val == &CSON_SPECIAL_VALUES[CSON_VAL_INT_0] );
2700 }
2701 i = x ? *x : 0;
 
2702 break;
2703 }
2704 case CSON_TYPE_DOUBLE: {
2705 cson_double_t d = 0.0;
2706 cson_value_fetch_double( val, &d );
@@ -2915,11 +2749,11 @@
2749 cson_value_fetch_integer( val, &i );
2750 d = i;
2751 break;
2752 }
2753 case CSON_TYPE_DOUBLE: {
2754 cson_double_t const* dv = CSON_DBL(val);
2755 d = dv ? *dv : 0.0;
2756 break;
2757 }
2758 default:
2759 rc = cson_rc.TypeError;
@@ -2964,11 +2798,11 @@
2798 {
2799 if( ! val ) return cson_rc.ArgError;
2800 else if( ! cson_value_is_object(val) ) return cson_rc.TypeError;
2801 else
2802 {
2803 if(obj) *obj = CSON_OBJ(val);
2804 return 0;
2805 }
2806 }
2807 cson_object * cson_value_get_object( cson_value const * v )
2808 {
@@ -2978,14 +2812,14 @@
2812 }
2813
2814 int cson_value_fetch_array( cson_value const * val, cson_array ** ar)
2815 {
2816 if( ! val ) return cson_rc.ArgError;
2817 else if( !cson_value_is_array(val) ) return cson_rc.TypeError;
2818 else
2819 {
2820 if(ar) *ar = CSON_ARRAY(val);
2821 return 0;
2822 }
2823 }
2824
2825 cson_array * cson_value_get_array( cson_value const * v )
@@ -3084,18 +2918,15 @@
2918 cson_value * cson_value_new_integer( cson_int_t v )
2919 {
2920 if( 0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_INT_0];
2921 else
2922 {
2923 cson_value * c = cson_value_new(CSON_TYPE_INTEGER,0);
2924
2925 if( c )
2926 {
2927 *CSON_INT(c) = v;
 
 
 
 
2928 }
2929 return c;
2930 }
2931 }
2932
@@ -3102,35 +2933,35 @@
2933 cson_value * cson_value_new_double( cson_double_t v )
2934 {
2935 if( 0.0 == v ) return &CSON_SPECIAL_VALUES[CSON_VAL_DBL_0];
2936 else
2937 {
2938 cson_value * c = cson_value_new(CSON_TYPE_DOUBLE,0);
2939 if( c )
2940 {
2941 *CSON_DBL(c) = v;
 
 
 
 
2942 }
2943 return c;
2944 }
2945 }
2946 cson_value * cson_value_new_string( char const * str, unsigned int len )
2947 {
2948 if( !str || !*str || !len ) return &CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY];
2949 else
2950 {
2951 cson_value * c = cson_value_new(CSON_TYPE_STRING, len + 1/*NUL byte*/);
2952 if( c )
2953 {
2954 char * dest = NULL;
2955 cson_string * s = CSON_STR(c);
2956 *s = cson_string_empty;
2957 assert( NULL != s );
2958 s->length = len;
2959 dest = cson_string_str(s);
2960 assert( NULL != dest );
2961 memcpy( dest, str, len );
2962 dest[len] = 0;
2963 }
2964 return c;
2965 }
2966 }
2967
@@ -4816,11 +4647,12 @@
4647 else
4648 {
4649 switch( orig->api->typeID )
4650 {
4651 case CSON_TYPE_UNDEF:
4652 assert(0 && "This should never happen.");
4653 return NULL;
4654 case CSON_TYPE_NULL:
4655 return cson_value_null();
4656 case CSON_TYPE_BOOL:
4657 return cson_value_new_bool( cson_value_get_bool( orig ) );
4658 case CSON_TYPE_INTEGER:
@@ -4841,10 +4673,34 @@
4673 }
4674 assert( 0 && "We can't get this far." );
4675 return NULL;
4676 }
4677 }
4678
4679 cson_value * cson_string_value(cson_string const * s)
4680 {
4681 return s
4682 ? CSON_VCAST(s)
4683 : NULL;
4684 }
4685
4686 cson_value * cson_object_value(cson_object const * s)
4687 {
4688 return s
4689 ? CSON_VCAST(s)
4690 : NULL;
4691 }
4692
4693
4694 cson_value * cson_array_value(cson_array const * s)
4695 {
4696 return s
4697 ? CSON_VCAST(s)
4698 : NULL;
4699 }
4700
4701
4702
4703 #if 0
4704 /* i'm not happy with this... */
4705 char * cson_pod_to_string( cson_value const * orig )
4706 {
@@ -4955,10 +4811,17 @@
4811 #endif
4812
4813 #undef MARKER
4814 #undef CSON_OBJECT_PROPS_SORT
4815 #undef CSON_OBJECT_PROPS_SORT_USE_LENGTH
4816 #undef CSON_CAST
4817 #undef CSON_INT
4818 #undef CSON_DBL
4819 #undef CSON_STR
4820 #undef CSON_OBJ
4821 #undef CSON_ARRAY
4822 #undef CSON_VCAST
4823 /* end file ./cson.c */
4824 /* begin file ./cson_lists.h */
4825 /* Auto-generated from cson_list.h. Edit at your own risk! */
4826 unsigned int cson_value_list_reserve( cson_value_list * self, unsigned int n )
4827 {
4828
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -57,46 +57,10 @@
5757
typedef long cson_int_t;
5858
#define CSON_INT_T_SFMT "ld"
5959
#define CSON_INT_T_PFMT "ld"
6060
#endif
6161
62
-/** @def CSON_VOID_PTR_IS_BIG
63
-
64
-ONLY define this to a true value if you know that
65
-
66
-(sizeof(cson_int_t) <= sizeof(void*))
67
-
68
-If that is the case, cson does not need to dynamically
69
-allocate integers. However, enabling this may cause
70
-compilation warnings in 32-bit builds even though the code
71
-being warned about cannot ever be called. To get around such
72
-warnings, when building on a 64-bit environment you can define
73
-this to 1 to get "big" integer support. HOWEVER, all clients must
74
-also use the same value for this macro. If i knew a halfway reliable
75
-way to determine this automatically at preprocessor-time, i would
76
-automate this. We might be able to do halfway reliably by looking
77
-for a large INT_MAX value?
78
-*/
79
-#if !defined(CSON_VOID_PTR_IS_BIG)
80
-
81
-/* Largely taken from http://predef.sourceforge.net/prearch.html
82
-
83
-See also: http://poshlib.hookatooka.com/poshlib/trac.cgi/browser/posh.h
84
-*/
85
-# if defined(_WIN64) || defined(__LP64__)/*gcc*/ \
86
- || defined(_M_X64) || defined(__amd64__) || defined(__amd64) \
87
- || defined(__x86_64__) || defined(__x86_64) \
88
- || defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) \
89
- || defined(_M_IA64) \
90
- || defined(__sparc_v9__) || defined(__sparcv9) || defined(_ADDR64) \
91
- || defined(__64BIT__)
92
-# define CSON_VOID_PTR_IS_BIG 1
93
-# else
94
-# define CSON_VOID_PTR_IS_BIG 0
95
-# endif
96
-#endif
97
-
9862
/** @typedef double_or_long_double cson_double_t
9963
10064
This is the type of double value used by the library.
10165
It is only lightly tested with long double, and when using
10266
long double the memory requirements for such values goes
@@ -843,15 +807,18 @@
843807
boolean: same
844808
845809
integer, double: 0 or 0.0 == false, else true
846810
847811
object, array: true
812
+
813
+ string: length-0 string is false, else true.
848814
849815
Returns 0 on success and assigns *v (if v is not NULL) to either 0 or 1.
850816
On error (val is NULL) then v is not modified.
851817
*/
852818
int cson_value_fetch_bool( cson_value const * val, char * v );
819
+
853820
/**
854821
Similar to cson_value_fetch_bool(), but fetches an integer value.
855822
856823
The conversion, if any, depends on the concrete type of val:
857824
@@ -865,10 +832,11 @@
865832
integer: *v is set to the int value and 0 is returned.
866833
867834
double: *v is set to the value truncated to int and 0 is returned.
868835
*/
869836
int cson_value_fetch_integer( cson_value const * val, cson_int_t * v );
837
+
870838
/**
871839
The same conversions and return values as
872840
cson_value_fetch_integer(), except that the roles of int/double are
873841
swapped.
874842
*/
@@ -1940,10 +1908,34 @@
19401908
allocation fails while constructing the clone. In other words, if
19411909
cloning fails due to something other than an allocation error then
19421910
either orig is in an invalid state or there is a bug.
19431911
*/
19441912
cson_value * cson_value_clone( cson_value const * orig );
1913
+
1914
+/**
1915
+ Returns the value handle associated with s. The handle itself owns
1916
+ s, and ownership of the handle is not changed by calling this
1917
+ function. If the returned handle is part of a container, calling
1918
+ cson_value_free() on the returned handle invoked undefined
1919
+ behaviour (quite possibly downstream when the container tries to
1920
+ use it).
1921
+
1922
+ This function only returns NULL if s. is NULL.
1923
+*/
1924
+cson_value * cson_string_value(cson_string const * s);
1925
+/**
1926
+ The Object form of cson_string_value(). See that function
1927
+ for full details.
1928
+*/
1929
+cson_value * cson_object_value(cson_object const * s);
1930
+
1931
+/**
1932
+ The Array form of cson_string_value(). See that function
1933
+ for full details.
1934
+*/
1935
+cson_value * cson_array_value(cson_array const * s);
1936
+
19451937
19461938
/* LICENSE
19471939
19481940
This software's source code, including accompanying documentation and
19491941
demonstration applications, are licensed under the following
19501942
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -57,46 +57,10 @@
57 typedef long cson_int_t;
58 #define CSON_INT_T_SFMT "ld"
59 #define CSON_INT_T_PFMT "ld"
60 #endif
61
62 /** @def CSON_VOID_PTR_IS_BIG
63
64 ONLY define this to a true value if you know that
65
66 (sizeof(cson_int_t) <= sizeof(void*))
67
68 If that is the case, cson does not need to dynamically
69 allocate integers. However, enabling this may cause
70 compilation warnings in 32-bit builds even though the code
71 being warned about cannot ever be called. To get around such
72 warnings, when building on a 64-bit environment you can define
73 this to 1 to get "big" integer support. HOWEVER, all clients must
74 also use the same value for this macro. If i knew a halfway reliable
75 way to determine this automatically at preprocessor-time, i would
76 automate this. We might be able to do halfway reliably by looking
77 for a large INT_MAX value?
78 */
79 #if !defined(CSON_VOID_PTR_IS_BIG)
80
81 /* Largely taken from http://predef.sourceforge.net/prearch.html
82
83 See also: http://poshlib.hookatooka.com/poshlib/trac.cgi/browser/posh.h
84 */
85 # if defined(_WIN64) || defined(__LP64__)/*gcc*/ \
86 || defined(_M_X64) || defined(__amd64__) || defined(__amd64) \
87 || defined(__x86_64__) || defined(__x86_64) \
88 || defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) \
89 || defined(_M_IA64) \
90 || defined(__sparc_v9__) || defined(__sparcv9) || defined(_ADDR64) \
91 || defined(__64BIT__)
92 # define CSON_VOID_PTR_IS_BIG 1
93 # else
94 # define CSON_VOID_PTR_IS_BIG 0
95 # endif
96 #endif
97
98 /** @typedef double_or_long_double cson_double_t
99
100 This is the type of double value used by the library.
101 It is only lightly tested with long double, and when using
102 long double the memory requirements for such values goes
@@ -843,15 +807,18 @@
843 boolean: same
844
845 integer, double: 0 or 0.0 == false, else true
846
847 object, array: true
 
 
848
849 Returns 0 on success and assigns *v (if v is not NULL) to either 0 or 1.
850 On error (val is NULL) then v is not modified.
851 */
852 int cson_value_fetch_bool( cson_value const * val, char * v );
 
853 /**
854 Similar to cson_value_fetch_bool(), but fetches an integer value.
855
856 The conversion, if any, depends on the concrete type of val:
857
@@ -865,10 +832,11 @@
865 integer: *v is set to the int value and 0 is returned.
866
867 double: *v is set to the value truncated to int and 0 is returned.
868 */
869 int cson_value_fetch_integer( cson_value const * val, cson_int_t * v );
 
870 /**
871 The same conversions and return values as
872 cson_value_fetch_integer(), except that the roles of int/double are
873 swapped.
874 */
@@ -1940,10 +1908,34 @@
1940 allocation fails while constructing the clone. In other words, if
1941 cloning fails due to something other than an allocation error then
1942 either orig is in an invalid state or there is a bug.
1943 */
1944 cson_value * cson_value_clone( cson_value const * orig );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1945
1946 /* LICENSE
1947
1948 This software's source code, including accompanying documentation and
1949 demonstration applications, are licensed under the following
1950
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -57,46 +57,10 @@
57 typedef long cson_int_t;
58 #define CSON_INT_T_SFMT "ld"
59 #define CSON_INT_T_PFMT "ld"
60 #endif
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62 /** @typedef double_or_long_double cson_double_t
63
64 This is the type of double value used by the library.
65 It is only lightly tested with long double, and when using
66 long double the memory requirements for such values goes
@@ -843,15 +807,18 @@
807 boolean: same
808
809 integer, double: 0 or 0.0 == false, else true
810
811 object, array: true
812
813 string: length-0 string is false, else true.
814
815 Returns 0 on success and assigns *v (if v is not NULL) to either 0 or 1.
816 On error (val is NULL) then v is not modified.
817 */
818 int cson_value_fetch_bool( cson_value const * val, char * v );
819
820 /**
821 Similar to cson_value_fetch_bool(), but fetches an integer value.
822
823 The conversion, if any, depends on the concrete type of val:
824
@@ -865,10 +832,11 @@
832 integer: *v is set to the int value and 0 is returned.
833
834 double: *v is set to the value truncated to int and 0 is returned.
835 */
836 int cson_value_fetch_integer( cson_value const * val, cson_int_t * v );
837
838 /**
839 The same conversions and return values as
840 cson_value_fetch_integer(), except that the roles of int/double are
841 swapped.
842 */
@@ -1940,10 +1908,34 @@
1908 allocation fails while constructing the clone. In other words, if
1909 cloning fails due to something other than an allocation error then
1910 either orig is in an invalid state or there is a bug.
1911 */
1912 cson_value * cson_value_clone( cson_value const * orig );
1913
1914 /**
1915 Returns the value handle associated with s. The handle itself owns
1916 s, and ownership of the handle is not changed by calling this
1917 function. If the returned handle is part of a container, calling
1918 cson_value_free() on the returned handle invoked undefined
1919 behaviour (quite possibly downstream when the container tries to
1920 use it).
1921
1922 This function only returns NULL if s. is NULL.
1923 */
1924 cson_value * cson_string_value(cson_string const * s);
1925 /**
1926 The Object form of cson_string_value(). See that function
1927 for full details.
1928 */
1929 cson_value * cson_object_value(cson_object const * s);
1930
1931 /**
1932 The Array form of cson_string_value(). See that function
1933 for full details.
1934 */
1935 cson_value * cson_array_value(cson_array const * s);
1936
1937
1938 /* LICENSE
1939
1940 This software's source code, including accompanying documentation and
1941 demonstration applications, are licensed under the following
1942

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button