mpack_tag_t mpack_peek_tag(mpack_reader_t* reader) { mpack_log("peeking tag\n"); // make sure we can peek a tag if (mpack_reader_error(reader) != mpack_ok) return mpack_tag_nil(); if (mpack_reader_track_peek_element(reader) != mpack_ok) return mpack_tag_nil(); mpack_tag_t tag; mpack_memset(&tag, 0, sizeof(tag)); if (mpack_parse_tag(reader, &tag) == 0) return mpack_tag_nil(); return tag; }
mpack_tag_t mpack_read_tag(mpack_reader_t* reader) { mpack_log("reading tag\n"); // make sure we can read a tag if (mpack_reader_error(reader) != mpack_ok) return mpack_tag_nil(); if (mpack_reader_track_element(reader) != mpack_ok) return mpack_tag_nil(); mpack_tag_t tag; mpack_memset(&tag, 0, sizeof(tag)); size_t count = mpack_parse_tag(reader, &tag); if (count == 0) return mpack_tag_nil(); #if MPACK_READ_TRACKING mpack_error_t track_error = mpack_ok; switch (tag.type) { case mpack_type_map: case mpack_type_array: track_error = mpack_track_push(&reader->track, tag.type, tag.v.l); break; case mpack_type_str: case mpack_type_bin: case mpack_type_ext: track_error = mpack_track_push(&reader->track, tag.type, tag.v.n); break; default: break; } if (track_error != mpack_ok) { mpack_reader_flag_error(reader, track_error); return mpack_tag_nil(); } #endif // the tag is guaranteed to have been read out of // the buffer, so we advance past it reader->pos += count; reader->left -= count; return tag; }
static void test_reader_miscellaneous() { // 0xc1 is reserved; it should always raise mpack_error_invalid TEST_SIMPLE_READ_ERROR("\xc1", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); // simple truncated tags (testing discard of additional // temporary data in mpack_parse_tag()) TEST_SIMPLE_READ_ERROR("\xcc", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xcd", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xce", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xcf", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xd0", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xd1", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xd2", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); TEST_SIMPLE_READ_ERROR("\xd3", mpack_tag_equal(mpack_read_tag(&reader), mpack_tag_nil()), mpack_error_invalid); // truncated discard errors TEST_SIMPLE_READ_ERROR("\x91", (mpack_discard(&reader), true), mpack_error_invalid); // array TEST_SIMPLE_READ_ERROR("\x81", (mpack_discard(&reader), true), mpack_error_invalid); // map }
static void test_node_read_misc() { mpack_node_data_t pool[128]; TEST_SIMPLE_TREE_READ("\xc0", (mpack_node_nil(node), true)); TEST_SIMPLE_TREE_READ("\xc2", false == mpack_node_bool(node)); TEST_SIMPLE_TREE_READ("\xc2", (mpack_node_false(node), true)); TEST_SIMPLE_TREE_READ("\xc3", true == mpack_node_bool(node)); TEST_SIMPLE_TREE_READ("\xc3", (mpack_node_true(node), true)); TEST_SIMPLE_TREE_READ_ERROR("\xc2", (mpack_node_true(node), true), mpack_error_type); TEST_SIMPLE_TREE_READ_ERROR("\xc3", (mpack_node_false(node), true), mpack_error_type); TEST_SIMPLE_TREE_READ("\xc0", mpack_tag_equal(mpack_tag_nil(), mpack_node_tag(node))); TEST_SIMPLE_TREE_READ("\xc2", mpack_tag_equal(mpack_tag_false(), mpack_node_tag(node))); TEST_SIMPLE_TREE_READ("\xc3", mpack_tag_equal(mpack_tag_true(), mpack_node_tag(node))); // test missing space for cstr null-terminator char buf[1]; mpack_tree_t tree; mpack_tree_init_pool(&tree, "\xa0", 1, pool, sizeof(pool) / sizeof(*pool)); TEST_ASSERT(mpack_node_copy_cstr(mpack_tree_root(&tree), buf, 0)); #ifdef MPACK_MALLOC TEST_BREAK(NULL == mpack_node_cstr_alloc(mpack_tree_root(&tree), 0)); TEST_TREE_DESTROY_ERROR(&tree, mpack_error_bug); #else TEST_TREE_DESTROY_NOERROR(&tree); #endif // test pool too small mpack_node_data_t small_pool[1]; mpack_tree_init_pool(&tree, "\x91\xc0", 2, small_pool, 1); TEST_TREE_DESTROY_ERROR(&tree, mpack_error_too_big); TEST_BREAK((mpack_tree_init_pool(&tree, "\xc0", 1, small_pool, 0), true)); TEST_TREE_DESTROY_ERROR(&tree, mpack_error_bug); }