Commit 0a09db9c authored by Julian Becker's avatar Julian Becker

BSON: Extend `binary_reader::get_number` to be able to hanlde little endian...

BSON: Extend `binary_reader::get_number` to be able to hanlde little endian input to get rid of `binary_reader::get_number_little_endian`
parent ef358ae6
...@@ -177,7 +177,7 @@ class binary_reader ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -6161,7 +6161,7 @@ class binary_reader ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment