X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fjson_out%2Fjson_out.h;fp=ccan%2Fjson_out%2Fjson_out.h;h=a3ebdb13e384af7bc27751608fcae96bc443f7eb;hb=2fd44331077429da94f8f7eb43513068257742f8;hp=0000000000000000000000000000000000000000;hpb=3ceb24bf19adbe59bf8aeda9cc1426b4ba2244c2;p=ccan diff --git a/ccan/json_out/json_out.h b/ccan/json_out/json_out.h new file mode 100644 index 00000000..a3ebdb13 --- /dev/null +++ b/ccan/json_out/json_out.h @@ -0,0 +1,189 @@ +/* MIT (BSD) license - see LICENSE file for details */ +#ifndef CCAN_JSON_OUT_H +#define CCAN_JSON_OUT_H +#include +#include +#include +#include + +struct json_out; + +/** + * json_out_new - allocate a json_out stream. + * @ctx: the tal_context to allocate from, or NULL + */ +struct json_out *json_out_new(const tal_t *ctx); + +/** + * json_out_call_on_move - callback for when buffer is reallocated. + * @jout: the json_out object to attach to. + * @cb: the callback to call. + * @arg: the argument to @cb (must match type). + * + * A NULL @cb disables. You can't currently have more than one callback. + * The @delta argument to @cb is the difference between the old location + * and the new one, and is never zero. + */ +#define json_out_call_on_move(jout, cb, arg) \ + json_out_call_on_move_((jout), \ + typesafe_cb_preargs(void, void *, \ + (cb), (arg), \ + struct json_out *, \ + ptrdiff_t), \ + (arg)) + +void json_out_call_on_move_(struct json_out *jout, + void (*cb)(struct json_out *jout, ptrdiff_t delta, + void *arg), + void *arg); + +/** + * json_out_dup - duplicate a json_out stream. + * @ctx: the tal_context to allocate from, or NULL + * @src: the json_out to copy. + */ +struct json_out *json_out_dup(const tal_t *ctx, const struct json_out *src); + +/** + * json_out_start - start an array or object. + * @jout: the json_out object to write into. + * @fieldname: the fieldname, if inside an object, or NULL if inside an array. + * @type: '[' or '{' to start an array or object, respectively. + * + * Literally writes '"@fieldname": @type' or '@type ' if fieldname is NULL. + * @fieldname must not need JSON escaping. + */ +void json_out_start(struct json_out *jout, const char *fieldname, char type); + +/** + * json_out_end - end an array or object. + * @jout: the json_out object to write into. + * @type: '}' or ']' to end an array or object, respectively. + * + * Literally writes ']' or '}', keeping track of whether we need to append + * a comma. + */ +void json_out_end(struct json_out *jout, char type); + +/** + * json_out_add - add a formatted member. + * @jout: the json_out object to write into. + * @fieldname: optional fieldname to prepend (must not need escaping). + * @quote: if true, surround fmt by " and ". + * @fmt...: the printf-style format + * + * If you're in an array, @fieldname must be NULL. If you're in an + * object, @fieldname must be non-NULL. This is checked if + * CCAN_JSON_OUT_DEBUG is defined. + * @fieldname must not need JSON escaping. + * + * If the resulting string requires escaping, we call json_escape(). + */ +PRINTF_FMT(4,5) +void json_out_add(struct json_out *jout, + const char *fieldname, + bool quote, + const char *fmt, ...); + +/** + * json_out_addv - add a formatted member (vararg variant) + * @jout: the json_out object to write into. + * @fieldname: optional fieldname to prepend. + * @quote: if true, surround fmt by " and ". + * @fmt: the printf-style format + * @ap: the argument list. + * + * See json_out_add() above. + */ +void json_out_addv(struct json_out *jout, + const char *fieldname, + bool quote, + const char *fmt, + va_list ap); + +/** + * json_out_addstr - convenience helper to add a string field. + * @jout: the json_out object to write into. + * @fieldname: optional fieldname to prepend. + * @str: the string to add (must not be NULL). + * + * Equivalent to json_out_add(@jout, @fieldname, true, "%s", @str); + */ +void json_out_addstr(struct json_out *jout, + const char *fieldname, + const char *str); + +/** + * json_out_member_direct - add a field, with direct access. + * @jout: the json_out object to write into. + * @fieldname: optional fieldname to prepend. + * @extra: how many bytes to allocate. + * + * @fieldname must not need JSON escaping. Returns a direct pointer into + * the @extra bytes. + * + * This allows you to write your own efficient type-specific helpers. + */ +char *json_out_member_direct(struct json_out *jout, + const char *fieldname, size_t extra); + +/** + * json_out_direct - make room in output and access directly. + * @jout: the json_out object to write into. + * @len: the length to allocate. + * + * This lets you access the json_out stream directly, to save a copy, + * if you know exactly how much you will write. + * + * Returns a pointer to @len bytes at the end of @jout. + * + * This is dangerous, since it doesn't automatically prepend a "," + * like the internal logic does, but can be used (carefully) to add + * entire objects, or whitespace. + */ +char *json_out_direct(struct json_out *jout, size_t extra); + +/** + * json_out_add_splice - copy a field from another json_out. + * @jout: the json_out object to write into. + * @fieldname: optional fieldname to prepend. + * @src: the json_out object to copy from. + * + * This asserts that @src is well-formed (as per json_out_finished()), + * then places it into @jout with optional @fieldname prepended. This + * can be used to assemble sub-objects for your JSON and then copy + * them in. + * + * Note that it will call json_out_contents(@src), so it expects that + * object to be unconsumed. + */ +void json_out_add_splice(struct json_out *jout, + const char *fieldname, + const struct json_out *src); + +/** + * json_out_finished - assert that the json buffer is finished. + * @jout: the json_out object written to. + * + * This simply causes internal assertions that all arrays and objects are + * finished. It needs CCAN_JSON_OUT_DEBUG defined to have any effect. + */ +void json_out_finished(const struct json_out *jout); + +/** + * json_out_contents - read contents from json_out stream. + * @jout: the json_out object we want to read from. + * @len: set to the length of the buffer returned. + * + * This returns a pointer into the JSON written so far. Returns NULL + * and sets @len to 0 if there's nothing left in the buffer. + */ +const char *json_out_contents(const struct json_out *jout, size_t *len); + +/** + * json_out_consume - discard contents from json_out stream. + * @jout: the json_out object we read from. + * @len: the length to consume (must be <= @len from json_out_contents) + */ +void json_out_consume(struct json_out *jout, size_t len); +#endif /* CCAN_JSON_OUT_H */