From 0a09db9cc24fe23e226fd15ced3182068dba06ae Mon Sep 17 00:00:00 2001 From: Julian Becker Date: Sat, 29 Sep 2018 11:33:01 +0200 Subject: [PATCH] BSON: Extend `binary_reader::get_number` to be able to hanlde little endian input to get rid of `binary_reader::get_number_little_endian` --- .../nlohmann/detail/input/binary_reader.hpp | 44 ++++--------------- single_include/nlohmann/json.hpp | 44 ++++--------------- 2 files changed, 16 insertions(+), 72 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 0a95fef5..d68a6091 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -177,7 +177,7 @@ class binary_reader case 0x01: // double { double number; - get_number_little_endian(number); + get_number(number); sax->number_float(static_cast(number), ""); } break; @@ -185,7 +185,7 @@ class binary_reader { std::int32_t len; string_t value; - get_number_little_endian(len); + get_number(len); get_string(len - 1ul, value); get(); sax->string(value); @@ -199,14 +199,14 @@ class binary_reader case 0x10: // int32 { std::int32_t value; - get_number_little_endian(value); + get_number(value); sax->number_integer(static_cast(value)); } break; case 0x12: // int64 { std::int64_t value; - get_number_little_endian(value); + get_number(value); sax->number_integer(static_cast(value)); } break; @@ -233,7 +233,7 @@ class binary_reader bool parse_bson_array() { std::int32_t documentSize; - get_number_little_endian(documentSize); + get_number(documentSize); if (JSON_UNLIKELY(not sax->start_array(-1))) { @@ -251,7 +251,7 @@ class binary_reader bool parse_bson_internal() { std::int32_t documentSize; - get_number_little_endian(documentSize); + get_number(documentSize); 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 (big endian) and therefore need reordering on little endian systems. */ - template + template bool get_number(NumberType& result) { // 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 - if (is_little_endian) + if (is_little_endian && !InputIsLittleEndian) { vec[sizeof(NumberType) - i - 1] = static_cast(current); } @@ -1045,34 +1045,6 @@ class binary_reader return true; } - template - bool get_number_little_endian(NumberType& result) - { - // step 1: read input into array with system's byte order - std::array 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(current); - } - else - { - vec[i] = static_cast(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 diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 3f7cd4e7..ac11591a 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6161,7 +6161,7 @@ class binary_reader case 0x01: // double { double number; - get_number_little_endian(number); + get_number(number); sax->number_float(static_cast(number), ""); } break; @@ -6169,7 +6169,7 @@ class binary_reader { std::int32_t len; string_t value; - get_number_little_endian(len); + get_number(len); get_string(len - 1ul, value); get(); sax->string(value); @@ -6183,14 +6183,14 @@ class binary_reader case 0x10: // int32 { std::int32_t value; - get_number_little_endian(value); + get_number(value); sax->number_integer(static_cast(value)); } break; case 0x12: // int64 { std::int64_t value; - get_number_little_endian(value); + get_number(value); sax->number_integer(static_cast(value)); } break; @@ -6217,7 +6217,7 @@ class binary_reader bool parse_bson_array() { std::int32_t documentSize; - get_number_little_endian(documentSize); + get_number(documentSize); if (JSON_UNLIKELY(not sax->start_array(-1))) { @@ -6235,7 +6235,7 @@ class binary_reader bool parse_bson_internal() { std::int32_t documentSize; - get_number_little_endian(documentSize); + get_number(documentSize); 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 (big endian) and therefore need reordering on little endian systems. */ - template + template bool get_number(NumberType& result) { // 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 - if (is_little_endian) + if (is_little_endian && !InputIsLittleEndian) { vec[sizeof(NumberType) - i - 1] = static_cast(current); } @@ -7029,34 +7029,6 @@ class binary_reader return true; } - template - bool get_number_little_endian(NumberType& result) - { - // step 1: read input into array with system's byte order - std::array 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(current); - } - else - { - vec[i] = static_cast(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