BSON: Extend binary_reader::get_number to be able to hanlde little endian input to get rid of binary_reader::get_number_little_endian

This commit is contained in:
Julian Becker 2018-09-29 11:33:01 +02:00
parent ef358ae695
commit 0a09db9cc2
2 changed files with 16 additions and 72 deletions

View file

@ -177,7 +177,7 @@ class binary_reader
case 0x01: // double case 0x01: // double
{ {
double number; double number;
get_number_little_endian(number); get_number<double, true>(number);
sax->number_float(static_cast<number_float_t>(number), ""); sax->number_float(static_cast<number_float_t>(number), "");
} }
break; break;
@ -185,7 +185,7 @@ class binary_reader
{ {
std::int32_t len; std::int32_t len;
string_t value; string_t value;
get_number_little_endian(len); get_number<std::int32_t, true>(len);
get_string(len - 1ul, value); get_string(len - 1ul, value);
get(); get();
sax->string(value); sax->string(value);
@ -199,14 +199,14 @@ class binary_reader
case 0x10: // int32 case 0x10: // int32
{ {
std::int32_t value; std::int32_t value;
get_number_little_endian(value); get_number<std::int32_t, true>(value);
sax->number_integer(static_cast<std::int32_t>(value)); sax->number_integer(static_cast<std::int32_t>(value));
} }
break; break;
case 0x12: // int64 case 0x12: // int64
{ {
std::int64_t value; std::int64_t value;
get_number_little_endian(value); get_number<std::int64_t, true>(value);
sax->number_integer(static_cast<std::int64_t>(value)); sax->number_integer(static_cast<std::int64_t>(value));
} }
break; break;
@ -233,7 +233,7 @@ class binary_reader
bool parse_bson_array() bool parse_bson_array()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number_little_endian(documentSize); get_number<std::int32_t, true>(documentSize);
if (JSON_UNLIKELY(not sax->start_array(-1))) if (JSON_UNLIKELY(not sax->start_array(-1)))
{ {
@ -251,7 +251,7 @@ class binary_reader
bool parse_bson_internal() bool parse_bson_internal()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number_little_endian(documentSize); get_number<std::int32_t, true>(documentSize);
if (JSON_UNLIKELY(not sax->start_object(-1))) if (JSON_UNLIKELY(not sax->start_object(-1)))
{ {
@ -1016,7 +1016,7 @@ class binary_reader
bytes in CBOR, MessagePack, and UBJSON are stored in network order bytes in CBOR, MessagePack, and UBJSON are stored in network order
(big endian) and therefore need reordering on little endian systems. (big endian) and therefore need reordering on little endian systems.
*/ */
template<typename NumberType> template<typename NumberType, bool InputIsLittleEndian = false>
bool get_number(NumberType& result) bool get_number(NumberType& result)
{ {
// step 1: read input into array with system's byte order // step 1: read input into array with system's byte order
@ -1030,7 +1030,7 @@ class binary_reader
} }
// reverse byte order prior to conversion if necessary // reverse byte order prior to conversion if necessary
if (is_little_endian) if (is_little_endian && !InputIsLittleEndian)
{ {
vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current); vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
} }
@ -1045,34 +1045,6 @@ class binary_reader
return true; return true;
} }
template<typename NumberType>
bool get_number_little_endian(NumberType& result)
{
// step 1: read input into array with system's byte order
std::array<uint8_t, sizeof(NumberType)> vec;
for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{
get();
if (JSON_UNLIKELY(not unexpect_eof()))
{
return false;
}
// reverse byte order prior to conversion if necessary
if (!is_little_endian)
{
vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
}
else
{
vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
}
}
// step 2: convert array into number of type T and return
std::memcpy(&result, vec.data(), sizeof(NumberType));
return true;
}
/*! /*!
@brief create a string by reading characters from the input @brief create a string by reading characters from the input

View file

@ -6161,7 +6161,7 @@ class binary_reader
case 0x01: // double case 0x01: // double
{ {
double number; double number;
get_number_little_endian(number); get_number<double, true>(number);
sax->number_float(static_cast<number_float_t>(number), ""); sax->number_float(static_cast<number_float_t>(number), "");
} }
break; break;
@ -6169,7 +6169,7 @@ class binary_reader
{ {
std::int32_t len; std::int32_t len;
string_t value; string_t value;
get_number_little_endian(len); get_number<std::int32_t, true>(len);
get_string(len - 1ul, value); get_string(len - 1ul, value);
get(); get();
sax->string(value); sax->string(value);
@ -6183,14 +6183,14 @@ class binary_reader
case 0x10: // int32 case 0x10: // int32
{ {
std::int32_t value; std::int32_t value;
get_number_little_endian(value); get_number<std::int32_t, true>(value);
sax->number_integer(static_cast<std::int32_t>(value)); sax->number_integer(static_cast<std::int32_t>(value));
} }
break; break;
case 0x12: // int64 case 0x12: // int64
{ {
std::int64_t value; std::int64_t value;
get_number_little_endian(value); get_number<std::int64_t, true>(value);
sax->number_integer(static_cast<std::int64_t>(value)); sax->number_integer(static_cast<std::int64_t>(value));
} }
break; break;
@ -6217,7 +6217,7 @@ class binary_reader
bool parse_bson_array() bool parse_bson_array()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number_little_endian(documentSize); get_number<std::int32_t, true>(documentSize);
if (JSON_UNLIKELY(not sax->start_array(-1))) if (JSON_UNLIKELY(not sax->start_array(-1)))
{ {
@ -6235,7 +6235,7 @@ class binary_reader
bool parse_bson_internal() bool parse_bson_internal()
{ {
std::int32_t documentSize; std::int32_t documentSize;
get_number_little_endian(documentSize); get_number<std::int32_t, true>(documentSize);
if (JSON_UNLIKELY(not sax->start_object(-1))) if (JSON_UNLIKELY(not sax->start_object(-1)))
{ {
@ -7000,7 +7000,7 @@ class binary_reader
bytes in CBOR, MessagePack, and UBJSON are stored in network order bytes in CBOR, MessagePack, and UBJSON are stored in network order
(big endian) and therefore need reordering on little endian systems. (big endian) and therefore need reordering on little endian systems.
*/ */
template<typename NumberType> template<typename NumberType, bool InputIsLittleEndian = false>
bool get_number(NumberType& result) bool get_number(NumberType& result)
{ {
// step 1: read input into array with system's byte order // step 1: read input into array with system's byte order
@ -7014,7 +7014,7 @@ class binary_reader
} }
// reverse byte order prior to conversion if necessary // reverse byte order prior to conversion if necessary
if (is_little_endian) if (is_little_endian && !InputIsLittleEndian)
{ {
vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current); vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
} }
@ -7029,34 +7029,6 @@ class binary_reader
return true; return true;
} }
template<typename NumberType>
bool get_number_little_endian(NumberType& result)
{
// step 1: read input into array with system's byte order
std::array<uint8_t, sizeof(NumberType)> vec;
for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{
get();
if (JSON_UNLIKELY(not unexpect_eof()))
{
return false;
}
// reverse byte order prior to conversion if necessary
if (!is_little_endian)
{
vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
}
else
{
vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
}
}
// step 2: convert array into number of type T and return
std::memcpy(&result, vec.data(), sizeof(NumberType));
return true;
}
/*! /*!
@brief create a string by reading characters from the input @brief create a string by reading characters from the input