Rolf Meyer
/
yajl
yajl - JSON library working with the compiler. URL: http://lloyd.github.com/yajl/
main.cpp@0:34f4a53d4ca3, 2009-11-18 (annotated)
- Committer:
- rolf
- Date:
- Wed Nov 18 17:56:51 2009 +0000
- Revision:
- 0:34f4a53d4ca3
Who changed what in which revision?
User | Revision | Line number | New 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 | } |