Browse Source

Add a json_object_to_json_string_ext() function to allow the formatting of output to be selected.

There are now three options: JSON_C_TO_STRING_SPACED, JSON_C_TO_STRING_PLAIN and JSON_C_TO_STRING_PRETTY.
This also add a json_object_to_file_ext() that takes the same flags.
Existing output of json_object_to_json_string() is unchanged, and uses JSON_C_TO_STRING_SPACED.
Thanks fo Grant Edwards for the initial patches.
tags/json-c-0.10-20120530
Eric Haszlakiewicz 13 years ago
parent
commit
3fcffe1bb0
5 changed files with 171 additions and 51 deletions
  1. +120
    -44
      json_object.c
  2. +32
    -1
      json_object.h
  3. +3
    -1
      json_object_private.h
  4. +14
    -5
      json_util.c
  5. +2
    -0
      json_util.h

+ 120
- 44
json_object.c View File

@@ -180,45 +180,88 @@ enum json_type json_object_get_type(struct json_object *jso)
return jso->o_type;
}

/* json_object_to_json_string */
/* extended conversion to string */

const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
{
if (!jso)
return "null";

if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
return NULL;

printbuf_reset(jso->_pb);

if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
return NULL;

return jso->_pb->buf;
}

/* backwards-compatible conversion to string */

const char* json_object_to_json_string(struct json_object *jso)
{
if(!jso) return "null";
if(!jso->_pb) {
if(!(jso->_pb = printbuf_new())) return NULL;
} else {
printbuf_reset(jso->_pb);
}
if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
return jso->_pb->buf;
return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
}

static void indent(struct printbuf *pb, int level, int flags)
{
if (flags & JSON_C_TO_STRING_PRETTY)
{
printbuf_memset(pb, -1, ' ', level * 2);
}
}

/* json_object_object */

static int json_object_object_to_json_string(struct json_object* jso,
struct printbuf *pb)
{
int i=0;
struct json_object_iter iter;
sprintbuf(pb, "{");

/* CAW: scope operator to make ANSI correctness */
/* CAW: switched to json_object_object_foreachC which uses an iterator struct */
json_object_object_foreachC(jso, iter) {
if(i) sprintbuf(pb, ",");
sprintbuf(pb, " \"");
json_escape_str(pb, iter.key, strlen(iter.key));
struct printbuf *pb,
int level,
int flags)
{
int had_children = 0;
struct json_object_iter iter;

sprintbuf(pb, "{" /*}*/);
if (flags & JSON_C_TO_STRING_PRETTY)
sprintbuf(pb, "\n");
json_object_object_foreachC(jso, iter)
{
if (had_children)
{
sprintbuf(pb, ",");
if (flags & JSON_C_TO_STRING_PRETTY)
sprintbuf(pb, "\n");
}
had_children = 1;
if (flags & JSON_C_TO_STRING_SPACED)
sprintbuf(pb, " ");
indent(pb, level+1, flags);
sprintbuf(pb, "\"");
json_escape_str(pb, iter.key, strlen(iter.key));
if (flags & JSON_C_TO_STRING_SPACED)
sprintbuf(pb, "\": ");
if(iter.val == NULL) sprintbuf(pb, "null");
else iter.val->_to_json_string(iter.val, pb);
i++;
else
sprintbuf(pb, "\":");
if(iter.val == NULL)
sprintbuf(pb, "null");
else
iter.val->_to_json_string(iter.val, pb, level+1,flags);
}

return sprintbuf(pb, " }");
if (flags & JSON_C_TO_STRING_PRETTY)
{
if (had_children)
sprintbuf(pb, "\n");
indent(pb,level,flags);
}
if (flags & JSON_C_TO_STRING_SPACED)
return sprintbuf(pb, /*{*/ " }");
else
return sprintbuf(pb, /*{*/ "}");
}


static void json_object_lh_entry_free(struct lh_entry *ent)
{
free(ent->k);
@@ -291,7 +334,9 @@ void json_object_object_del(struct json_object* jso, const char *key)
/* json_object_boolean */

static int json_object_boolean_to_json_string(struct json_object* jso,
struct printbuf *pb)
struct printbuf *pb,
int level,
int flags)
{
if(jso->o.c_boolean) return sprintbuf(pb, "true");
else return sprintbuf(pb, "false");
@@ -327,7 +372,9 @@ json_bool json_object_get_boolean(struct json_object *jso)
/* json_object_int */

static int json_object_int_to_json_string(struct json_object* jso,
struct printbuf *pb)
struct printbuf *pb,
int level,
int flags)
{
return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
}
@@ -412,7 +459,9 @@ int64_t json_object_get_int64(struct json_object *jso)
/* json_object_double */

static int json_object_double_to_json_string(struct json_object* jso,
struct printbuf *pb)
struct printbuf *pb,
int level,
int flags)
{
return sprintbuf(pb, "%lf", jso->o.c_double);
}
@@ -449,7 +498,9 @@ double json_object_get_double(struct json_object *jso)
/* json_object_string */

