🚧 started UBJSON implementation
This commit is contained in:
parent
15b6421d07
commit
c9938ea838
12 changed files with 2929 additions and 19 deletions
405
src/json.hpp
405
src/json.hpp
|
@ -4534,6 +4534,27 @@ class binary_reader
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief create a JSON value from UBJSON input
|
||||||
|
|
||||||
|
@param[in] strict whether to expect the input to be consumed completed
|
||||||
|
@return JSON value created from UBJSON input
|
||||||
|
|
||||||
|
@throw parse_error.110 if input ended unexpectedly or the end of file was
|
||||||
|
not reached when @a strict was set to true
|
||||||
|
@throw parse_error.112 if unsupported byte was read
|
||||||
|
*/
|
||||||
|
BasicJsonType parse_ubjson(const bool strict)
|
||||||
|
{
|
||||||
|
const auto res = parse_ubjson_internal();
|
||||||
|
if (strict)
|
||||||
|
{
|
||||||
|
get();
|
||||||
|
check_eof(true);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief determine system byte order
|
@brief determine system byte order
|
||||||
|
|
||||||
|
@ -5195,6 +5216,68 @@ class binary_reader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@param[in] get_char whether a new character should be retrieved from the
|
||||||
|
input (true, default) or whether the last read
|
||||||
|
character should be considered instead
|
||||||
|
*/
|
||||||
|
BasicJsonType parse_ubjson_internal(const bool get_char = true)
|
||||||
|
{
|
||||||
|
switch (get_char ? get() : current)
|
||||||
|
{
|
||||||
|
case std::char_traits<char>::eof(): // EOF
|
||||||
|
JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
|
||||||
|
|
||||||
|
case 'T': // true
|
||||||
|
return true;
|
||||||
|
case 'F': // false
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case 'Z': // null
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
case 'N': // no-op
|
||||||
|
return parse_ubjson_internal(); // read next byte
|
||||||
|
|
||||||
|
case 'U':
|
||||||
|
return get_number<uint8_t>();
|
||||||
|
case 'i':
|
||||||
|
return get_number<int8_t>();
|
||||||
|
case 'I':
|
||||||
|
return get_number<int16_t>();
|
||||||
|
case 'l':
|
||||||
|
return get_number<int32_t>();
|
||||||
|
case 'L':
|
||||||
|
return get_number<int64_t>();
|
||||||
|
case 'd':
|
||||||
|
return get_number<float>();
|
||||||
|
case 'D':
|
||||||
|
return get_number<double>();
|
||||||
|
|
||||||
|
case 'C': // char
|
||||||
|
{
|
||||||
|
get();
|
||||||
|
check_eof();
|
||||||
|
return std::string(1, static_cast<char>(current));
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'S': // string
|
||||||
|
return get_ubjson_string();
|
||||||
|
|
||||||
|
case '[': // array
|
||||||
|
return get_ubjson_array();
|
||||||
|
|
||||||
|
case '{': // object
|
||||||
|
return get_ubjson_object();
|
||||||
|
|
||||||
|
default: // anything else
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
|
||||||
|
JSON_THROW(parse_error::create(112, chars_read,
|
||||||
|
"error reading UBJSON; last byte: 0x" + ss.str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief get next character from the input
|
@brief get next character from the input
|
||||||
|
|
||||||
|
@ -5495,6 +5578,80 @@ class binary_reader
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief reads a UBJSON string
|
||||||
|
|
||||||
|
This function first reads starting bytes to determine the expected
|
||||||
|
string length and then copies this number of bytes into a string.
|
||||||
|
|
||||||
|
@param[in] get_char whether a new character should be retrieved from the
|
||||||
|
input (true, default) or whether the last read
|
||||||
|
character should be considered instead
|
||||||
|
|
||||||
|
@return string
|
||||||
|
|
||||||
|
@throw parse_error.110 if input ended
|
||||||
|
@throw parse_error.113 if an unexpected byte is read
|
||||||
|
*/
|
||||||
|
std::string get_ubjson_string(const bool get_char = true)
|
||||||
|
{
|
||||||
|
if (get_char)
|
||||||
|
{
|
||||||
|
get();
|
||||||
|
}
|
||||||
|
|
||||||
|
check_eof();
|
||||||
|
|
||||||
|
switch (current)
|
||||||
|
{
|
||||||
|
case 'U':
|
||||||
|
return get_string(get_number<uint8_t>());
|
||||||
|
case 'i':
|
||||||
|
return get_string(get_number<int8_t>());
|
||||||
|
case 'I':
|
||||||
|
return get_string(get_number<int16_t>());
|
||||||
|
case 'l':
|
||||||
|
return get_string(get_number<int32_t>());
|
||||||
|
case 'L':
|
||||||
|
return get_string(get_number<int64_t>());
|
||||||
|
default:
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::setw(2) << std::uppercase << std::setfill('0') << std::hex << current;
|
||||||
|
JSON_THROW(parse_error::create(113, chars_read,
|
||||||
|
"expected a UBJSON string; last byte: 0x" + ss.str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicJsonType get_ubjson_array()
|
||||||
|
{
|
||||||
|
BasicJsonType result = value_t::array;
|
||||||
|
|
||||||
|
while (get() != ']')
|
||||||
|
{
|
||||||
|
// skip no-op
|
||||||
|
if (current == 'N')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.push_back(parse_ubjson_internal(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicJsonType get_ubjson_object()
|
||||||
|
{
|
||||||
|
BasicJsonType result = value_t::object;
|
||||||
|
|
||||||
|
while (get() != '}')
|
||||||
|
{
|
||||||
|
auto key = get_ubjson_string(false);
|
||||||
|
result[std::move(key)] = parse_ubjson_internal();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief check if input ended
|
@brief check if input ended
|
||||||
@throw parse_error.110 if input ended
|
@throw parse_error.110 if input ended
|
||||||
|
@ -5678,23 +5835,23 @@ class binary_writer
|
||||||
{
|
{
|
||||||
write_number(static_cast<uint8_t>(0x60 + N));
|
write_number(static_cast<uint8_t>(0x60 + N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFF)
|
else if (N <= (std::numeric_limits<uint8_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x78));
|
oa->write_character(static_cast<CharType>(0x78));
|
||||||
write_number(static_cast<uint8_t>(N));
|
write_number(static_cast<uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFF)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x79));
|
oa->write_character(static_cast<CharType>(0x79));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x7A));
|
oa->write_character(static_cast<CharType>(0x7A));
|
||||||
write_number(static_cast<uint32_t>(N));
|
write_number(static_cast<uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= 0xFFFFFFFFFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint64_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x7B));
|
oa->write_character(static_cast<CharType>(0x7B));
|
||||||
write_number(static_cast<uint64_t>(N));
|
write_number(static_cast<uint64_t>(N));
|
||||||
|
@ -5716,23 +5873,23 @@ class binary_writer
|
||||||
{
|
{
|
||||||
write_number(static_cast<uint8_t>(0x80 + N));
|
write_number(static_cast<uint8_t>(0x80 + N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFF)
|
else if (N <= (std::numeric_limits<uint8_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x98));
|
oa->write_character(static_cast<CharType>(0x98));
|
||||||
write_number(static_cast<uint8_t>(N));
|
write_number(static_cast<uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFF)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x99));
|
oa->write_character(static_cast<CharType>(0x99));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x9A));
|
oa->write_character(static_cast<CharType>(0x9A));
|
||||||
write_number(static_cast<uint32_t>(N));
|
write_number(static_cast<uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= 0xFFFFFFFFFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint64_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0x9B));
|
oa->write_character(static_cast<CharType>(0x9B));
|
||||||
write_number(static_cast<uint64_t>(N));
|
write_number(static_cast<uint64_t>(N));
|
||||||
|
@ -5755,23 +5912,23 @@ class binary_writer
|
||||||
{
|
{
|
||||||
write_number(static_cast<uint8_t>(0xA0 + N));
|
write_number(static_cast<uint8_t>(0xA0 + N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFF)
|
else if (N <= (std::numeric_limits<uint8_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0xB8));
|
oa->write_character(static_cast<CharType>(0xB8));
|
||||||
write_number(static_cast<uint8_t>(N));
|
write_number(static_cast<uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFF)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0xB9));
|
oa->write_character(static_cast<CharType>(0xB9));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0xBA));
|
oa->write_character(static_cast<CharType>(0xBA));
|
||||||
write_number(static_cast<uint32_t>(N));
|
write_number(static_cast<uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= 0xFFFFFFFFFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
oa->write_character(static_cast<CharType>(0xBB));
|
oa->write_character(static_cast<CharType>(0xBB));
|
||||||
write_number(static_cast<uint64_t>(N));
|
write_number(static_cast<uint64_t>(N));
|
||||||
|
@ -5939,19 +6096,19 @@ class binary_writer
|
||||||
// fixstr
|
// fixstr
|
||||||
write_number(static_cast<uint8_t>(0xA0 | N));
|
write_number(static_cast<uint8_t>(0xA0 | N));
|
||||||
}
|
}
|
||||||
else if (N <= 255)
|
else if (N <= (std::numeric_limits<uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// str 8
|
// str 8
|
||||||
oa->write_character(static_cast<CharType>(0xD9));
|
oa->write_character(static_cast<CharType>(0xD9));
|
||||||
write_number(static_cast<uint8_t>(N));
|
write_number(static_cast<uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 65535)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// str 16
|
// str 16
|
||||||
oa->write_character(static_cast<CharType>(0xDA));
|
oa->write_character(static_cast<CharType>(0xDA));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 4294967295)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// str 32
|
// str 32
|
||||||
oa->write_character(static_cast<CharType>(0xDB));
|
oa->write_character(static_cast<CharType>(0xDB));
|
||||||
|
@ -5974,13 +6131,13 @@ class binary_writer
|
||||||
// fixarray
|
// fixarray
|
||||||
write_number(static_cast<uint8_t>(0x90 | N));
|
write_number(static_cast<uint8_t>(0x90 | N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFF)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// array 16
|
// array 16
|
||||||
oa->write_character(static_cast<CharType>(0xDC));
|
oa->write_character(static_cast<CharType>(0xDC));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 0xFFFFFFFF)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// array 32
|
// array 32
|
||||||
oa->write_character(static_cast<CharType>(0xDD));
|
oa->write_character(static_cast<CharType>(0xDD));
|
||||||
|
@ -6004,13 +6161,13 @@ class binary_writer
|
||||||
// fixmap
|
// fixmap
|
||||||
write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
|
write_number(static_cast<uint8_t>(0x80 | (N & 0xF)));
|
||||||
}
|
}
|
||||||
else if (N <= 65535)
|
else if (N <= (std::numeric_limits<uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// map 16
|
// map 16
|
||||||
oa->write_character(static_cast<CharType>(0xDE));
|
oa->write_character(static_cast<CharType>(0xDE));
|
||||||
write_number(static_cast<uint16_t>(N));
|
write_number(static_cast<uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= 4294967295)
|
else if (N <= (std::numeric_limits<uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// map 32
|
// map 32
|
||||||
oa->write_character(static_cast<CharType>(0xDF));
|
oa->write_character(static_cast<CharType>(0xDF));
|
||||||
|
@ -6031,6 +6188,110 @@ class binary_writer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief[in] j JSON value to serialize
|
||||||
|
*/
|
||||||
|
void write_ubjson(const BasicJsonType& j, const bool use_count = false)
|
||||||
|
{
|
||||||
|
switch (j.type())
|
||||||
|
{
|
||||||
|
case value_t::null:
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('Z'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::boolean:
|
||||||
|
{
|
||||||
|
oa->write_character(j.m_value.boolean
|
||||||
|
? static_cast<CharType>('T')
|
||||||
|
: static_cast<CharType>('F'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::number_integer:
|
||||||
|
{
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.number_integer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::number_unsigned:
|
||||||
|
{
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.number_unsigned);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::number_float:
|
||||||
|
{
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.number_float);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::string:
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('S'));
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.string->size());
|
||||||
|
oa->write_characters(
|
||||||
|
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||||
|
j.m_value.string->size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::array:
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('['));
|
||||||
|
|
||||||
|
if (use_count)
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('#'));
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.array->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& el : *j.m_value.array)
|
||||||
|
{
|
||||||
|
write_ubjson(el, use_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not use_count)
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>(']'));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case value_t::object:
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('{'));
|
||||||
|
|
||||||
|
if (use_count)
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('#'));
|
||||||
|
write_number_with_ubjson_prefix(j.m_value.object->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& el : *j.m_value.object)
|
||||||
|
{
|
||||||
|
write_number_with_ubjson_prefix(el.first.size());
|
||||||
|
oa->write_characters(
|
||||||
|
reinterpret_cast<const CharType*>(el.first.c_str()),
|
||||||
|
el.first.size());
|
||||||
|
write_ubjson(el.second, use_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not use_count)
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('}'));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
@brief write a number to output input
|
@brief write a number to output input
|
||||||
|
@ -6058,6 +6319,82 @@ class binary_writer
|
||||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
oa->write_characters(vec.data(), sizeof(NumberType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename NumberType>
|
||||||
|
void write_number_with_ubjson_prefix(const NumberType n)
|
||||||
|
{
|
||||||
|
if (std::is_floating_point<NumberType>::value)
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('D')); // float64
|
||||||
|
write_number(n);
|
||||||
|
}
|
||||||
|
else if (std::is_unsigned<NumberType>::value)
|
||||||
|
{
|
||||||
|
if (n <= (std::numeric_limits<int8_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('i')); // uint8
|
||||||
|
write_number(static_cast<uint8_t>(n));
|
||||||
|
}
|
||||||
|
else if (n <= (std::numeric_limits<uint8_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('U')); // uint8
|
||||||
|
write_number(static_cast<uint8_t>(n));
|
||||||
|
}
|
||||||
|
else if (n <= (std::numeric_limits<int16_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('I')); // int16
|
||||||
|
write_number(static_cast<int16_t>(n));
|
||||||
|
}
|
||||||
|
else if (n <= (std::numeric_limits<int32_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('l')); // int32
|
||||||
|
write_number(static_cast<int32_t>(n));
|
||||||
|
}
|
||||||
|
else if (n <= (std::numeric_limits<int64_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('L')); // int64
|
||||||
|
write_number(static_cast<int64_t>(n));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: replace by exception
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((std::numeric_limits<int8_t>::min)() <= n and n <= (std::numeric_limits<int8_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('i')); // int8
|
||||||
|
write_number(static_cast<int8_t>(n));
|
||||||
|
}
|
||||||
|
else if ((std::numeric_limits<uint8_t>::min)() <= n and n <= (std::numeric_limits<uint8_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('U')); // uint8
|
||||||
|
write_number(static_cast<uint8_t>(n));
|
||||||
|
}
|
||||||
|
else if ((std::numeric_limits<int16_t>::min)() <= n and n <= (std::numeric_limits<int16_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('I')); // int16
|
||||||
|
write_number(static_cast<int16_t>(n));
|
||||||
|
}
|
||||||
|
else if (-(std::numeric_limits<int32_t>::min)() <= n and n <= (std::numeric_limits<int32_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('l')); // int32
|
||||||
|
write_number(static_cast<int32_t>(n));
|
||||||
|
}
|
||||||
|
else if ((std::numeric_limits<int64_t>::min)() <= n and n <= (std::numeric_limits<int64_t>::max)())
|
||||||
|
{
|
||||||
|
oa->write_character(static_cast<CharType>('L')); // int64
|
||||||
|
write_number(static_cast<int64_t>(n));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: replace by exception
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// whether we can assume little endianess
|
/// whether we can assume little endianess
|
||||||
const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
|
const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
|
||||||
|
@ -13511,6 +13848,23 @@ class basic_json
|
||||||
binary_writer<char>(o).write_msgpack(j);
|
binary_writer<char>(o).write_msgpack(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<uint8_t> to_ubjson(const basic_json& j)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> result;
|
||||||
|
to_ubjson(j, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o)
|
||||||
|
{
|
||||||
|
binary_writer<uint8_t>(o).write_ubjson(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void to_ubjson(const basic_json& j, detail::output_adapter<char> o)
|
||||||
|
{
|
||||||
|
binary_writer<char>(o).write_ubjson(j);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a JSON value from an input in CBOR format
|
@brief create a JSON value from an input in CBOR format
|
||||||
|
|
||||||
|
@ -13705,6 +14059,19 @@ class basic_json
|
||||||
return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
|
return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static basic_json from_ubjson(detail::input_adapter i,
|
||||||
|
const bool strict = true)
|
||||||
|
{
|
||||||
|
return binary_reader(i).parse_ubjson(strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename A1, typename A2,
|
||||||
|
detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
|
||||||
|
static basic_json from_ubjson(A1 && a1, A2 && a2, const bool strict = true)
|
||||||
|
{
|
||||||
|
return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_ubjson(strict);
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
|
@ -39,6 +39,7 @@ SOURCES = src/unit.cpp \
|
||||||
src/unit-regression.cpp \
|
src/unit-regression.cpp \
|
||||||
src/unit-serialization.cpp \
|
src/unit-serialization.cpp \
|
||||||
src/unit-testsuites.cpp \
|
src/unit-testsuites.cpp \
|
||||||
|
src/unit-ubjson.cpp \
|
||||||
src/unit-unicode.cpp
|
src/unit-unicode.cpp
|
||||||
|
|
||||||
OBJECTS = $(SOURCES:.cpp=.o)
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
275
test/data/universal-binary-json-java/CouchDB4k.formatted.json
Normal file
275
test/data/universal-binary-json-java/CouchDB4k.formatted.json
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
{
|
||||||
|
"data3":"ColreUHAtuYoUOx1N4ZloouQt2o6ugnUT6eYtS10gu7niM8i0vEiNufpk1RlMQXaHXlIwQBDsMFDFUQcFeg2vW5eD259Xm",
|
||||||
|
"data4":"zCxriJhL726WNNTdJJzurgSA8vKT6rHA0cFCb9koZcLUMXg4rmoXVPqIHWYaCV0ovl2t6xm7I1Hm36jXpLlXEb8fRfbwBeTW2V0OAsVqYH8eAT",
|
||||||
|
"data0":"9EVqHm5ARqcEB5jq2D14U2bCJPyBY0JWDr1Tjh8gTB0sWUNjqYiWDxFzlx6S",
|
||||||
|
"data7":"Bi1ujcgEvfADfBeyZudE7nwxc3Ik8qpYjsJIfKmwOMEbV2L3Bi0x2tcRpGuf4fiyvIbypDvJN1PPdQtfQW1Gv6zccXHwwZwKzUq6",
|
||||||
|
"data5":{
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
],
|
||||||
|
"float1":76.572,
|
||||||
|
"float2":83.5299,
|
||||||
|
"nested1":{
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
],
|
||||||
|
"floats":[
|
||||||
|
43121609.5543,
|
||||||
|
99454976.3019,
|
||||||
|
32945584.756,
|
||||||
|
18122905.9212,
|
||||||
|
45893183.44,
|
||||||
|
63052200.6225,
|
||||||
|
69032152.6897,
|
||||||
|
3748217.6946,
|
||||||
|
75449850.474,
|
||||||
|
37111527.415,
|
||||||
|
84852536.859,
|
||||||
|
32906366.487,
|
||||||
|
27027600.417,
|
||||||
|
63874310.5614,
|
||||||
|
39440408.51,
|
||||||
|
97176857.1716,
|
||||||
|
97438252.1171,
|
||||||
|
49728043.5056,
|
||||||
|
40818570.245,
|
||||||
|
41415831.8949,
|
||||||
|
24796297.4251,
|
||||||
|
2819085.3449,
|
||||||
|
84263963.4848,
|
||||||
|
74503228.6878,
|
||||||
|
67925677.403,
|
||||||
|
4758851.9417,
|
||||||
|
75227407.9214,
|
||||||
|
76946667.8403,
|
||||||
|
72518275.9469,
|
||||||
|
94167085.9588,
|
||||||
|
75883067.8321,
|
||||||
|
27389831.6101,
|
||||||
|
57987075.5053,
|
||||||
|
1298995.2674,
|
||||||
|
14590614.6939,
|
||||||
|
45292214.2242,
|
||||||
|
3332166.364,
|
||||||
|
53784167.729,
|
||||||
|
25193846.1867,
|
||||||
|
81456965.477,
|
||||||
|
68532032.39,
|
||||||
|
73820009.7952,
|
||||||
|
57736110.5717,
|
||||||
|
37304166.7363,
|
||||||
|
20054244.864,
|
||||||
|
29746392.7397,
|
||||||
|
86467624.6,
|
||||||
|
45192685.8793,
|
||||||
|
44008816.5186,
|
||||||
|
1861872.8736,
|
||||||
|
14595859.467,
|
||||||
|
87795257.6703,
|
||||||
|
57768720.8303,
|
||||||
|
18290154.3126,
|
||||||
|
45893183.44,
|
||||||
|
63052200.6225,
|
||||||
|
69032152.6897,
|
||||||
|
3748217.6946,
|
||||||
|
75449850.474,
|
||||||
|
37111527.415,
|
||||||
|
84852536.859,
|
||||||
|
32906366.487,
|
||||||
|
27027600.417,
|
||||||
|
63874310.5614,
|
||||||
|
39440408.51,
|
||||||
|
97176857.1716,
|
||||||
|
97438252.1171,
|
||||||
|
49728043.5056,
|
||||||
|
40818570.245,
|
||||||
|
41415831.8949,
|
||||||
|
24796297.4251,
|
||||||
|
2819085.3449,
|
||||||
|
84263963.4848,
|
||||||
|
74503228.6878,
|
||||||
|
67925677.403,
|
||||||
|
4758851.9417,
|
||||||
|
75227407.9214,
|
||||||
|
76946667.8403,
|
||||||
|
72518275.9469,
|
||||||
|
94167085.9588,
|
||||||
|
75883067.8321,
|
||||||
|
27389831.6101,
|
||||||
|
57987075.5053,
|
||||||
|
1298995.2674,
|
||||||
|
80858801.2712,
|
||||||
|
98262252.4656,
|
||||||
|
51612877.944,
|
||||||
|
33397812.7835,
|
||||||
|
36089655.3049,
|
||||||
|
50164685.8153,
|
||||||
|
16852105.5192,
|
||||||
|
61171929.752,
|
||||||
|
86376339.7175,
|
||||||
|
73009014.5521,
|
||||||
|
7397302.331,
|
||||||
|
34345128.9589,
|
||||||
|
98343269.4418,
|
||||||
|
95039116.9058,
|
||||||
|
44833102.5752,
|
||||||
|
51052997.8873,
|
||||||
|
22719195.6783,
|
||||||
|
64883244.8699
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nested2":{
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
],
|
||||||
|
"float1":76.572,
|
||||||
|
"float2":83.5299
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strings":[
|
||||||
|
"edx5XzRkPVeEW2MBQzQMcUSuMI4FntjhlJ9VGhQaBHKPEazAaT",
|
||||||
|
"2fQUbzRUax4A",
|
||||||
|
"jURcBZ0vrJcmf2roZUMzZJQoTsKZDIdj7KhO7itskKvM80jBU9",
|
||||||
|
"8jKLmo3N2zYdKyTyfTczfr2x6bPaarorlnTNJ7r8lIkiZyBvrP",
|
||||||
|
"jbUeAVOdBSPzYmYhH0sabUHUH39O5e",
|
||||||
|
"I8yAQKZsyZhMfpzWjArQU9pQ6PfU6b14q2eWvQjtCUdgAUxFjg",
|
||||||
|
"97N8ZmGcxRZO4ZabzRRcY4KVHqxJwQ8qY",
|
||||||
|
"0DtY1aWXmUfJENt9rYW9",
|
||||||
|
"DtpBUEppPwMnWexi8eIIxlXRO3GUpPgeNFG9ONpWJYvk8xBkVj",
|
||||||
|
"YsX8V2xOrTw6LhNIMMhO4F4VXFyXUXFr66L3sTkLWgFA9NZuBV",
|
||||||
|
"fKYYthv8iFvaYoFoYZyB",
|
||||||
|
"zGuLsPXoJqMbO4PcePteZfDMYFXdWtvNF8WvaplXypsd6"
|
||||||
|
],
|
||||||
|
"data1":"9EVqHm5ARqcEB5jq21v2g0jVcG9CXB0Abk7uAF4NHYyTzeF3TnHhpZBECD14U2bCJPyBY0JWDr1Tjh8gTB0sWUNjqYiWDxFzlx6S",
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
],
|
||||||
|
"more_nested":{
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
],
|
||||||
|
"float1":76.572,
|
||||||
|
"float2":83.5299,
|
||||||
|
"nested1":{
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
275045,
|
||||||
|
703447,
|
||||||
|
50156,
|
||||||
|
685803,
|
||||||
|
147958,
|
||||||
|
941747,
|
||||||
|
905651,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nested2":{
|
||||||
|
"strings":[
|
||||||
|
"2fQUbzRUax4A",
|
||||||
|
"jURcBZ0vrJcmf2roZUMzZJQoTsKZDIdj7KhO7itskKvM80jBU9",
|
||||||
|
"8jKLmo3N2zYdKyTyfTczfr2x6bPaarorlnTNJ7r8lIkiZyBvrP",
|
||||||
|
"jbUeAVOdBSPzYmYhH0sabUHUH39O5e",
|
||||||
|
"I8yAQKZsyZhMfpzWjArQU9pQ6PfU6b14q2eWvQjtCUdgAUxFjg",
|
||||||
|
"97N8ZmGcxRZO4ZabzRRcY4KVHqxJwQ8qY",
|
||||||
|
"0DtY1aWXmUfJENt9rYW9",
|
||||||
|
"DtpBUEppPwMnWexi8eIIxlXRO3GUpPgeNFG9ONpWJYvk8xBkVj",
|
||||||
|
"YsX8V2xOrTw6LhNIMMhO4F4VXFyXUXFr66L3sTkLWgFA9NZuBV",
|
||||||
|
"fKYYthv8iFvaYoFoYZyB",
|
||||||
|
"zGuLsPXoJqMbO4PcePteZfDMYFXdWtvNF8WvaplXypsd6"
|
||||||
|
],
|
||||||
|
"integers":[
|
||||||
|
756509,
|
||||||
|
116117,
|
||||||
|
776378,
|
||||||
|
57367,
|
||||||
|
530248,
|
||||||
|
312888,
|
||||||
|
740951,
|
||||||
|
988947,
|
||||||
|
450154
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
test/data/universal-binary-json-java/CouchDB4k.ubj
Normal file
BIN
test/data/universal-binary-json-java/CouchDB4k.ubj
Normal file
Binary file not shown.
202
test/data/universal-binary-json-java/LICENSE
Normal file
202
test/data/universal-binary-json-java/LICENSE
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"Media":{
|
||||||
|
"uri":"http://javaone.com/keynote.mpg",
|
||||||
|
"title":"Javaone Keynote",
|
||||||
|
"width":640,
|
||||||
|
"height":480,
|
||||||
|
"format":"video/mpg4",
|
||||||
|
"duration":18000000,
|
||||||
|
"size":58982400,
|
||||||
|
"bitrate":262144,
|
||||||
|
"persons":[
|
||||||
|
"Bill Gates",
|
||||||
|
"Steve Jobs"
|
||||||
|
],
|
||||||
|
"player":"JAVA",
|
||||||
|
"copyright":null
|
||||||
|
},
|
||||||
|
"Images":[
|
||||||
|
{
|
||||||
|
"uri":"http://javaone.com/keynote_large.jpg",
|
||||||
|
"title":"Javaone Keynote",
|
||||||
|
"width":1024,
|
||||||
|
"height":768,
|
||||||
|
"size":"LARGE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri":"http://javaone.com/keynote_small.jpg",
|
||||||
|
"title":"Javaone Keynote",
|
||||||
|
"width":320,
|
||||||
|
"height":240,
|
||||||
|
"size":"SMALL"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
test/data/universal-binary-json-java/MediaContent.ubj
Normal file
BIN
test/data/universal-binary-json-java/MediaContent.ubj
Normal file
Binary file not shown.
357
test/data/universal-binary-json-java/README
Normal file
357
test/data/universal-binary-json-java/README
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
Universal Binary JSON Java Library
|
||||||
|
http://ubjson.org
|
||||||
|
|
||||||
|
|
||||||
|
About this project...
|
||||||
|
---------------------
|
||||||
|
This code base is actively under development and implements the latest
|
||||||
|
specification of Universal Binary JSON (Draft 8).
|
||||||
|
|
||||||
|
I/O is handled through the following core classes:
|
||||||
|
|
||||||
|
* UBJOutputStream
|
||||||
|
* UBJInputStream
|
||||||
|
* UBJInputStreamParser
|
||||||
|
|
||||||
|
Additionally, if you are working with Java's NIO and need byte[]-based
|
||||||
|
results, you can wrap any of the above I/O classes around one of the highly
|
||||||
|
optimized custom byte[]-stream impls:
|
||||||
|
|
||||||
|
* ByteArrayInputStream (optimized for reuse, not from JDK)
|
||||||
|
* ByteArrayOutputStream (optimized for reuse, not from JDK)
|
||||||
|
|
||||||
|
If you are working with NIO and want maximum performance by using (and reusing)
|
||||||
|
direct ByteBuffers along with the UBJSON stream impls, take a look at the:
|
||||||
|
|
||||||
|
* ByteBufferInputStream
|
||||||
|
* ByteBufferOutputStream
|
||||||
|
|
||||||
|
classes. You can wrap any ByteBuffer source or destination with this stream type,
|
||||||
|
then wrap that stream type with a UBJSON stream impl and utilize the full
|
||||||
|
potential of Java's NIO with Universal Binary JSON without giving yourself an
|
||||||
|
ulcer.
|
||||||
|
|
||||||
|
This allows you to re-use the streams over and over again in a pool of reusable
|
||||||
|
streams for high-performance I/O with no object creation and garbage collection
|
||||||
|
overhead; a perfect match for high frequency NIO-based communication.
|
||||||
|
|
||||||
|
All of the core I/O classes have been stable for a while, with tweaks to make the
|
||||||
|
performance tighter and the error messages more informative over the last few
|
||||||
|
months.
|
||||||
|
|
||||||
|
More Java-convenient reflection-based I/O classes are available in the
|
||||||
|
org.ubjson.io.reflect package, but they are under active development.
|
||||||
|
|
||||||
|
There are other efforts (like utilities) in other sub portions of the source
|
||||||
|
tree. This project intends to eventually contain a multitude of UBJSON
|
||||||
|
abstraction layers, I/O methods and utilities.
|
||||||
|
|
||||||
|
|
||||||
|
Changelog
|
||||||
|
---------
|
||||||
|
02-10-12
|
||||||
|
* Added ByteBuffer input and output stream impls as compliments to the
|
||||||
|
re-usable byte[] stream impls.
|
||||||
|
|
||||||
|
Provides a fast translation layer between standard Java stream-IO and the
|
||||||
|
new Buffer-based I/O in NIO (including transparent support for using
|
||||||
|
ultra-fast direct ByteBuffers).
|
||||||
|
|
||||||
|
* Optimized some of the read/write methods by removing unnecessary bounds
|
||||||
|
checks that are done by subsequent Input or Output stream impls themselves.
|
||||||
|
|
||||||
|
02-09-12
|
||||||
|
* Fixed bug with readHugeAsBigInteger returning an invalid value and not
|
||||||
|
treating the underlying bytes as a string-encoded value.
|
||||||
|
|
||||||
|
* Removed implicit buffer.flip() at the end of StreamDecoder; there is no
|
||||||
|
way to know what the caller had planned for the buffer before reading all
|
||||||
|
the data back out. Also the flip was in the wrong place and in the case of
|
||||||
|
an empty decode request (length=0) the flip would not have been performed,
|
||||||
|
providing the caller with a "full" buffer of nothing.
|
||||||
|
|
||||||
|
* Rewrote all readHugeXXX method impls; now huge's can be read in as a
|
||||||
|
simple Number (BigInteger or BigDecimal) as well as raw bytes and even
|
||||||
|
decoded chars. Additionally the methods can even accept and use existing
|
||||||
|
buffers to write into to allow for tighter optimizations.
|
||||||
|
|
||||||
|
* Rewrote all readStringXXX methods using the same optimizations and
|
||||||
|
flexibility that readHuge methods now use.
|
||||||
|
|
||||||
|
02-07-12
|
||||||
|
More Memory and CPU optimizations across all the I/O impls.
|
||||||
|
|
||||||
|
* StreamDecoder was rewritten to no longer create a ByteBuffer on every
|
||||||
|
invocation and instead re-use the same one to decode from on every single call.
|
||||||
|
|
||||||
|
* StreamDecoder now requires the call to pass in a CharBuffer instance to hold
|
||||||
|
the result of the decode operation. This avoids the creation of a CharBuffer
|
||||||
|
and allows for large-scale optimization by re-using existing buffers between
|
||||||
|
calls.
|
||||||
|
|
||||||
|
* StreamEncoder was rewritten to no longer create a ByteBuffer on every
|
||||||
|
invocation either and now re-uses the same single instance over and over
|
||||||
|
again.
|
||||||
|
|
||||||
|
* UBJOutputStream writeHuge and writeString series of methods were all
|
||||||
|
rewritten to accept a CharBuffer in the rawest form (no longer char[]) to stop
|
||||||
|
hiding the fact that the underlying encode operation required one.
|
||||||
|
|
||||||
|
This gives the caller an opportunity to cache and re-use CharBuffers over
|
||||||
|
and over again if they can; otherwise this just pushes the CharBuffer.wrap()
|
||||||
|
call up to the caller instead of hiding it secretly in the method impl under
|
||||||
|
the guise of accepting a raw char[] (that it couldn't use directly).
|
||||||
|
|
||||||
|
For callers that can re-use buffers, this will lead to big performance gains
|
||||||
|
now that were previously impossible.
|
||||||
|
|
||||||
|
* UBJInputStream added readHuge and readString methods that accept an existing
|
||||||
|
CharBuffer argument to make use of the optimizations made in the Stream encoder
|
||||||
|
and decoder impls.
|
||||||
|
|
||||||
|
01-15-12
|
||||||
|
Huge performance boost for deserialization!
|
||||||
|
|
||||||
|
StreamDecoder previously used separate read and write buffers for decoding
|
||||||
|
bytes to chars including the resulting char[] that was returned to the caller.
|
||||||
|
This design required at least 1 full array copy before returning a result in
|
||||||
|
the best case and 2x full array copies before returning the result in the
|
||||||
|
worst case.
|
||||||
|
|
||||||
|
The rewrite removed the need for a write buffer entire as well as ALL array
|
||||||
|
copies; in the best OR worse case they never occur anymore.
|
||||||
|
|
||||||
|
Raw performance boost of roughly 25% in all UBJ I/O classes as a result.
|
||||||
|
|
||||||
|
12-01-11 through 01-24-12
|
||||||
|
A large amount of work has continued on the core I/O classes (stream impls)
|
||||||
|
to help make them not only faster and more robust, but also more helpful.
|
||||||
|
When errors are encountered in the streams, they are reported along with the
|
||||||
|
stream positions. This is critical for debugging problems with corrupt
|
||||||
|
formats.
|
||||||
|
|
||||||
|
Also provided ByteArray I/O stream classes that have the potential to provide
|
||||||
|
HUGE performance boosts for high frequency systems.
|
||||||
|
|
||||||
|
Both these classes (ByteArrayInputStream and ByteArrayOutputStream) are
|
||||||
|
reusable and when wrapped by a UBJInputStream or UBJOutputStream, the top
|
||||||
|
level UBJ streams implicitly become reusable as well.
|
||||||
|
|
||||||
|
Reusing the streams not only saves on object creation/GC cleanup but also
|
||||||
|
allows the caller to re-use the temporary byte[] used to translate to and
|
||||||
|
from the UBJ format, avoiding object churn entirely!
|
||||||
|
|
||||||
|
This optimized design was chosen to be intentionally performant when combined
|
||||||
|
with NIO implementations as the ByteBuffer's can be used to wrap() existing
|
||||||
|
outbound buffers (avoiding the most expensive part of a buffer) or use
|
||||||
|
array() to get access to the underlying buffer that needs to be written to
|
||||||
|
the stream.
|
||||||
|
|
||||||
|
In the case of direct ByteBuffers, there is no additional overhead added
|
||||||
|
because the calls to get or put are required anyway to pull or push the
|
||||||
|
values from the native memory location.
|
||||||
|
|
||||||
|
This approach allows the fastest implementation of Universal Binary JSON
|
||||||
|
I/O possible in the JVM whether you are using the standard IO (stream)
|
||||||
|
classes or the NIO (ByteBuffer) classes in the JDK.
|
||||||
|
|
||||||
|
Some ancillary work on UBJ-based command line utilities (viewers, converters,
|
||||||
|
etc.) has begun as well.
|
||||||
|
|
||||||
|
11-28-11
|
||||||
|
* Fixed UBJInputStreamParser implementation; nextType correctly implements
|
||||||
|
logic to skip existing element (if called back to back) as well as validate
|
||||||
|
the marker type it encounters before returning it to the caller.
|
||||||
|
|
||||||
|
* Modified IObjectReader contract; a Parser implementation is required to
|
||||||
|
make traversing the UBJ stream possible without knowing what type of element
|
||||||
|
is next.
|
||||||
|
|
||||||
|
11-27-11
|
||||||
|
* Streamlined ByteArrayOutputStream implementation to ensure the capacity
|
||||||
|
of the underlying byte[] is never grown unless absolutely necessary.
|
||||||
|
|
||||||
|
* Rewrote class Javadoc for ByteArrayOutputStream to include a code snippet
|
||||||
|
on how to use it.
|
||||||
|
|
||||||
|
11-26-11
|
||||||
|
* Fixed major bug in how 16, 32 and 64-bit integers are re-assembled when
|
||||||
|
read back from binary representations.
|
||||||
|
|
||||||
|
* Added a numeric test to specifically catch this error if it ever pops up
|
||||||
|
again.
|
||||||
|
|
||||||
|
* Optimized reading and writing of numeric values in Input and Output
|
||||||
|
stream implementations.
|
||||||
|
|
||||||
|
* Optimized ObjectWriter implementation by streamlining the numeric read/write
|
||||||
|
logic and removing the sub-optimal force-compression of on-disk storage.
|
||||||
|
|
||||||
|
* Fixed ObjectWriter to match exactly with the output written by
|
||||||
|
UBJOutputStream.
|
||||||
|
|
||||||
|
* Normalized all testing between I/O classes so they use the same classes
|
||||||
|
to ensure parity.
|
||||||
|
|
||||||
|
11-10-11
|
||||||
|
* DRAFT 8 Spec Support Added.
|
||||||
|
|
||||||
|
* Added support for the END marker (readEnd) to the InputStreams which is
|
||||||
|
required for proper unbounded-container support.
|
||||||
|
|
||||||
|
* Added support for the END marker (writeEnd) to UBJOutputStream.
|
||||||
|
|
||||||
|
UBJInputStreamParser must be used for properly support unbounded-containers
|
||||||
|
because you never know when the 'E' will be encountered marking the end;
|
||||||
|
so the caller needs to pay attention to the type marker that nextType()
|
||||||
|
returns and respond accordingly.
|
||||||
|
|
||||||
|
* Added readHugeAsBytes to InputStream implementations, allowing the bytes
|
||||||
|
used to represent a HUGE to be read in their raw form with no decoding.
|
||||||
|
|
||||||
|
This can save on processing as BigInteger and BigDecimal do their own decoding
|
||||||
|
of byte[] directly.
|
||||||
|
|
||||||
|
* Added readHugeAsChars to InputStream implementations, allowing a HUGE
|
||||||
|
value to be read in as a raw char[] without trying to decode it to a
|
||||||
|
BigInteger or BigDecimal.
|
||||||
|
|
||||||
|
* Added writeHuge(char[]) to support writing out HUGE values directly from
|
||||||
|
their raw char[] form without trying to decode from a BigInteger or
|
||||||
|
BigDecimal.
|
||||||
|
|
||||||
|
* readArrayLength and readObjectLenght were modified to return -1 when an
|
||||||
|
unbounded container length is encountered (255).
|
||||||
|
|
||||||
|
* Fixed UBJInputStreamParser.nextType to correctly skip past any NOOP
|
||||||
|
markers found in the underlying stream before returning a valid next type.
|
||||||
|
|
||||||
|
* Normalized all reading of "next byte" to the singular
|
||||||
|
UBJInputStream.nextMarker method -- correctly skips over NOOP until end of
|
||||||
|
stream OR until the next valid marker byte, then returns it.
|
||||||
|
|
||||||
|
* Modified readNull behavior to have no return type. It is already designed
|
||||||
|
to throw an exception when 'NULL' isn't found, no need for the additional
|
||||||
|
return type.
|
||||||
|
|
||||||
|
* Began work on a simple abstract representation of the UBJ data types as
|
||||||
|
objects that can be assembled into maps and lists and written/read easily
|
||||||
|
using the IO package.
|
||||||
|
|
||||||
|
This is intended to be a higher level of abstraction than the IO streams,
|
||||||
|
but lower level (and faster) than the reflection-based work that inspects
|
||||||
|
user-provided classes.
|
||||||
|
|
||||||
|
* Refactored StreamDecoder and StreamEncoder into the core IO package,
|
||||||
|
because they are part of core IO.
|
||||||
|
|
||||||
|
* Refactored StreamParser into the io.parser package to more clearly denote
|
||||||
|
its relationship to the core IO classes. It is a slightly higher level
|
||||||
|
abstraction ontop of the core IO, having it along side the core IO classes
|
||||||
|
while .reflect was a subpackage was confusing and suggested that
|
||||||
|
StreamParser was somehow intended as a swapable replacement for
|
||||||
|
UBJInputStream which is not how it is intended to be used.
|
||||||
|
|
||||||
|
* Refactored org.ubjson.reflect to org.ubjson.io.reflect to more correctly
|
||||||
|
communicate the relationship -- the reflection-based classes are built on
|
||||||
|
the core IO classes and are just a higher abstraction to interact with UBJSON
|
||||||
|
with.
|
||||||
|
|
||||||
|
* Renamed IDataType to IMarkerType to follow the naming convention for the
|
||||||
|
marker bytes set forth by the spec doc.
|
||||||
|
|
||||||
|
|
||||||
|
10-14-11
|
||||||
|
* ObjectWriter rewritten and works correctly. Tested with the example test
|
||||||
|
data and wrote out the compressed and uncompressed formats files correctly
|
||||||
|
from their original object representation.
|
||||||
|
|
||||||
|
* Added support for reading and writing huge values as BigInteger as well
|
||||||
|
as BigDecimal.
|
||||||
|
|
||||||
|
* Added automatic numeric storage compression support to ObjectWriter - based
|
||||||
|
on the numeric value (regardless of type) the value will be stored as the
|
||||||
|
smallest possible representation in the UBJ format if requested.
|
||||||
|
|
||||||
|
* Added mapping support for BigDecimal, BigInteger, AtomicInteger and
|
||||||
|
AtomicLong to ObjectWriter.
|
||||||
|
|
||||||
|
* Added readNull and readBoolean to the UBJInputStream and
|
||||||
|
UBJInputStreamParser implementations to make the API feel complete and feel
|
||||||
|
more natural to use.
|
||||||
|
|
||||||
|
10-10-11
|
||||||
|
* com.ubjson.io AND com.ubjson.io.charset are finalized against the
|
||||||
|
Draft 8 specification.
|
||||||
|
|
||||||
|
* The lowest level UBJInput/OuputStream classes were tightened up to run as
|
||||||
|
fast as possible showing an 800ns-per-op improvement in speed.
|
||||||
|
|
||||||
|
* Profiled core UBJInput/OuputStream classes using HPROF for a few million
|
||||||
|
iterations and found no memory leaks and no performance traps; everything at
|
||||||
|
that low level is as tight as it can be.
|
||||||
|
|
||||||
|
* Stream-parsing facilities were moved out of the overloaded UBJInputStream
|
||||||
|
class and into their own subclass called UBJInputStreamParser which operates
|
||||||
|
exactly like a pull-parsing scenario (calling nextType then switching on the
|
||||||
|
value and pulling the appropriate value out of the stream).
|
||||||
|
|
||||||
|
* More example testing/benchmarking data checked into /test/java/com/ubjson/data
|
||||||
|
|
||||||
|
Will begin reworking the Reflection based Object mapping in the
|
||||||
|
org.ubjson.reflect package now that the core IO classes are finalized.
|
||||||
|
|
||||||
|
* Removed all old scratch test files from the org.ubjson package, this was
|
||||||
|
confusing.
|
||||||
|
|
||||||
|
09-27-11
|
||||||
|
* Initial check-in of core IO classes to read/write spec.
|
||||||
|
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
Using the standard UBJInputStream, UBJInputStreamParser and UBJOutputStream
|
||||||
|
implementations to manually read/write UBJ objects is stable and tuned for
|
||||||
|
optimal performance.
|
||||||
|
|
||||||
|
Automatic mapping of objects to/from UBJ format via the reflection-based
|
||||||
|
implementation is not tuned yet. Writing is implemented, but not tuned for
|
||||||
|
optimal performance and reading still has to be written.
|
||||||
|
|
||||||
|
* org.ubjson.io - STABLE
|
||||||
|
* org.ubjson.io.parser - STABLE
|
||||||
|
* org.ubjson.io.reflect - ALPHA
|
||||||
|
* org.ubjson.model - BETA
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
This library is released under the Apache 2 License. See LICENSE.
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
This project represents (the official?) Java implementations of the
|
||||||
|
Universal Binary JSON specification: http://ubjson.org
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
Comming soon...
|
||||||
|
|
||||||
|
|
||||||
|
Performance
|
||||||
|
-----------
|
||||||
|
Comming soon...
|
||||||
|
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---------
|
||||||
|
Universal Binary JSON Specification - http://ubjson.org
|
||||||
|
JSON Specification - http://json.org
|
||||||
|
|
||||||
|
|
||||||
|
Contact
|
||||||
|
-------
|
||||||
|
If you have questions, comments or bug reports for this software please contact
|
||||||
|
us at: software@thebuzzmedia.com
|
|
@ -0,0 +1,80 @@
|
||||||
|
{
|
||||||
|
"id_str":"121769183821312000",
|
||||||
|
"retweet_count":0,
|
||||||
|
"in_reply_to_screen_name":null,
|
||||||
|
"in_reply_to_user_id":null,
|
||||||
|
"truncated":false,
|
||||||
|
"retweeted":false,
|
||||||
|
"possibly_sensitive":false,
|
||||||
|
"in_reply_to_status_id_str":null,
|
||||||
|
"entities":{
|
||||||
|
"urls":[
|
||||||
|
{
|
||||||
|
"url":"http:\/\/t.co\/wtioKkFS",
|
||||||
|
"display_url":"dlvr.it\/pWQy2",
|
||||||
|
"indices":[
|
||||||
|
33,
|
||||||
|
53
|
||||||
|
],
|
||||||
|
"expanded_url":"http:\/\/dlvr.it\/pWQy2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hashtags":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"user_mentions":[
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"geo":null,
|
||||||
|
"place":null,
|
||||||
|
"coordinates":null,
|
||||||
|
"created_at":"Thu Oct 06 02:10:10 +0000 2011",
|
||||||
|
"in_reply_to_user_id_str":null,
|
||||||
|
"user":{
|
||||||
|
"id_str":"77029015",
|
||||||
|
"profile_link_color":"009999",
|
||||||
|
"protected":false,
|
||||||
|
"url":"http:\/\/www.techday.co.nz\/",
|
||||||
|
"screen_name":"techdaynz",
|
||||||
|
"statuses_count":5144,
|
||||||
|
"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1479058408\/techday_48_normal.jpg",
|
||||||
|
"name":"TechDay",
|
||||||
|
"default_profile_image":false,
|
||||||
|
"default_profile":false,
|
||||||
|
"profile_background_color":"131516",
|
||||||
|
"lang":"en",
|
||||||
|
"profile_background_tile":false,
|
||||||
|
"utc_offset":43200,
|
||||||
|
"description":"",
|
||||||
|
"is_translator":false,
|
||||||
|
"show_all_inline_media":false,
|
||||||
|
"contributors_enabled":false,
|
||||||
|
"profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/75893948\/Techday_Background.jpg",
|
||||||
|
"created_at":"Thu Sep 24 20:02:01 +0000 2009",
|
||||||
|
"profile_sidebar_fill_color":"efefef",
|
||||||
|
"follow_request_sent":false,
|
||||||
|
"friends_count":3215,
|
||||||
|
"followers_count":3149,
|
||||||
|
"time_zone":"Auckland",
|
||||||
|
"favourites_count":0,
|
||||||
|
"profile_sidebar_border_color":"eeeeee",
|
||||||
|
"profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1479058408\/techday_48_normal.jpg",
|
||||||
|
"following":false,
|
||||||
|
"geo_enabled":false,
|
||||||
|
"notifications":false,
|
||||||
|
"profile_use_background_image":true,
|
||||||
|
"listed_count":151,
|
||||||
|
"verified":false,
|
||||||
|
"profile_text_color":"333333",
|
||||||
|
"location":"Ponsonby, Auckland, NZ",
|
||||||
|
"id":77029015,
|
||||||
|
"profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/75893948\/Techday_Background.jpg"
|
||||||
|
},
|
||||||
|
"contributors":null,
|
||||||
|
"source":"\u003Ca href=\"http:\/\/dlvr.it\" rel=\"nofollow\"\u003Edlvr.it\u003C\/a\u003E",
|
||||||
|
"in_reply_to_status_id":null,
|
||||||
|
"favorited":false,
|
||||||
|
"id":121769183821312000,
|
||||||
|
"text":"Apple CEO's message to employees http:\/\/t.co\/wtioKkFS"
|
||||||
|
}
|
BIN
test/data/universal-binary-json-java/TwitterTimeline.ubj
Normal file
BIN
test/data/universal-binary-json-java/TwitterTimeline.ubj
Normal file
Binary file not shown.
1
test/data/universal-binary-json-java/url.txt
Normal file
1
test/data/universal-binary-json-java/url.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
https://github.com/ubjson/universal-binary-json-java/tree/master/src/test/resources/org/ubjson
|
1593
test/src/unit-ubjson.cpp
Normal file
1593
test/src/unit-ubjson.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue