Fossil

Check-in [c75759d8]
Login

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

Overview
Comment:Minor internal tweaks. Pulled in lastest cson_amalgamation for the new convenience functions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json-multitag-test | json
Files: files | file ages | folders
SHA1: c75759d8d0cf9a38cea0158e565e9c4c1de010f7
User & Date: stephan 2011-10-07 06:54:11
Context
2011-10-07
10:20
Another round of cson memory optimizations. Object keys can now be cson_strings, which can be refcounted/shared. check-in: 3d252e87 user: stephan tags: json-multitag-test, json
06:54
Minor internal tweaks. Pulled in lastest cson_amalgamation for the new convenience functions. check-in: c75759d8 user: stephan tags: json-multitag-test, json
03:52
/json/wiki/get: renamed request.payload.page to "name" for consistency. Added a TODO to /json/tag/list. check-in: 34056ea2 user: stephan tags: json-multitag-test, json
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cson_amalgamation.c.

1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606











1607
1608
1609
1610
1611
1612
1613
....
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
....
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
....
2418
2419
2420
2421
2422
2423
2424






2425
2426
2427
2428
2429
2430






2431
2432
2433
2434
2435
2436
2437
....
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
2970
2971
2972
2973
....
4674
4675
4676
4677
4678
4679
4680

4681
4682
4683

4684
4685
4686
4687
4688
4689
4690
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_
................................................................................
   len may be 0, in which case the internal string is "", as opposed
   to null. This is because the string bytes and the cson_string are
   allocated in a single chunk of memory, and the cson_string object
   does not directly provide (or have) a pointer to the string bytes.
