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);
/* 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");
/* 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);
}
/* 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);
}
/* 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);
/* 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)
#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)
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 */
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);
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;
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;
}
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;