yajl - JSON library working with the compiler. URL: http://lloyd.github.com/yajl/

Dependencies:   mbed

Committer:
rolf
Date:
Wed Nov 18 17:56:51 2009 +0000
Revision:
0:34f4a53d4ca3

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rolf 0:34f4a53d4ca3 1 /*
rolf 0:34f4a53d4ca3 2 * Copyright 2007-2009, Lloyd Hilaiel.
rolf 0:34f4a53d4ca3 3 *
rolf 0:34f4a53d4ca3 4 * Redistribution and use in source and binary forms, with or without
rolf 0:34f4a53d4ca3 5 * modification, are permitted provided that the following conditions are
rolf 0:34f4a53d4ca3 6 * met:
rolf 0:34f4a53d4ca3 7 *
rolf 0:34f4a53d4ca3 8 * 1. Redistributions of source code must retain the above copyright
rolf 0:34f4a53d4ca3 9 * notice, this list of conditions and the following disclaimer.
rolf 0:34f4a53d4ca3 10 *
rolf 0:34f4a53d4ca3 11 * 2. Redistributions in binary form must reproduce the above copyright
rolf 0:34f4a53d4ca3 12 * notice, this list of conditions and the following disclaimer in
rolf 0:34f4a53d4ca3 13 * the documentation and/or other materials provided with the
rolf 0:34f4a53d4ca3 14 * distribution.
rolf 0:34f4a53d4ca3 15 *
rolf 0:34f4a53d4ca3 16 * 3. Neither the name of Lloyd Hilaiel nor the names of its
rolf 0:34f4a53d4ca3 17 * contributors may be used to endorse or promote products derived
rolf 0:34f4a53d4ca3 18 * from this software without specific prior written permission.
rolf 0:34f4a53d4ca3 19 *
rolf 0:34f4a53d4ca3 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
rolf 0:34f4a53d4ca3 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
rolf 0:34f4a53d4ca3 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
rolf 0:34f4a53d4ca3 23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
rolf 0:34f4a53d4ca3 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rolf 0:34f4a53d4ca3 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
rolf 0:34f4a53d4ca3 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
rolf 0:34f4a53d4ca3 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
rolf 0:34f4a53d4ca3 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
rolf 0:34f4a53d4ca3 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
rolf 0:34f4a53d4ca3 30 * POSSIBILITY OF SUCH DAMAGE.
rolf 0:34f4a53d4ca3 31 */
rolf 0:34f4a53d4ca3 32
rolf 0:34f4a53d4ca3 33 #include "mbed.h"
rolf 0:34f4a53d4ca3 34
rolf 0:34f4a53d4ca3 35 LocalFileSystem local("local");
rolf 0:34f4a53d4ca3 36
rolf 0:34f4a53d4ca3 37 #ifdef __cplusplus
rolf 0:34f4a53d4ca3 38 extern "C" {
rolf 0:34f4a53d4ca3 39 #endif
rolf 0:34f4a53d4ca3 40
rolf 0:34f4a53d4ca3 41 #include <yajl/yajl_parse.h>
rolf 0:34f4a53d4ca3 42 #include <yajl/yajl_gen.h>
rolf 0:34f4a53d4ca3 43
rolf 0:34f4a53d4ca3 44 #include <stdio.h>
rolf 0:34f4a53d4ca3 45 #include <stdlib.h>
rolf 0:34f4a53d4ca3 46 #include <string.h>
rolf 0:34f4a53d4ca3 47
rolf 0:34f4a53d4ca3 48 #include <assert.h>
rolf 0:34f4a53d4ca3 49
rolf 0:34f4a53d4ca3 50 /* memory debugging routines */
rolf 0:34f4a53d4ca3 51 typedef struct {
rolf 0:34f4a53d4ca3 52 unsigned int numFrees;
rolf 0:34f4a53d4ca3 53 unsigned int numMallocs;
rolf 0:34f4a53d4ca3 54 /* XXX: we really need a hash table here with per-allocation
rolf 0:34f4a53d4ca3 55 * information */
rolf 0:34f4a53d4ca3 56 } yajlTestMemoryContext;
rolf 0:34f4a53d4ca3 57
rolf 0:34f4a53d4ca3 58 /* cast void * into context */
rolf 0:34f4a53d4ca3 59 #define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
rolf 0:34f4a53d4ca3 60
rolf 0:34f4a53d4ca3 61 static void yajlTestFree(void * ctx, void * ptr) {
rolf 0:34f4a53d4ca3 62 assert(ptr != NULL);
rolf 0:34f4a53d4ca3 63 TEST_CTX(ctx)->numFrees++;
rolf 0:34f4a53d4ca3 64 free(ptr);
rolf 0:34f4a53d4ca3 65 }
rolf 0:34f4a53d4ca3 66
rolf 0:34f4a53d4ca3 67 static void * yajlTestMalloc(void * ctx, unsigned int sz) {
rolf 0:34f4a53d4ca3 68 assert(sz != 0);
rolf 0:34f4a53d4ca3 69 TEST_CTX(ctx)->numMallocs++;
rolf 0:34f4a53d4ca3 70 return malloc(sz);
rolf 0:34f4a53d4ca3 71 }
rolf 0:34f4a53d4ca3 72
rolf 0:34f4a53d4ca3 73 static void * yajlTestRealloc(void * ctx, void * ptr, unsigned int sz) {
rolf 0:34f4a53d4ca3 74 if (ptr == NULL) {
rolf 0:34f4a53d4ca3 75 assert(sz != 0);
rolf 0:34f4a53d4ca3 76 TEST_CTX(ctx)->numMallocs++;
rolf 0:34f4a53d4ca3 77 } else if (sz == 0) {
rolf 0:34f4a53d4ca3 78 TEST_CTX(ctx)->numFrees++;
rolf 0:34f4a53d4ca3 79 }
rolf 0:34f4a53d4ca3 80
rolf 0:34f4a53d4ca3 81 return realloc(ctx, sz);
rolf 0:34f4a53d4ca3 82 }
rolf 0:34f4a53d4ca3 83
rolf 0:34f4a53d4ca3 84
rolf 0:34f4a53d4ca3 85 /* begin parsing callback routines */
rolf 0:34f4a53d4ca3 86 #define BUF_SIZE 2048
rolf 0:34f4a53d4ca3 87
rolf 0:34f4a53d4ca3 88 static int test_yajl_null(void *ctx) {
rolf 0:34f4a53d4ca3 89 printf("null\n");
rolf 0:34f4a53d4ca3 90 return 1;
rolf 0:34f4a53d4ca3 91 }
rolf 0:34f4a53d4ca3 92
rolf 0:34f4a53d4ca3 93 static int test_yajl_boolean(void * ctx, int boolVal) {
rolf 0:34f4a53d4ca3 94 printf("bool: %s\n", boolVal ? "true" : "false");
rolf 0:34f4a53d4ca3 95 return 1;
rolf 0:34f4a53d4ca3 96 }
rolf 0:34f4a53d4ca3 97
rolf 0:34f4a53d4ca3 98 static int test_yajl_integer(void *ctx, long integerVal) {
rolf 0:34f4a53d4ca3 99 printf("integer: %ld\n", integerVal);
rolf 0:34f4a53d4ca3 100 return 1;
rolf 0:34f4a53d4ca3 101 }
rolf 0:34f4a53d4ca3 102
rolf 0:34f4a53d4ca3 103 static int test_yajl_double(void *ctx, double doubleVal) {
rolf 0:34f4a53d4ca3 104 printf("double: %g\n", doubleVal);
rolf 0:34f4a53d4ca3 105 return 1;
rolf 0:34f4a53d4ca3 106 }
rolf 0:34f4a53d4ca3 107
rolf 0:34f4a53d4ca3 108 static int test_yajl_string(void *ctx, const unsigned char * stringVal, unsigned int stringLen) {
rolf 0:34f4a53d4ca3 109 printf("string: '");
rolf 0:34f4a53d4ca3 110 fwrite(stringVal, 1, stringLen, stdout);
rolf 0:34f4a53d4ca3 111 printf("'\n");
rolf 0:34f4a53d4ca3 112 return 1;
rolf 0:34f4a53d4ca3 113 }
rolf 0:34f4a53d4ca3 114
rolf 0:34f4a53d4ca3 115 static int test_yajl_map_key(void *ctx, const unsigned char * stringVal, unsigned int stringLen) {
rolf 0:34f4a53d4ca3 116 char * str = (char *) malloc(stringLen + 1);
rolf 0:34f4a53d4ca3 117 str[stringLen] = 0;
rolf 0:34f4a53d4ca3 118 memcpy(str, stringVal, stringLen);
rolf 0:34f4a53d4ca3 119 printf("key: '%s'\n", str);
rolf 0:34f4a53d4ca3 120 free(str);
rolf 0:34f4a53d4ca3 121 return 1;
rolf 0:34f4a53d4ca3 122 }
rolf 0:34f4a53d4ca3 123
rolf 0:34f4a53d4ca3 124 static int test_yajl_start_map(void *ctx) {
rolf 0:34f4a53d4ca3 125 printf("map open '{'\n");
rolf 0:34f4a53d4ca3 126 return 1;
rolf 0:34f4a53d4ca3 127 }
rolf 0:34f4a53d4ca3 128
rolf 0:34f4a53d4ca3 129
rolf 0:34f4a53d4ca3 130 static int test_yajl_end_map(void *ctx) {
rolf 0:34f4a53d4ca3 131 printf("map close '}'\n");
rolf 0:34f4a53d4ca3 132 return 1;
rolf 0:34f4a53d4ca3 133 }
rolf 0:34f4a53d4ca3 134
rolf 0:34f4a53d4ca3 135 static int test_yajl_start_array(void *ctx) {
rolf 0:34f4a53d4ca3 136 printf("array open '['\n");
rolf 0:34f4a53d4ca3 137 return 1;
rolf 0:34f4a53d4ca3 138 }
rolf 0:34f4a53d4ca3 139
rolf 0:34f4a53d4ca3 140 static int test_yajl_end_array(void *ctx) {
rolf 0:34f4a53d4ca3 141 printf("array close ']'\n");
rolf 0:34f4a53d4ca3 142 return 1;
rolf 0:34f4a53d4ca3 143 }
rolf 0:34f4a53d4ca3 144
rolf 0:34f4a53d4ca3 145 static yajl_callbacks callbacks = {
rolf 0:34f4a53d4ca3 146 test_yajl_null,
rolf 0:34f4a53d4ca3 147 test_yajl_boolean,
rolf 0:34f4a53d4ca3 148 test_yajl_integer,
rolf 0:34f4a53d4ca3 149 test_yajl_double,
rolf 0:34f4a53d4ca3 150 NULL,
rolf 0:34f4a53d4ca3 151 test_yajl_string,
rolf 0:34f4a53d4ca3 152 test_yajl_start_map,
rolf 0:34f4a53d4ca3 153 test_yajl_map_key,
rolf 0:34f4a53d4ca3 154 test_yajl_end_map,
rolf 0:34f4a53d4ca3 155 test_yajl_start_array,
rolf 0:34f4a53d4ca3 156 test_yajl_end_array
rolf 0:34f4a53d4ca3 157 };
rolf 0:34f4a53d4ca3 158
rolf 0:34f4a53d4ca3 159 static void usage(const char * progname) {
rolf 0:34f4a53d4ca3 160 fprintf(stderr,
rolf 0:34f4a53d4ca3 161 "usage: %s [options] <filename>\n"
rolf 0:34f4a53d4ca3 162 " -c allow comments\n"
rolf 0:34f4a53d4ca3 163 " -b set the read buffer size\n",
rolf 0:34f4a53d4ca3 164 progname);
rolf 0:34f4a53d4ca3 165 exit(1);
rolf 0:34f4a53d4ca3 166 }
rolf 0:34f4a53d4ca3 167
rolf 0:34f4a53d4ca3 168 #ifdef __cplusplus
rolf 0:34f4a53d4ca3 169 }
rolf 0:34f4a53d4ca3 170 #endif
rolf 0:34f4a53d4ca3 171
rolf 0:34f4a53d4ca3 172 int main() {
rolf 0:34f4a53d4ca3 173 printf("Main\n");
rolf 0:34f4a53d4ca3 174 yajl_handle hand;
rolf 0:34f4a53d4ca3 175 const char * fileName;
rolf 0:34f4a53d4ca3 176 static unsigned char * fileData = NULL;
rolf 0:34f4a53d4ca3 177 unsigned int bufSize = BUF_SIZE;
rolf 0:34f4a53d4ca3 178 yajl_status stat;
rolf 0:34f4a53d4ca3 179 size_t rd;
rolf 0:34f4a53d4ca3 180 yajl_parser_config cfg = { 0, 1 };
rolf 0:34f4a53d4ca3 181 int done;
rolf 0:34f4a53d4ca3 182
rolf 0:34f4a53d4ca3 183 /* memory allocation debugging: allocate a structure which collects
rolf 0:34f4a53d4ca3 184 * statistics */
rolf 0:34f4a53d4ca3 185 yajlTestMemoryContext memCtx = { 0,0 };
rolf 0:34f4a53d4ca3 186
rolf 0:34f4a53d4ca3 187 /* memory allocation debugging: allocate a structure which holds
rolf 0:34f4a53d4ca3 188 * allocation routines */
rolf 0:34f4a53d4ca3 189 yajl_alloc_funcs allocFuncs = {
rolf 0:34f4a53d4ca3 190 yajlTestMalloc,
rolf 0:34f4a53d4ca3 191 yajlTestRealloc,
rolf 0:34f4a53d4ca3 192 yajlTestFree,
rolf 0:34f4a53d4ca3 193 (void *) NULL
rolf 0:34f4a53d4ca3 194 };
rolf 0:34f4a53d4ca3 195
rolf 0:34f4a53d4ca3 196 allocFuncs.ctx = (void *) &memCtx;
rolf 0:34f4a53d4ca3 197
rolf 0:34f4a53d4ca3 198 /* check arguments. We expect exactly one! */
rolf 0:34f4a53d4ca3 199 cfg.allowComments = 1;
rolf 0:34f4a53d4ca3 200 bufSize = 2048;
rolf 0:34f4a53d4ca3 201
rolf 0:34f4a53d4ca3 202 fileData = new unsigned char[bufSize];
rolf 0:34f4a53d4ca3 203
rolf 0:34f4a53d4ca3 204 if (fileData == NULL) {
rolf 0:34f4a53d4ca3 205 printf("failed to allocate read buffer of %u bytes, exiting.",
rolf 0:34f4a53d4ca3 206 bufSize);
rolf 0:34f4a53d4ca3 207 exit(2);
rolf 0:34f4a53d4ca3 208 }
rolf 0:34f4a53d4ca3 209
rolf 0:34f4a53d4ca3 210 fileName = "/local/json.txt";
rolf 0:34f4a53d4ca3 211 FILE *file = fopen(fileName, "r");
rolf 0:34f4a53d4ca3 212
rolf 0:34f4a53d4ca3 213 printf("Lets start\n");
rolf 0:34f4a53d4ca3 214
rolf 0:34f4a53d4ca3 215 /* ok. open file. let's read and parse */
rolf 0:34f4a53d4ca3 216 hand = yajl_alloc(&callbacks, &cfg, &allocFuncs, NULL);
rolf 0:34f4a53d4ca3 217
rolf 0:34f4a53d4ca3 218 done = 0;
rolf 0:34f4a53d4ca3 219 printf("While loop\n");
rolf 0:34f4a53d4ca3 220 while (!done) {
rolf 0:34f4a53d4ca3 221 rd = fread((void *) fileData, 1, bufSize, file);
rolf 0:34f4a53d4ca3 222
rolf 0:34f4a53d4ca3 223 if (rd == 0) {
rolf 0:34f4a53d4ca3 224 if (!feof(file)) {
rolf 0:34f4a53d4ca3 225 fprintf(stderr, "error reading from '%s'\n", fileName);
rolf 0:34f4a53d4ca3 226 break;
rolf 0:34f4a53d4ca3 227 }
rolf 0:34f4a53d4ca3 228 done = 1;
rolf 0:34f4a53d4ca3 229 }
rolf 0:34f4a53d4ca3 230
rolf 0:34f4a53d4ca3 231 if (done) {
rolf 0:34f4a53d4ca3 232 /* parse any remaining buffered data */
rolf 0:34f4a53d4ca3 233 stat = yajl_parse_complete(hand);
rolf 0:34f4a53d4ca3 234 } else {
rolf 0:34f4a53d4ca3 235 /* read file data, pass to parser */
rolf 0:34f4a53d4ca3 236 stat = yajl_parse(hand, fileData, rd);
rolf 0:34f4a53d4ca3 237 }
rolf 0:34f4a53d4ca3 238
rolf 0:34f4a53d4ca3 239 if(stat != yajl_status_insufficient_data &&
rolf 0:34f4a53d4ca3 240 stat != yajl_status_ok) {
rolf 0:34f4a53d4ca3 241 unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
rolf 0:34f4a53d4ca3 242 fflush(stdout);
rolf 0:34f4a53d4ca3 243 fprintf(stderr, (char *) str);
rolf 0:34f4a53d4ca3 244 yajl_free_error(hand, str);
rolf 0:34f4a53d4ca3 245 break;
rolf 0:34f4a53d4ca3 246 }
rolf 0:34f4a53d4ca3 247 }
rolf 0:34f4a53d4ca3 248
rolf 0:34f4a53d4ca3 249 yajl_free(hand);
rolf 0:34f4a53d4ca3 250 free(fileData);
rolf 0:34f4a53d4ca3 251
rolf 0:34f4a53d4ca3 252 /* finally, print out some memory statistics */
rolf 0:34f4a53d4ca3 253
rolf 0:34f4a53d4ca3 254 /* (lth) only print leaks here, as allocations and frees may vary depending
rolf 0:34f4a53d4ca3 255 * on read buffer size, causing false failures.
rolf 0:34f4a53d4ca3 256 *
rolf 0:34f4a53d4ca3 257 * printf("allocations:\t%u\n", memCtx.numMallocs);
rolf 0:34f4a53d4ca3 258 * printf("frees:\t\t%u\n", memCtx.numFrees);
rolf 0:34f4a53d4ca3 259 */
rolf 0:34f4a53d4ca3 260 fflush(stderr);
rolf 0:34f4a53d4ca3 261 fflush(stdout);
rolf 0:34f4a53d4ca3 262 printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
rolf 0:34f4a53d4ca3 263
rolf 0:34f4a53d4ca3 264 return 0;
rolf 0:34f4a53d4ca3 265 }