diff options
author | Lloyd Hilaiel <lloyd@hilaiel.com> | 2009-12-05 18:29:44 -0700 |
---|---|---|
committer | Lloyd Hilaiel <lloyd@hilaiel.com> | 2009-12-05 18:29:44 -0700 |
commit | bbb833ad7de28df6eebc87156c7a19a4084b82df (patch) | |
tree | c87dcdb7154c688c52c444e34e37a0a22db220e4 | |
parent | 0c5fc370c155da38338ed483ab9a8d36a0c94985 (diff) | |
parent | 280f019df0b98fadb9a7d250d92d8cbc4909fd76 (diff) | |
download | yajl-bbb833ad7de28df6eebc87156c7a19a4084b82df.tar.gz |
Merge branch 'master' of github.com:lloyd/yajl
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/api/yajl_gen.h | 32 | ||||
-rw-r--r-- | src/yajl_encode.c | 15 | ||||
-rw-r--r-- | src/yajl_encode.h | 6 | ||||
-rw-r--r-- | src/yajl_gen.c | 76 |
5 files changed, 99 insertions, 33 deletions
@@ -1,3 +1,6 @@ +1.0.8 + * (Brian Maher) allow client to specify a printing function in generationh + 1.0.7 * lth fix win32 build (isinf and isnan) diff --git a/src/api/yajl_gen.h b/src/api/yajl_gen.h index 3fa31b6..36593e9 100644 --- a/src/api/yajl_gen.h +++ b/src/api/yajl_gen.h @@ -60,12 +60,20 @@ extern "C" { yajl_gen_generation_complete, /** yajl_gen_double was passed an invalid floating point value * (infinity or NaN). */ - yajl_gen_invalid_number + yajl_gen_invalid_number, + /** A print callback was passed in, so there is no internal + * buffer to get from */ + yajl_gen_no_buf } yajl_gen_status; /** an opaque handle to a generator */ typedef struct yajl_gen_t * yajl_gen; + /** a callback used for "printing" the results. */ + typedef void (*yajl_print_t)(void * ctx, + const char * str, + unsigned int len); + /** configuration structure for the generator */ typedef struct { /** generate indented (beautiful) output */ @@ -89,6 +97,28 @@ extern "C" { yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config, const yajl_alloc_funcs * allocFuncs); + /** allocate a generator handle that will print to the specified + * callback rather than storing the results in an internal buffer. + * \param callback a pointer to a printer function. May be NULL + * in which case, the results will be store in an + * internal buffer. + * \param config a pointer to a structure containing parameters + * which configure the behavior of the json + * generator. + * \param allocFuncs an optional pointer to a structure which allows + * the client to overide the memory allocation + * used by yajl. May be NULL, in which case + * malloc/free/realloc will be used. + * \param ctx a context pointer that will be passed to the + * printer callback. + * + * \returns an allocated handle on success, NULL on failure (bad params) + */ + yajl_gen YAJL_API yajl_gen_alloc2(yajl_print_t callback, + const yajl_gen_config * config, + const yajl_alloc_funcs * allocFuncs, + void * ctx); + /** free a generator handle */ void YAJL_API yajl_gen_free(yajl_gen handle); diff --git a/src/yajl_encode.c b/src/yajl_encode.c index 184277b..c3b02ed 100644 --- a/src/yajl_encode.c +++ b/src/yajl_encode.c @@ -48,6 +48,15 @@ void yajl_string_encode(yajl_buf buf, const unsigned char * str, unsigned int len) { + yajl_string_encode2((yajl_print_t) &yajl_buf_append, buf, str, len); +} + +void +yajl_string_encode2(const yajl_print_t print, + void * ctx, + const unsigned char * str, + unsigned int len) +{ unsigned int beg = 0; unsigned int end = 0; char hexBuf[7]; @@ -73,14 +82,14 @@ yajl_string_encode(yajl_buf buf, const unsigned char * str, break; } if (escaped != NULL) { - yajl_buf_append(buf, str + beg, end - beg); - yajl_buf_append(buf, escaped, strlen(escaped)); + print(ctx, (const char *) (str + beg), end - beg); + print(ctx, escaped, strlen(escaped)); beg = ++end; } else { ++end; } } - yajl_buf_append(buf, str + beg, end - beg); + print(ctx, (const char *) (str + beg), end - beg); } static void hexToDigit(unsigned int * val, const unsigned char * hex) diff --git a/src/yajl_encode.h b/src/yajl_encode.h index 8bd01af..3f5b236 100644 --- a/src/yajl_encode.h +++ b/src/yajl_encode.h @@ -34,6 +34,12 @@ #define __YAJL_ENCODE_H__ #include "yajl_buf.h" +#include "api/yajl_gen.h" + +void yajl_string_encode2(yajl_print_t printer, + void * ctx, + const unsigned char * str, + unsigned int length); void yajl_string_encode(yajl_buf buf, const unsigned char * str, unsigned int length); diff --git a/src/yajl_gen.c b/src/yajl_gen.c index 40605ef..8b7fce2 100644 --- a/src/yajl_gen.c +++ b/src/yajl_gen.c @@ -56,7 +56,8 @@ struct yajl_gen_t unsigned int pretty; const char * indentString; yajl_gen_state state[YAJL_MAX_DEPTH]; - yajl_buf buf; + yajl_print_t print; + void * ctx; /* yajl_buf */ /* memory allocation routines */ yajl_alloc_funcs alloc; }; @@ -65,6 +66,15 @@ yajl_gen yajl_gen_alloc(const yajl_gen_config * config, const yajl_alloc_funcs * afs) { + return yajl_gen_alloc2(NULL, config, afs, NULL); +} + +yajl_gen +yajl_gen_alloc2(yajl_print_t callback, + const yajl_gen_config * config, + const yajl_alloc_funcs * afs, + void * ctx) +{ yajl_gen g = NULL; yajl_alloc_funcs afsBuffer; @@ -88,7 +98,14 @@ yajl_gen_alloc(const yajl_gen_config * config, g->pretty = config->beautify; g->indentString = config->indentString ? config->indentString : " "; } - g->buf = yajl_buf_alloc(&(g->alloc)); + + if (callback) { + g->print = callback; + g->ctx = ctx; + } else { + g->print = (yajl_print_t)&yajl_buf_append; + g->ctx = yajl_buf_alloc(&(g->alloc)); + } return g; } @@ -96,18 +113,18 @@ yajl_gen_alloc(const yajl_gen_config * config, void yajl_gen_free(yajl_gen g) { - yajl_buf_free(g->buf); + if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx); YA_FREE(&(g->alloc), g); } #define INSERT_SEP \ if (g->state[g->depth] == yajl_gen_map_key || \ g->state[g->depth] == yajl_gen_in_array) { \ - yajl_buf_append(g->buf, ",", 1); \ - if (g->pretty) yajl_buf_append(g->buf, "\n", 1); \ + g->print(g->ctx, ",", 1); \ + if (g->pretty) g->print(g->ctx, "\n", 1); \ } else if (g->state[g->depth] == yajl_gen_map_val) { \ - yajl_buf_append(g->buf, ":", 1); \ - if (g->pretty) yajl_buf_append(g->buf, " ", 1); \ + g->print(g->ctx, ":", 1); \ + if (g->pretty) g->print(g->ctx, " ", 1); \ } #define INSERT_WHITESPACE \ @@ -115,8 +132,8 @@ yajl_gen_free(yajl_gen g) if (g->state[g->depth] != yajl_gen_map_val) { \ unsigned int _i; \ for (_i=0;_i<g->depth;_i++) \ - yajl_buf_append(g->buf, g->indentString, \ - strlen(g->indentString)); \ + g->print(g->ctx, g->indentString, \ + strlen(g->indentString)); \ } \ } @@ -158,7 +175,7 @@ yajl_gen_free(yajl_gen g) #define FINAL_NEWLINE \ if (g->pretty && g->state[g->depth] == yajl_gen_complete) \ - yajl_buf_append(g->buf, "\n", 1); + g->print(g->ctx, "\n", 1); yajl_gen_status yajl_gen_integer(yajl_gen g, long int number) @@ -166,7 +183,7 @@ yajl_gen_integer(yajl_gen g, long int number) char i[32]; ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; sprintf(i, "%ld", number); - yajl_buf_append(g->buf, i, strlen(i)); + g->print(g->ctx, i, strlen(i)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -186,7 +203,7 @@ yajl_gen_double(yajl_gen g, double number) if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; INSERT_SEP; INSERT_WHITESPACE; sprintf(i, "%g", number); - yajl_buf_append(g->buf, i, strlen(i)); + g->print(g->ctx, i, strlen(i)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -196,7 +213,7 @@ yajl_gen_status yajl_gen_number(yajl_gen g, const char * s, unsigned int l) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - yajl_buf_append(g->buf, s, l); + g->print(g->ctx, s, l); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -207,9 +224,9 @@ yajl_gen_string(yajl_gen g, const unsigned char * str, unsigned int len) { ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE; - yajl_buf_append(g->buf, "\"", 1); - yajl_string_encode(g->buf, str, len); - yajl_buf_append(g->buf, "\"", 1); + g->print(g->ctx, "\"", 1); + yajl_string_encode2(g->print, g->ctx, str, len); + g->print(g->ctx, "\"", 1); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -219,7 +236,7 @@ yajl_gen_status yajl_gen_null(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - yajl_buf_append(g->buf, "null", strlen("null")); + g->print(g->ctx, "null", strlen("null")); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -231,7 +248,7 @@ yajl_gen_bool(yajl_gen g, int boolean) const char * val = boolean ? "true" : "false"; ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - yajl_buf_append(g->buf, val, strlen(val)); + g->print(g->ctx, val, strlen(val)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; @@ -244,8 +261,8 @@ yajl_gen_map_open(yajl_gen g) INCREMENT_DEPTH; g->state[g->depth] = yajl_gen_map_start; - yajl_buf_append(g->buf, "{", 1); - if (g->pretty) yajl_buf_append(g->buf, "\n", 1); + g->print(g->ctx, "{", 1); + if (g->pretty) g->print(g->ctx, "\n", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } @@ -255,10 +272,10 @@ yajl_gen_map_close(yajl_gen g) { ENSURE_VALID_STATE; (g->depth)--; - if (g->pretty) yajl_buf_append(g->buf, "\n", 1); + if (g->pretty) g->print(g->ctx, "\n", 1); APPENDED_ATOM; INSERT_WHITESPACE; - yajl_buf_append(g->buf, "}", 1); + g->print(g->ctx, "}", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } @@ -269,8 +286,8 @@ yajl_gen_array_open(yajl_gen g) ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; INCREMENT_DEPTH; g->state[g->depth] = yajl_gen_array_start; - yajl_buf_append(g->buf, "[", 1); - if (g->pretty) yajl_buf_append(g->buf, "\n", 1); + g->print(g->ctx, "[", 1); + if (g->pretty) g->print(g->ctx, "\n", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } @@ -279,11 +296,11 @@ yajl_gen_status yajl_gen_array_close(yajl_gen g) { ENSURE_VALID_STATE; - if (g->pretty) yajl_buf_append(g->buf, "\n", 1); + if (g->pretty) g->print(g->ctx, "\n", 1); (g->depth)--; APPENDED_ATOM; INSERT_WHITESPACE; - yajl_buf_append(g->buf, "]", 1); + g->print(g->ctx, "]", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } @@ -292,13 +309,14 @@ yajl_gen_status yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf, unsigned int * len) { - *buf = yajl_buf_data(g->buf); - *len = yajl_buf_len(g->buf); + if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf; + *buf = yajl_buf_data((yajl_buf)g->ctx); + *len = yajl_buf_len((yajl_buf)g->ctx); return yajl_gen_status_ok; } void yajl_gen_clear(yajl_gen g) { - yajl_buf_clear(g->buf); + if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx); } |