*/
static cson_string * cson_string_alloc(unsigned int len)
{
    if( ! len ) return &CSON_EMPTY_HOLDER.stringValue;
    else
    {
        cson_string * s = NULL;
        const size_t msz = sizeof(cson_string) + len + 1 /*NUL*/;
        unsigned char * mem = NULL;
        if( msz < (sizeof(cson_string)+len) ) /*overflow*/ return NULL;
        mem = (unsigned char *)cson_malloc( msz, "cson_string_alloc" );
................................................................................
   @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;
................................................................................
    return v;
}

cson_value * cson_value_new_object()
{
    return cson_value_object_alloc();
}







cson_value * cson_value_new_array()
{
    return cson_value_array_alloc();
}







/**
   Frees kvp->key and kvp->value and sets them to NULL, but does not free
   kvp. If !kvp then this is a no-op.
*/
static void cson_kvp_clean( cson_kvp * kvp )
{
    if( kvp )
................................................................................
        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( !ar) return cson_rc.ArgError;
    if( pos >= ar->list.count ) return cson_rc.RangeError;
    else
    {
................................................................................
        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;







<






>
>
>
>
>
>
>
>
>
>
>







 







|







 







<
<
<
<
<
<
<
<







 







>
>
>
>
>
>






>
>
>
>
>
>







 







>
|

|



>



|








|


>
>
>
>
>







 







>

|

>







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
1621
1622
1623
....
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
....
2273
2274
2275
2276
2277
2278
2279








2280
2281
2282
2283
2284
2285
2286
....
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
....
2953
2954
2955
2956
2957
2958
2959
2960
2961
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
2994
....
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
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;



#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))

/**
 
 Holds special shared "constant" (though they are non-const)
 values.
 
*/
static struct CSON_EMPTY_HOLDER_
................................................................................
   len may be 0, in which case the internal string is "", as opposed
   to null. This is because the string bytes and the cson_string are
   allocated in a single chunk of memory, and the cson_string object
   does not directly provide (or have) a pointer to the string bytes.
*/
static cson_string * cson_string_alloc(unsigned int len)
{
    if( ! len ) return CSON_STR(&CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY]);
    else
    {
        cson_string * s = NULL;
        const size_t msz = sizeof(cson_string) + len + 1 /*NUL*/;
        unsigned char * mem = NULL;
        if( msz < (sizeof(cson_string)+len) ) /*overflow*/ return NULL;
        mem = (unsigned char *)cson_malloc( msz, "cson_string_alloc" );
................................................................................
   @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);









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;
................................................................................
    return v;
}

cson_value * cson_value_new_object()
{
    return cson_value_object_alloc();
}

cson_object * cson_new_object()
{
    
    return cson_value_get_object( cson_value_new_object() );
}

cson_value * cson_value_new_array()
{
    return cson_value_array_alloc();
}


cson_array * cson_new_array()
{
    return cson_value_get_array( cson_value_new_array() );
}

/**
   Frees kvp->key and kvp->value and sets them to NULL, but does not free
   kvp. If !kvp then this is a no-op.
*/
static void cson_kvp_clean( cson_kvp * kvp )
{
    if( kvp )
................................................................................
        if( c )
        {
            *CSON_DBL(c) = v;
        }
        return c;
    }
}

cson_string const * cson_new_string(char const * str, unsigned int len)
{
    if( !str || !*str || !len ) return &CSON_EMPTY_HOLDER.stringValue;
    else
    {
        cson_value * c = cson_value_new(CSON_TYPE_STRING, len + 1/*NUL byte*/);
        cson_string * s = NULL;
        if( c )
        {
            char * dest = NULL;
            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 s;
    }
}

cson_value * cson_value_new_string( char const * str, unsigned int len )
{
    return cson_string_value( cson_new_string(str, len) );
}

int cson_array_value_fetch( cson_array const * ar, unsigned int pos, cson_value ** v )
{
    if( !ar) return cson_rc.ArgError;
    if( pos >= ar->list.count ) return cson_rc.RangeError;
    else
    {
................................................................................
        assert( 0 && "We can't get this far." );
        return NULL;
    }
}

cson_value * cson_string_value(cson_string const * s)
{
#define MT CSON_SPECIAL_VALUES[CSON_VAL_STR_EMPTY]
    return s
        ? ((s==MT.value) ? &MT : CSON_VCAST(s))
        : NULL;
#undef MT
}

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

Changes to src/cson_amalgamation.h.

1203
1204
1205
1206
1207
1208
1209
































1210
1211
1212
1213
1214
1215
1216
   Post-conditions: cson_value_is_object(value) will return true.

   @see cson_value_new_array()
   @see cson_value_free()
*/
cson_value * cson_value_new_object();

































/**
   Allocates a new "array" value and transfers 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().

   Returns NULL on allocation error.








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







1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
   Post-conditions: cson_value_is_object(value) will return true.

   @see cson_value_new_array()
   @see cson_value_free()
*/
cson_value * cson_value_new_object();

/**
   This works like cson_value_new_object() but returns an Object
   handle directly.

   The value handle for the returned object can be fetched with
   cson_object_value(theObject).
   
   Ownership is transfered to the caller, who must eventually free it
   by passing the Value handle (NOT the Object handle) to
   cson_value_free() or passing ownership to a parent container.

   Returns NULL on error (out of memory).
*/
cson_object * cson_new_object();

/**
   Identical to cson_new_object() except that it creates
   an Array.
*/
cson_array * cson_new_array();

/**
   Identical to cson_new_object() except that it creates
   a String.

   ACHTUNG: this function returns a const pointer but the ownership of
   the memory belongs to the caller! Use cson_string_value() to fetch
   the Value handle, and then cson_value_free() that handle or insert
   it into a container to transfer ownership.
*/
cson_string const * cson_new_string(char const * val, unsigned int len);

/**
   Allocates a new "array" value and transfers 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().

   Returns NULL on allocation error.

Changes to src/json.c.

41
42
43
44
45
46
47

48
49
50
51
52
53
54
....
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
#include "json_detail.h" /* workaround for apparent enum limitation in makeheaders */
#endif

const FossilJsonKeys_ FossilJsonKeys = {
  "anonymousSeed" /*anonymousSeed*/,
  "authToken"  /*authToken*/,
  "COMMAND_PATH" /*commandPath*/,

  "payload" /* payload */,
  "requestId" /*requestId*/,
  "resultCode" /*resultCode*/,
  "resultText" /*resultText*/,
  "timestamp" /*timestamp*/
};

................................................................................
                                   char const * pMsg,
                                   cson_value * payload){
  cson_value * v = NULL;
  cson_value * tmp = NULL;
  cson_object * o = NULL;
  int rc;
  resultCode = json_dumbdown_rc(resultCode);
  v = cson_value_new_object();
  o = cson_value_get_object(v);
  if( ! o ) return NULL;
#define SET(K) if(!tmp) goto cleanup; \
  rc = cson_object_set( o, K, tmp ); \
  if(rc) do{\
    cson_value_free(tmp); \
    tmp = NULL; \
    goto cleanup; \







>







 







|
|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
....
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
#include "json_detail.h" /* workaround for apparent enum limitation in makeheaders */
#endif

const FossilJsonKeys_ FossilJsonKeys = {
  "anonymousSeed" /*anonymousSeed*/,
  "authToken"  /*authToken*/,
  "COMMAND_PATH" /*commandPath*/,
  "mtime" /*mtime*/,
  "payload" /* payload */,
  "requestId" /*requestId*/,
  "resultCode" /*resultCode*/,
  "resultText" /*resultText*/,
  "timestamp" /*timestamp*/
};

................................................................................
                                   char const * pMsg,
                                   cson_value * payload){
  cson_value * v = NULL;
  cson_value * tmp = NULL;
  cson_object * o = NULL;
  int rc;
  resultCode = json_dumbdown_rc(resultCode);
  o = cson_new_object();
  v = cson_object_value(o);
  if( ! o ) return NULL;
#define SET(K) if(!tmp) goto cleanup; \
  rc = cson_object_set( o, K, tmp ); \
  if(rc) do{\
    cson_value_free(tmp); \
    tmp = NULL; \
    goto cleanup; \

Changes to src/json_detail.h.

155
156
157
158
159
160
161

162
163
164
165
166
167
168
** Holds common keys used for various JSON API properties.
*/
typedef struct FossilJsonKeys_{
  /** maintainers: please keep alpha sorted (case-insensitive) */
  char const * anonymousSeed;
  char const * authToken;
  char const * commandPath;

  char const * payload;
  char const * requestId;
  char const * resultCode;
  char const * resultText;
  char const * timestamp;
} FossilJsonKeys_;
const FossilJsonKeys_ FossilJsonKeys;







>







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
** Holds common keys used for various JSON API properties.
*/
typedef struct FossilJsonKeys_{
  /** maintainers: please keep alpha sorted (case-insensitive) */
  char const * anonymousSeed;
  char const * authToken;
  char const * commandPath;
  char const * mtime;
  char const * payload;
  char const * requestId;
  char const * resultCode;
  char const * resultText;
  char const * timestamp;
} FossilJsonKeys_;
const FossilJsonKeys_ FossilJsonKeys;

Changes to src/json_wiki.c.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    unsigned int len;
    cson_value * payV = cson_value_new_object();
    cson_object * pay = cson_value_get_object(payV);
    cson_object_set(pay,"name",json_new_string(zPageName));
    cson_object_set(pay,"uuid",json_new_string(zUuid));
    free(zUuid);
    zUuid = NULL;
    cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));
    cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
    cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
    cson_object_set(pay,"contentFormat",json_new_string(zFormat));
    if( doParse ){
      Blob content = empty_blob;
      Blob raw = empty_blob;
      blob_append(&raw,zBody,-1);







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    unsigned int len;
    cson_value * payV = cson_value_new_object();
    cson_object * pay = cson_value_get_object(payV);
    cson_object_set(pay,"name",json_new_string(zPageName));
    cson_object_set(pay,"uuid",json_new_string(zUuid));
    free(zUuid);
    zUuid = NULL;
    /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/
    cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
    cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
    cson_object_set(pay,"contentFormat",json_new_string(zFormat));
    if( doParse ){
      Blob content = empty_blob;
      Blob raw = empty_blob;
      blob_append(&raw,zBody,-1);