static void unpack_test(void) { /*************** Test of unpack *****************/ cw_pack_context pc; cw_unpack_context uc; mpack_reader_t mr; cmp_ctx_t cc; cmp_object_t cobj; BEFORE_UTEST(cw_pack_nil(&pc)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_read_tag(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; BEFORE_UTEST(cw_pack_signed(&pc, -1)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_read_tag(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; BEFORE_UTEST(cw_pack_signed(&pc, 100000)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_read_tag(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; BEFORE_UTEST(cw_pack_float(&pc, (float)3.14)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_read_tag(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; BEFORE_UTEST(cw_pack_double(&pc, 3.14)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_read_tag(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; BEFORE_UTEST(cw_pack_str(&pc, "Claes",5)); UTEST("CMP", cmp_read_object(&cc, &cobj)); UTEST("MPack", mpack_skip_bytes(&mr,mpack_expect_str(&mr));mpack_done_str(&mr)); UTEST("CWPack", cw_unpack_next(&uc)); AFTER_UTEST; }
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 bool element(mpack_reader_t* reader, yajl_gen gen, options_t* options, int depth) { const mpack_tag_t tag = mpack_read_tag(reader); if (mpack_reader_error(reader) != mpack_ok) return false; if (!options->debug && depth == 0 && (tag.type != mpack_type_map && tag.type != mpack_type_array)) { fprintf(stderr, "%s: Top-level object must be a map or array. Try debug viewing mode (-d)\n", options->command); return false; } // TODO check not depth zero switch (tag.type) { case mpack_type_bool: return yajl_gen_bool(gen, tag.v.b) == yajl_gen_status_ok; case mpack_type_nil: return yajl_gen_null(gen) == yajl_gen_status_ok; case mpack_type_int: return yajl_gen_integer(gen, tag.v.i) == yajl_gen_status_ok; case mpack_type_float: return yajl_gen_double(gen, tag.v.f) == yajl_gen_status_ok; case mpack_type_double: return yajl_gen_double(gen, tag.v.d) == yajl_gen_status_ok; case mpack_type_uint: if (tag.v.u > (uint64_t)INT64_MAX) { char buf[32]; snprintf(buf, sizeof(buf), "%" PRIu64, tag.v.u); return yajl_gen_string(gen, (const unsigned char*)buf, strlen(buf)) == yajl_gen_status_ok; } return yajl_gen_integer(gen, (int64_t)tag.v.u) == yajl_gen_status_ok; case mpack_type_str: return string(reader, gen, options, tag.v.l); case mpack_type_bin: if (options->base64) { return base64_bin(reader, gen, options, tag.v.l, options->base64_prefix); } else if (options->debug) { mpack_skip_bytes(reader, tag.v.l); mpack_done_bin(reader); // output nothing to allow us to print our debug string skip_quotes = true; if (yajl_gen_string(gen, (const unsigned char*)"", 0) != yajl_gen_status_ok) return false; skip_quotes = false; char buf[64]; snprintf(buf, sizeof(buf), "<bin of size %u>", tag.v.l); print(out_file, buf, strlen(buf)); return true; } else { fprintf(stderr, "%s: bin unencodable in JSON. Try debug viewing mode (-d)\n", options->command); return false; } case mpack_type_ext: if (options->base64) { return base64_ext(reader, gen, options, tag.exttype, tag.v.l); } else if (options->debug) { mpack_skip_bytes(reader, tag.v.l); mpack_done_ext(reader); // output nothing to allow us to print our debug string skip_quotes = true; if (yajl_gen_string(gen, (const unsigned char*)"", 0) != yajl_gen_status_ok) return false; skip_quotes = false; char buf[64]; snprintf(buf, sizeof(buf), "<ext of type %i size %u>", tag.exttype, tag.v.l); print(out_file, buf, strlen(buf)); return true; } else { fprintf(stderr, "%s: ext type %i unencodable in JSON. Try debug viewing mode (-d)\n", options->command, tag.exttype); return false; } case mpack_type_array: if (yajl_gen_array_open(gen) != yajl_gen_status_ok) return false; for (size_t i = 0; i < tag.v.l; ++i) if (!element(reader, gen, options, depth + 1)) return false; mpack_done_array(reader); return yajl_gen_array_close(gen) == yajl_gen_status_ok; case mpack_type_map: if (yajl_gen_map_open(gen) != yajl_gen_status_ok) return false; for (size_t i = 0; i < tag.v.l; ++i) { if (options->debug) { element(reader, gen, options, depth + 1); } else { uint32_t len = mpack_expect_str(reader); if (mpack_reader_error(reader) != mpack_ok) { fprintf(stderr, "%s: map key is not a string. Try debug viewing mode (-d)\n", options->command); return false; } if (!string(reader, gen, options, len)) return false; } if (!element(reader, gen, options, depth + 1)) return false; } mpack_done_map(reader); return yajl_gen_map_close(gen) == yajl_gen_status_ok; } return true; }