static int json_object_string_to_json_string(struct json_object* jso,
struct printbuf *pb)
struct printbuf *pb,
int level,
int flags)
{
sprintbuf(pb, "\"");
json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
@@ -511,20 +562,45 @@ int json_object_get_string_len(struct json_object *jso) {
/* json_object_array */

static int json_object_array_to_json_string(struct json_object* jso,
struct printbuf *pb)
{
int i;
sprintbuf(pb, "[");
for(i=0; i < json_object_array_length(jso); i++) {
struct json_object *val;
if(i) { sprintbuf(pb, ", "); }
else { sprintbuf(pb, " "); }

val = json_object_array_get_idx(jso, i);
if(val == NULL) { sprintbuf(pb, "null"); }
else { val->_to_json_string(val, pb); }
}
return sprintbuf(pb, " ]");
struct printbuf *pb,
int level,
int flags)
{
int had_children = 0;
int ii;
sprintbuf(pb, "[");
if (flags & JSON_C_TO_STRING_PRETTY)
sprintbuf(pb, "\n");
for(ii=0; ii < json_object_array_length(jso); ii++)
{
struct json_object *val;
if (had_children)
{
sprintbuf(pb, ",");
if (flags & JSON_C_TO_STRING_PRETTY)
sprintbuf(pb, "\n");
}
had_children = 1;
if (flags & JSON_C_TO_STRING_SPACED)
sprintbuf(pb, " ");
indent(pb, level + 1, flags);
val = json_object_array_get_idx(jso, ii);
if(val == NULL)
sprintbuf(pb, "null");
else
val->_to_json_string(val, pb, level+1, flags);
}
if (flags & JSON_C_TO_STRING_PRETTY)
{
if (had_children)
sprintbuf(pb, "\n");
indent(pb,level,flags);
}

if (flags & JSON_C_TO_STRING_SPACED)
return sprintbuf(pb, " ]");
else
return sprintbuf(pb, "]");
}

static void json_object_array_entry_free(void *data)


+ 32
- 1
json_object.h View File

@@ -21,6 +21,28 @@ extern "C" {

#define JSON_OBJECT_DEF_HASH_ENTRIES 16

/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes the output
* to have no extra whitespace or formatting applied.
*/
#define JSON_C_TO_STRING_PLAIN 0
/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes the output to have
* minimal whitespace inserted to make things slightly more readable.
*/
#define JSON_C_TO_STRING_SPACED (1<<0)
/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes
* the output to be formatted.
*
* See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/
* for an example of the format.
*/
#define JSON_C_TO_STRING_PRETTY (1<<1)

#undef FALSE
#define FALSE ((json_bool)0)

@@ -112,12 +134,21 @@ extern int json_object_is_type(struct json_object *obj, enum json_type type);
extern enum json_type json_object_get_type(struct json_object *obj);


/** Stringify object to json format
/** Stringify object to json format.
* Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
* @param obj the json_object instance
* @returns a string in JSON format
*/
extern const char* json_object_to_json_string(struct json_object *obj);

/** Stringify object to json format
* @param obj the json_object instance
* @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
* @returns a string in JSON format
*/
extern const char* json_object_to_json_string_ext(struct json_object *obj, int
flags);


/* object type methods */



+ 3
- 1
json_object_private.h View File

@@ -18,7 +18,9 @@ extern "C" {

typedef void (json_object_delete_fn)(struct json_object *o);
typedef int (json_object_to_json_string_fn)(struct json_object *o,
struct printbuf *pb);
struct printbuf *pb,
int level,
int flags);

struct json_object
{


+ 14
- 5
json_util.c View File

@@ -65,12 +65,12 @@ struct json_object* json_object_from_file(const char *filename)
if((fd = open(filename, O_RDONLY)) < 0) {
MC_ERROR("json_object_from_file: error reading file %s: %s\n",
filename, strerror(errno));
return (struct json_object*)error_ptr(-1);
return NULL; // XAX this is an API change!
}
if(!(pb = printbuf_new())) {
close(fd);
MC_ERROR("json_object_from_file: printbuf_new failed\n");
return (struct json_object*)error_ptr(-1);
return NULL;
}
while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
printbuf_memappend(pb, buf, ret);
@@ -80,14 +80,16 @@ struct json_object* json_object_from_file(const char *filename)
MC_ABORT("json_object_from_file: error reading file %s: %s\n",
filename, strerror(errno));
printbuf_free(pb);
return (struct json_object*)error_ptr(-1);
return NULL;
}
obj = json_tokener_parse(pb->buf);
printbuf_free(pb);
return obj;
}

int json_object_to_file(char *filename, struct json_object *obj)
/* extended "format and write to file" function */

int json_object_to_file_ext(char *filename, struct json_object *obj, int flags)
{
const char *json_str;
int fd, ret;
@@ -104,7 +106,7 @@ int json_object_to_file(char *filename, struct json_object *obj)
return -1;
}

if(!(json_str = json_object_to_json_string(obj))) {
if(!(json_str = json_object_to_json_string_ext(obj,flags))) {
close(fd);
return -1;
}
@@ -127,6 +129,13 @@ int json_object_to_file(char *filename, struct json_object *obj)
return 0;
}

// backwards compatible "format and write to file" function

int json_object_to_file(char *filename, struct json_object *obj)
{
return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
}

int json_parse_int64(const char *buf, int64_t *retval)
{
int64_t num64;


+ 2
- 0
json_util.h View File

@@ -23,8 +23,10 @@ extern "C" {
/* utility functions */
extern struct json_object* json_object_from_file(const char *filename);
extern int json_object_to_file(char *filename, struct json_object *obj);
extern int json_object_to_file_ext(char *filename, struct json_object *obj, int flags);
extern int json_parse_int64(const char *buf, int64_t *retval);


/**
* Return a string describing the type of the object.
* e.g. "int", or "object", etc...


Loading…
Cancel
Save