Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow yajl_gen to serialize yajl_val and raw json strings #74

Open
wants to merge 2 commits into from

3 participants

@deepfryed

Hi,

I wanted this feature so i can extract yajl_val snippets from yajl_tree and pass them on to yajl_gen or pass a raw fully formed json snippet to yajl_gen.

I've not seen any tests for yajl_tree and yajl_gen in the codebase atm, but I'd be happy to add some if you're interested in merging this.

Thanks

@stewartbrodie stewartbrodie commented on the diff
src/yajl_gen.c
((28 lines not shown))
+ }
+ status = yajl_gen_array_close(g);
+ if (status != yajl_gen_status_ok) return status;
+ }
+ else if (YAJL_IS_OBJECT(v)) {
+ status = yajl_gen_map_open(g);
+ if (status != yajl_gen_status_ok) return status;
+ for (i = 0; i < YAJL_GET_OBJECT(v)->len; i++) {
+ key = YAJL_GET_OBJECT(v)->keys[i];
+ status = yajl_gen_string(g, (const unsigned char*)key, strlen(key));
+ if (status != yajl_gen_status_ok) return status;
+ status = yajl_gen_val(g, YAJL_GET_OBJECT(v)->values[i]);
+ if (status != yajl_gen_status_ok) return status;
+ }
+ status = yajl_gen_map_close(g);
+ if (status != yajl_gen_status_ok) return status;

This return should not be conditional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stewartbrodie stewartbrodie commented on the diff
src/yajl_gen.c
((15 lines not shown))
+ return yajl_gen_bool(g, 1);
+ else if (YAJL_IS_FALSE(v))
+ return yajl_gen_bool(g, 0);
+ else if (YAJL_IS_NUMBER(v))
+ return yajl_gen_number(g, v->u.number.r, strlen(v->u.number.r));
+ else if (YAJL_IS_STRING(v))
+ return yajl_gen_string(g, (const unsigned char*)v->u.string, strlen(v->u.string));
+ else if (YAJL_IS_ARRAY(v)) {
+ status = yajl_gen_array_open(g);
+ if (status != yajl_gen_status_ok) return status;
+ for (i = 0; i < YAJL_GET_ARRAY(v)->len; i++) {
+ status = yajl_gen_val(g, YAJL_GET_ARRAY(v)->values[i]);
+ if (status != yajl_gen_status_ok) return status;
+ }
+ status = yajl_gen_array_close(g);
+ if (status != yajl_gen_status_ok) return status;

This return should not be conditional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@stewartbrodie

Hi deepfryed,

I realise that this is a couple of years old now, but I was looking for some code to do exactly this, so I tried incorporating your patch into my build of yajl. Apart from one trivial problem, it's working well for me. I've marked the two places above - as the code stands, processing objects and arrays always returns a failure.

@soulofmachines

stewartbrodie, these should fix the problem

diff --git a/src/yajl_gen.c b/src/yajl_gen.c
index 7024707..8a7e657 100644
--- a/src/yajl_gen.c
+++ b/src/yajl_gen.c
@@ -377,8 +377,7 @@ yajl_gen_val(yajl_gen g, yajl_val v)
             status = yajl_gen_val(g, YAJL_GET_ARRAY(v)->values[i]);
             if (status != yajl_gen_status_ok) return status;
         }
-        status = yajl_gen_array_close(g);
-        if (status != yajl_gen_status_ok) return status;
+        return yajl_gen_array_close(g);
     }
     else if (YAJL_IS_OBJECT(v)) {
         status = yajl_gen_map_open(g);
@@ -390,8 +389,7 @@ yajl_gen_val(yajl_gen g, yajl_val v)
             status = yajl_gen_val(g, YAJL_GET_OBJECT(v)->values[i]);
             if (status != yajl_gen_status_ok) return status;
         }
-        status = yajl_gen_map_close(g);
-        if (status != yajl_gen_status_ok) return status;
+        return yajl_gen_map_close(g);
     }

     /* if control reaches here then something must have gone terribly wrong */
