summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLloyd Hilaiel <lloyd@hilaiel.com>2009-12-05 18:29:44 -0700
committerLloyd Hilaiel <lloyd@hilaiel.com>2009-12-05 18:29:44 -0700
commitbbb833ad7de28df6eebc87156c7a19a4084b82df (patch)
treec87dcdb7154c688c52c444e34e37a0a22db220e4
parent0c5fc370c155da38338ed483ab9a8d36a0c94985 (diff)
parent280f019df0b98fadb9a7d250d92d8cbc4909fd76 (diff)
downloadyajl-bbb833ad7de28df6eebc87156c7a19a4084b82df.tar.gz
Merge branch 'master' of github.com:lloyd/yajl
-rw-r--r--ChangeLog3
-rw-r--r--src/api/yajl_gen.h32
-rw-r--r--src/yajl_encode.c15
-rw-r--r--src/yajl_encode.h6
-rw-r--r--src/yajl_gen.c76
5 files changed, 99 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index d0758b0..dc70788 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
}