static int bser_array(const bser_ctx_t *ctx, const json_t *array, void *data) { size_t n = json_array_size(array); size_t i; json_t *templ; if (!is_bser_version_supported(ctx)) { return -1; } templ = json_array_get_template(array); if (templ) { return bser_template(ctx, array, templ, data); } if (ctx->dump(&bser_array_hdr, sizeof(bser_array_hdr), data)) { return -1; } if (bser_int(ctx, n, data)) { return -1; } for (i = 0; i < n; i++) { json_t *val = json_array_get(array, i); if (w_bser_dump(ctx, val, data)) { return -1; } } return 0; }
static int bser_object(json_t *obj, json_dump_callback_t dump, void *data) { size_t n; json_t *val; const char *key; void *iter; if (dump(&bser_object_hdr, sizeof(bser_object_hdr), data)) { return -1; } n = json_object_size(obj); if (bser_int(n, dump, data)) { return -1; } iter = json_object_iter(obj); while (iter) { key = json_object_iter_key(iter); val = json_object_iter_value(iter); if (bser_string(key, dump, data)) { return -1; } if (w_bser_dump(val, dump, data)) { return -1; } iter = json_object_iter_next(obj, iter); } return 0; }
static int bser_array(const json_t *array, json_dump_callback_t dump, void *data) { int n = json_array_size(array); int i; json_t *templ; templ = json_array_get_template(array); if (templ) { return bser_template(array, templ, dump, data); } if (dump(&bser_array_hdr, sizeof(bser_array_hdr), data)) { return -1; } if (bser_int(n, dump, data)) { return -1; } for (i = 0; i < n; i++) { json_t *val = json_array_get(array, i); if (w_bser_dump(val, dump, data)) { return -1; } } return 0; }
int w_bser_write_pdu(const uint32_t bser_version, const uint32_t bser_capabilities, json_dump_callback_t dump, json_t *json, void *data) { json_int_t m_size = 0; bser_ctx_t ctx = { .bser_version = bser_version, .bser_capabilities = bser_capabilities, .dump = measure }; if (!is_bser_version_supported(&ctx)) { return -1; } if (w_bser_dump(&ctx, json, &m_size)) { return -1; } // To actually write the contents ctx.dump = dump; if (bser_version == 2) { if (dump(BSER_V2_MAGIC, 2, data)) { return -1; } } else { if (dump(BSER_MAGIC, 2, data)) { return -1; } } if (bser_version == 2) { if (bser_int(&ctx, bser_capabilities, data)) { return -1; } } if (bser_int(&ctx, m_size, data)) { return -1; } if (w_bser_dump(&ctx, json, data)) { return -1; } return 0; }
static int bser_template(const bser_ctx_t *ctx, const json_t *array, const json_t *templ, void *data) { size_t n = json_array_size(array); size_t i, pn; if (!is_bser_version_supported(ctx)) { return -1; } if (ctx->dump(&bser_template_hdr, sizeof(bser_template_hdr), data)) { return -1; } // The template goes next if (bser_array(ctx, templ, data)) { return -1; } // Now the array of arrays of object values. // How many objects if (bser_int(ctx, n, data)) { return -1; } pn = json_array_size(templ); // For each object for (i = 0; i < n; i++) { json_t *obj = json_array_get(array, i); size_t pi; // For each factored key for (pi = 0; pi < pn; pi++) { const char *key = json_string_value(json_array_get(templ, pi)); json_t *val; // Look up the object property val = json_object_get(obj, key); if (!val) { // property not set on this one; emit a skip if (ctx->dump(&bser_skip, sizeof(bser_skip), data)) { return -1; } continue; } // Emit value if (w_bser_dump(ctx, val, data)) { return -1; } } } return 0; }
int w_bser_write_pdu(json_t *json, json_dump_callback_t dump, void *data) { uint32_t m_size = 0; if (w_bser_dump(json, measure, &m_size)) { return -1; } if (dump(BSER_MAGIC, 2, data)) { return -1; } if (bser_int(m_size, dump, data)) { return -1; } if (w_bser_dump(json, dump, data)) { return -1; } return 0; }
static char *bdumps(json_t *json, char **end) { strbuffer_t strbuff; if (strbuffer_init(&strbuff)) { return NULL; } if (w_bser_dump(json, dump_to_strbuffer, &strbuff) == 0) { *end = strbuff.value + strbuff.length; return strbuff.value; } strbuffer_close(&strbuff); return NULL; }
static int bser_object(const bser_ctx_t *ctx, json_t *obj, void *data) { size_t n; json_t *val; const char *key; void *iter; if (!is_bser_version_supported(ctx)) { return -1; } if (ctx->dump(&bser_object_hdr, sizeof(bser_object_hdr), data)) { return -1; } n = json_object_size(obj); if (bser_int(ctx, n, data)) { return -1; } iter = json_object_iter(obj); while (iter) { key = json_object_iter_key(iter); val = json_object_iter_value(iter); if (bser_bytestring(ctx, key, data)) { return -1; } if (w_bser_dump(ctx, val, data)) { return -1; } iter = json_object_iter_next(obj, iter); } return 0; }