@soulofmachines soulofmachines referenced this pull request from a commit in soulofmachines/i3barout
@soulofmachines soulofmachines add sorting (lloyd/yajl#74) 96d5faf
@stewartbrodie

Yes, thanks soulofmachines, I agree with that patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 28, 2012
  1. @deepfryed
Commits on Mar 1, 2012
  1. @deepfryed
This page is out of date. Refresh to see the latest.
Showing with 68 additions and 10 deletions.
  1. +5 −2 src/api/yajl_gen.h
  2. +1 −1  src/api/yajl_tree.h
  3. +62 −7 src/yajl_gen.c
View
7 src/api/yajl_gen.h
@@ -20,6 +20,7 @@
*/
#include <yajl/yajl_common.h>
+#include <yajl/yajl_tree.h>
#ifndef __YAJL_GEN_H__
#define __YAJL_GEN_H__
@@ -43,7 +44,7 @@ extern "C" {
* state */
yajl_gen_in_error_state,
/** A complete JSON document has been generated */
- yajl_gen_generation_complete,
+ yajl_gen_generation_complete,
/** yajl_gen_double was passed an invalid floating point value
* (infinity or NaN). */
yajl_gen_invalid_number,
@@ -137,6 +138,8 @@ extern "C" {
YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand);
YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand);
YAJL_API yajl_gen_status yajl_gen_array_close(yajl_gen hand);
+ YAJL_API yajl_gen_status yajl_gen_val(yajl_gen hand, yajl_val v);
+ YAJL_API yajl_gen_status yajl_gen_raw(yajl_gen hand, char *, size_t);
/** access the null terminated generator buffer. If incrementally
* outputing JSON, one should call yajl_gen_clear to clear the
@@ -152,6 +155,6 @@ extern "C" {
#ifdef __cplusplus
}
-#endif
+#endif
#endif
View
2  src/api/yajl_tree.h
@@ -137,7 +137,7 @@ YAJL_API void yajl_tree_free (yajl_val v);
* \param type the yajl_type of the object you seek, or yajl_t_any if any will do.
*
* \returns a pointer to the found value, or NULL if we came up empty.
- *
+ *
* Future Ideas: it'd be nice to move path to a string and implement support for
* a teeny tiny micro language here, so you can extract array elements, do things
* like .first and .last, even .length. Inspiration from JSONPath and css selectors?
View
69 src/yajl_gen.c
@@ -140,7 +140,7 @@ yajl_gen_free(yajl_gen g)
} else if (g->state[g->depth] == yajl_gen_map_val) { \
g->print(g->ctx, ":", 1); \
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, " ", 1); \
- }
+ }
#define INSERT_WHITESPACE \
if ((g->flags & yajl_gen_beautify)) { \
@@ -219,7 +219,7 @@ yajl_gen_status
yajl_gen_double(yajl_gen g, double number)
{
char i[32];
- ENSURE_VALID_STATE; ENSURE_NOT_KEY;
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY;
if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
INSERT_SEP; INSERT_WHITESPACE;
sprintf(i, "%.20g", number);
@@ -289,8 +289,8 @@ yajl_gen_status
yajl_gen_map_open(yajl_gen g)
{
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
- INCREMENT_DEPTH;
-
+ INCREMENT_DEPTH;
+
g->state[g->depth] = yajl_gen_map_start;
g->print(g->ctx, "{", 1);
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
@@ -301,9 +301,9 @@ yajl_gen_map_open(yajl_gen g)
yajl_gen_status
yajl_gen_map_close(yajl_gen g)
{
- ENSURE_VALID_STATE;
+ ENSURE_VALID_STATE;
DECREMENT_DEPTH;
-
+
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
APPENDED_ATOM;
INSERT_WHITESPACE;
@@ -316,7 +316,7 @@ yajl_gen_status
yajl_gen_array_open(yajl_gen g)
{
ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
- INCREMENT_DEPTH;
+ INCREMENT_DEPTH;
g->state[g->depth] = yajl_gen_array_start;
g->print(g->ctx, "[", 1);
if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
@@ -352,3 +352,58 @@ yajl_gen_clear(yajl_gen g)
{
if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx);
}
+
+yajl_gen_status
+yajl_gen_val(yajl_gen g, yajl_val v)
+{
+ size_t i;
+ const char *key;
+ yajl_gen_status status;
+
+ if (YAJL_IS_NULL(v))
+ return yajl_gen_null(g);
+ else if (YAJL_IS_TRUE(v))
+ return yajl_gen_bool(g, 1);
+ else if (YAJL_IS_FALSE(v))
+ return yajl_gen_bool(g, 0);
+ else if (YAJL_IS_NUMBER(v))
+ return yajl_gen_number(g, v->u.number.r, strlen(v->u.number.r));
+ else if (YAJL_IS_STRING(v))
+ return yajl_gen_string(g, (const unsigned char*)v->u.string, strlen(v->u.string));
+ else if (YAJL_IS_ARRAY(v)) {
+ status = yajl_gen_array_open(g);
+ if (status != yajl_gen_status_ok) return status;
+ for (i = 0; i < YAJL_GET_ARRAY(v)->len; i++) {
+ status = yajl_gen_val(g, YAJL_GET_ARRAY(v)->values[i]);
+ if (status != yajl_gen_status_ok) return status;
+ }
+ status = yajl_gen_array_close(g);
+ if (status != yajl_gen_status_ok) return status;

This return should not be conditional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ else if (YAJL_IS_OBJECT(v)) {
+ status = yajl_gen_map_open(g);
+ if (status != yajl_gen_status_ok) return status;
+ for (i = 0; i < YAJL_GET_OBJECT(v)->len; i++) {
+ key = YAJL_GET_OBJECT(v)->keys[i];
+ status = yajl_gen_string(g, (const unsigned char*)key, strlen(key));
+ if (status != yajl_gen_status_ok) return status;
+ status = yajl_gen_val(g, YAJL_GET_OBJECT(v)->values[i]);
+ if (status != yajl_gen_status_ok) return status;
+ }
+ status = yajl_gen_map_close(g);
+ if (status != yajl_gen_status_ok) return status;

This return should not be conditional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ /* if control reaches here then something must have gone terribly wrong */
+ return yajl_gen_in_error_state;
+}
+
+yajl_gen_status
+yajl_gen_raw(yajl_gen g, char *json, size_t size)
+{
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
+ g->print(g->ctx, json, size);
+ APPENDED_ATOM;
+ FINAL_NEWLINE;
+ return yajl_gen_status_ok;
+}
Something went wrong with that request. Please try again.