// Converts MessagePack bin/ext bytes to JSON base64 string static bool base64(mpack_reader_t* reader, yajl_gen gen, options_t* options, uint32_t len, char* output, char* p, bool prefix) { if (prefix) { memcpy(p, b64_str, strlen(b64_str)); p += strlen(b64_str); } base64_encodestate state; base64_init_encodestate(&state); while (len > 0) { char buf[4096]; uint32_t count = (len < sizeof(buf)) ? len : sizeof(buf); len -= count; mpack_read_bytes(reader, buf, count); if (mpack_reader_error(reader) != mpack_ok) { fprintf(stderr, "%s: error reading base64 bytes\n", options->command); return false; } p += base64_encode_block(buf, (int)count, p, &state); } p += base64_encode_blockend(p, &state); bool ret = yajl_gen_string(gen, (const unsigned char*)output, p - output) == yajl_gen_status_ok; return ret; }
size_t mpack_expect_bin_buf(mpack_reader_t* reader, char* buf, size_t bufsize) { size_t binsize = mpack_expect_bin(reader); if (mpack_reader_error(reader)) return 0; if (binsize > bufsize) { mpack_reader_flag_error(reader, mpack_error_too_big); return 0; } mpack_read_bytes(reader, buf, binsize); if (mpack_reader_error(reader)) return 0; mpack_done_bin(reader); return binsize; }
// Reads MessagePack string bytes and outputs a JSON string static bool string(mpack_reader_t* reader, yajl_gen gen, options_t* options, uint32_t len) { char* str = (char*)malloc(len); mpack_read_bytes(reader, str, len); if (mpack_reader_error(reader) != mpack_ok) { fprintf(stderr, "%s: error reading string bytes\n", options->command); free(str); return false; } mpack_done_str(reader); yajl_gen_status status = yajl_gen_string(gen, (const unsigned char*)str, len); free(str); return status == yajl_gen_status_ok; }
size_t mpack_expect_str_buf(mpack_reader_t* reader, char* buf, size_t bufsize) { size_t length = mpack_expect_str(reader); if (mpack_reader_error(reader)) return 0; if (length > bufsize) { mpack_reader_flag_error(reader, mpack_error_too_big); return 0; } mpack_read_bytes(reader, buf, length); if (mpack_reader_error(reader)) return 0; mpack_done_str(reader); return length; }
static void mpack_print_element(mpack_reader_t* reader, size_t depth, FILE* file) { mpack_tag_t val = mpack_read_tag(reader); if (mpack_reader_error(reader) != mpack_ok) return; switch (val.type) { case mpack_type_nil: fprintf(file, "null"); break; case mpack_type_bool: fprintf(file, val.v.b ? "true" : "false"); break; case mpack_type_float: fprintf(file, "%f", val.v.f); break; case mpack_type_double: fprintf(file, "%f", val.v.d); break; case mpack_type_int: fprintf(file, "%" PRIi64, val.v.i); break; case mpack_type_uint: fprintf(file, "%" PRIu64, val.v.u); break; case mpack_type_bin: fprintf(file, "<binary data of length %u>", val.v.l); mpack_skip_bytes(reader, val.v.l); mpack_done_bin(reader); break; case mpack_type_ext: fprintf(file, "<ext data of type %i and length %u>", val.exttype, val.v.l); mpack_skip_bytes(reader, val.v.l); mpack_done_ext(reader); break; case mpack_type_str: putc('"', file); for (size_t i = 0; i < val.v.l; ++i) { char c; mpack_read_bytes(reader, &c, 1); if (mpack_reader_error(reader) != mpack_ok) return; switch (c) { case '\n': fprintf(file, "\\n"); break; case '\\': fprintf(file, "\\\\"); break; case '"': fprintf(file, "\\\""); break; default: putc(c, file); break; } } putc('"', file); mpack_done_str(reader); break; case mpack_type_array: fprintf(file, "[\n"); for (size_t i = 0; i < val.v.n; ++i) { for (size_t j = 0; j < depth + 1; ++j) fprintf(file, " "); mpack_print_element(reader, depth + 1, file); if (mpack_reader_error(reader) != mpack_ok) return; if (i != val.v.n - 1) putc(',', file); putc('\n', file); } for (size_t i = 0; i < depth; ++i) fprintf(file, " "); putc(']', file); mpack_done_array(reader); break; case mpack_type_map: fprintf(file, "{\n"); for (size_t i = 0; i < val.v.n; ++i) { for (size_t j = 0; j < depth + 1; ++j) fprintf(file, " "); mpack_print_element(reader, depth + 1, file); if (mpack_reader_error(reader) != mpack_ok) return; fprintf(file, ": "); mpack_print_element(reader, depth + 1, file); if (mpack_reader_error(reader) != mpack_ok) return; if (i != val.v.n - 1) putc(',', file); putc('\n', file); } for (size_t i = 0; i < depth; ++i) fprintf(file, " "); putc('}', file); mpack_done_map(reader); break; } }