// // MessagePack for C++ deserializing routine // // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // #ifndef MSGPACK_V1_UNPACK_HPP #define MSGPACK_V1_UNPACK_HPP
} elseif(0x90 <= selector && selector <= 0x9f) { // FixArray int ret = push_aggregate<fix_tag>(
unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, m_current, off); if (ret != 0) return ret;
} elseif(0x80 <= selector && selector <= 0x8f) { // FixMap int ret = push_aggregate<fix_tag>(
unpack_map(), MSGPACK_CT_MAP_KEY, obj, m_current, off); if (ret != 0) return ret;
} elseif(selector == 0xc2) { // false
unpack_false(obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} elseif(selector == 0xc3) { // true
unpack_true(obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} elseif(selector == 0xc0) { // nil
unpack_nil(obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
off = m_current - m_start; return -1;
} // end MSGPACK_CS_HEADER
} if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) { if (fixed_trail_again) {
++m_current;
fixed_trail_again = false;
} if(static_cast<std::size_t>(pe - m_current) < m_trail) {
off = m_current - m_start; return 0;
}
n = m_current;
m_current += m_trail - 1; switch(m_cs) { //case MSGPACK_CS_ //case MSGPACK_CS_ case MSGPACK_CS_FLOAT: { union { uint32_t i; float f; } mem;
load<uint32_t>(mem.i, n);
unpack_float(mem.f, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_DOUBLE: { union { uint64_t i; double f; } mem;
load<uint64_t>(mem.i, n); #ifdefined(TARGET_OS_IPHONE) // ok #elifdefined(__arm__) && !(__ARM_EABI__) // arm-oabi // https://github.com/msgpack/msgpack-perl/pull/1
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); #endif
unpack_double(mem.f, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_UINT_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
unpack_uint8(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_UINT_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
unpack_uint16(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_UINT_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
unpack_uint32(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_UINT_64: {
uint64_t tmp;
load<uint64_t>(tmp, n);
unpack_uint64(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_INT_8: {
int8_t tmp;
load<int8_t>(tmp, n);
unpack_int8(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_INT_16: {
int16_t tmp;
load<int16_t>(tmp, n);
unpack_int16(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_INT_32: {
int32_t tmp;
load<int32_t>(tmp, n);
unpack_int32(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_INT_64: {
int64_t tmp;
load<int64_t>(tmp, n);
unpack_int64(tmp, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_FIXEXT_1: {
unpack_ext(m_user, n, 1+1, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_FIXEXT_2: {
unpack_ext(m_user, n, 2+1, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_FIXEXT_4: {
unpack_ext(m_user, n, 4+1, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_FIXEXT_8: {
unpack_ext(m_user, n, 8+1, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_FIXEXT_16: {
unpack_ext(m_user, n, 16+1, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_STR_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_STR_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_BIN_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_BIN_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_EXT_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
m_trail = tmp + 1; if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_STR_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_STR_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_BIN_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_BIN_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_EXT_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
m_trail = tmp + 1; if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_STR_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_STR_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_BIN_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
m_trail = tmp; if(m_trail == 0) {
unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_BIN_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_CS_EXT_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
check_ext_size<sizeof(std::size_t)>(tmp);
m_trail = tmp;
++m_trail; if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} else {
m_cs = MSGPACK_ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break; case MSGPACK_ACS_STR_VALUE: {
unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_ACS_BIN_VALUE: {
unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_ACS_EXT_VALUE: {
unpack_ext(m_user, n, m_trail, obj); int ret = push_proc(obj, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_ARRAY_16: { int ret = push_aggregate<uint16_t>(
unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_ARRAY_32: { /* FIXME security guard */ int ret = push_aggregate<uint32_t>(
unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_MAP_16: { int ret = push_aggregate<uint16_t>(
unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off); if (ret != 0) return ret;
} break; case MSGPACK_CS_MAP_32: { /* FIXME security guard */ int ret = push_aggregate<uint32_t>(
unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off); if (ret != 0) return ret;
} break; default:
off = m_current - m_start; return -1;
}
}
} while(m_current != pe);
off = m_current - m_start; return 0;
}
} // detail
/// Unpacking class for a stream deserialization. class unpacker { public: /// Constructor /** * @param f A judging function that msgpack::object refer to the buffer. * @param user_data This parameter is passed to f. * @param initial_buffer_size The memory size to allocate when unpacker is constructed. * @param limit The size limit information of msgpack::object. *
*/
unpacker(unpack_reference_func f = &unpacker::default_reference_func, void* user_data = MSGPACK_NULLPTR,
std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
unpack_limit const& limit = unpack_limit());
/// Notify a buffer consumed information to msgpack::unpacker. /** * @param size The size of memory that you consumed. * * After copying the data to the memory that is pointed by buffer(), you need to call the * function to notify how many bytes are consumed. Then you can call next() functions. * * See: * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
*/ void buffer_consumed(std::size_t size);
/// Unpack one msgpack::object. [obsolete] /** * * @param result The object that contains unpacked data. * * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete * and additional data is required, then return false. If data format is invalid, throw * msgpack::parse_error. * * See: * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer * This function is obsolete. Use the reference inteface version of next() function instead of * the pointer interface version.
*/
MSGPACK_DEPRECATED("please use reference version instead") bool next(msgpack::object_handle* result);
/// Unpack one msgpack::object. /** * * @param result The object that contains unpacked data. * @param referenced If the unpacked object contains reference of the buffer, * then set as true, otherwise false. * * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete * and additional data is required, then return false. If data format is invalid, throw * msgpack::parse_error. * * See: * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
*/ bool next(msgpack::object_handle& result, bool& referenced);
/// Unpack one msgpack::object. /** * * @param result The object that contains unpacked data. * * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete * and additional data is required, then return false. If data format is invalid, throw * msgpack::parse_error. * * See: * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
*/ bool next(msgpack::object_handle& result);
/*! for backward compatibility */
msgpack::object const& data();
/*! for backward compatibility */
msgpack::zone* release_zone();
/*! for backward compatibility */ void reset_zone();
/*! for backward compatibility */ void reset();
public: /// Get parsed message size. /** * @return Parsed message size. * * This function is usable when non-MessagePack message follows after * MessagePack message.
*/
std::size_t parsed_size() const;
/// Get the address that is not parsed in the buffer. /** * @return Address of the buffer that is not parsed * * This function is usable when non-MessagePack message follows after * MessagePack message.
*/ char* nonparsed_buffer();
/// Get the size of the buffer that is not parsed. /** * @return Size of the buffer that is not parsed * * This function is usable when non-MessagePack message follows after * MessagePack message.
*/
std::size_t nonparsed_size() const;
/// Skip the specified size of non-parsed buffer. /** * @param size to skip * * Note that the `size' argument must be smaller than nonparsed_size(). * This function is usable when non-MessagePack message follows after * MessagePack message.
*/ void skip_nonparsed_buffer(std::size_t size);
/// Remove nonparsed buffer and reset the current position as a new start point. /** * This function is usable when non-MessagePack message follows after * MessagePack message.
*/ void remove_nonparsed_buffer();