char* mpack_expect_str_alloc(mpack_reader_t* reader, size_t maxsize, size_t* size) { *size = 0; if (maxsize > UINT32_MAX) maxsize = UINT32_MAX; size_t length = mpack_expect_str_max(reader, (uint32_t)maxsize); char* str = mpack_read_bytes_alloc(reader, length); mpack_done_str(reader); if (str) *size = length; return str; }
// 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; }
void mpack_expect_str_match(mpack_reader_t* reader, const char* str, size_t len) { // expect a str the correct length if (len > UINT32_MAX) mpack_reader_flag_error(reader, mpack_error_type); mpack_expect_str_length(reader, (uint32_t)len); if (mpack_reader_error(reader)) return; // check each byte for (size_t i = 0; i < len; ++i) { mpack_reader_track_bytes(reader, 1); if (mpack_read_native_u8(reader) != *str++) { mpack_reader_flag_error(reader, mpack_error_type); return; } } mpack_done_str(reader); }
void mpack_discard(mpack_reader_t* reader) { mpack_tag_t var = mpack_read_tag(reader); if (mpack_reader_error(reader)) return; switch (var.type) { case mpack_type_str: mpack_skip_bytes(reader, var.v.l); mpack_done_str(reader); break; case mpack_type_bin: mpack_skip_bytes(reader, var.v.l); mpack_done_bin(reader); break; case mpack_type_ext: mpack_skip_bytes(reader, var.v.l); mpack_done_ext(reader); break; case mpack_type_array: { for (; var.v.n > 0; --var.v.n) { mpack_discard(reader); if (mpack_reader_error(reader)) break; } mpack_done_array(reader); break; } case mpack_type_map: { for (; var.v.n > 0; --var.v.n) { mpack_discard(reader); mpack_discard(reader); if (mpack_reader_error(reader)) break; } mpack_done_map(reader); break; } default: break; } }
static char* mpack_expect_cstr_alloc_unchecked(mpack_reader_t* reader, size_t maxsize, size_t* out_length) { *out_length = 0; // make sure argument makes sense if (maxsize < 1) { mpack_break("maxsize is zero; you must have room for at least a null-terminator"); mpack_reader_flag_error(reader, mpack_error_bug); return NULL; } if (maxsize > UINT32_MAX) maxsize = UINT32_MAX; size_t length = mpack_expect_str_max(reader, (uint32_t)maxsize - 1); char* str = mpack_read_bytes_alloc_size(reader, length, length + 1); mpack_done_str(reader); if (str) { str[length] = 0; *out_length = length; } return str; }
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; } }