Remove unreachable code found by the coverage analysis
Remove code that no input can reach, and mark the lines that cannot be covered with LCOV_EXCL_LINE: - BJData writer: the dry_run parameter of the ND-array element writers was always true; replace them by range checks. - BON8 writer: call throw_integer_out_of_range() directly instead of write_bon8_value() for values that always throw. - binary_writer: integer_bits() is only called for integers of up to 64 bits. - serializer, view serializer, lexer: replace guards that the callers make unreachable by assertions or by the simpler code (surrogate pairs under ensure_ascii, next_unget, '-' at the end of the buffer). - json_view: drop unreachable branches in scalar(), set(), check_utf8_scan(), append_input_impl() and unescape(). - Mark exception-cleanup braces, 2 GiB limits, big-endian and 32-bit code, and fall-through case labels with LCOV_EXCL_LINE. No behavior changes for any input that reaches these functions. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
21 files changed
+234
-404
No files matched your search
@@ -91,7 +91,7 @@ const typename BasicJsonType::binary_t& binary_value(const BasicJsonType& j)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
typename View::basic_json_type::binary_t binary_value(const View& /*unused*/)
|
typename View::basic_json_type::binary_t binary_value(const View& /*unused*/) // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
return {}; // LCOV_EXCL_LINE
|
return {}; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ class input_stream_adapter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current_in_get_area = true;
|
current_in_get_area = true; // LCOV_EXCL_LINE (called only when the get area is exhausted)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -999,7 +999,7 @@ class json_sax_dom_parser : public json_sax_dom_error_state
|
|||||||
ordered_data.members[f.ordered.dest_member].second = std::move(value);
|
ordered_data.members[f.ordered.dest_member].second = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void place_member(const frame& /*f*/, BasicJsonType&& /*value*/, std::false_type /*indexed*/) noexcept {}
|
static void place_member(const frame& /*f*/, BasicJsonType&& /*value*/, std::false_type /*indexed*/) noexcept {} // LCOV_EXCL_LINE
|
||||||
|
|
||||||
/// store the members of a new object directly in it
|
/// store the members of a new object directly in it
|
||||||
bool start_stored_object(std::size_t len)
|
bool start_stored_object(std::size_t len)
|
||||||
|
|||||||
@@ -437,11 +437,10 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
template<bool Keep>
|
template<bool Keep>
|
||||||
char_int_type get_after_string_run(std::true_type /*bulk*/, std::integral_constant<bool, Keep> keep)
|
char_int_type get_after_string_run(std::true_type /*bulk*/, std::integral_constant<bool, Keep> keep)
|
||||||
{
|
{
|
||||||
// a pending unget must be consumed through the normal path first
|
// scan_string() is entered from scan_after_whitespace(), whose current
|
||||||
if (next_unget)
|
// was read by skip_whitespace() (its first get() clears a pending
|
||||||
{
|
// unget), and nothing in scan_string() calls unget()
|
||||||
return get();
|
JSON_ASSERT(!next_unget);
|
||||||
}
|
|
||||||
const std::size_t remaining = ia.bulk_remaining();
|
const std::size_t remaining = ia.bulk_remaining();
|
||||||
if (remaining == 0)
|
if (remaining == 0)
|
||||||
{
|
{
|
||||||
@@ -1516,11 +1515,9 @@ scan_number_done:
|
|||||||
*/
|
*/
|
||||||
token_type scan_number_bulk_contiguous()
|
token_type scan_number_bulk_contiguous()
|
||||||
{
|
{
|
||||||
// a pending unget offsets the buffer position from current; fall back
|
// called right after scan_after_whitespace() read current (see
|
||||||
if (next_unget)
|
// get_after_string_run()), so no unget is pending
|
||||||
{
|
JSON_ASSERT(!next_unget);
|
||||||
return token_type::uninitialized;
|
|
||||||
}
|
|
||||||
const std::size_t rem = ia.bulk_remaining();
|
const std::size_t rem = ia.bulk_remaining();
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
{
|
{
|
||||||
@@ -1541,11 +1538,7 @@ scan_number_done:
|
|||||||
if (data[0] == '-')
|
if (data[0] == '-')
|
||||||
{
|
{
|
||||||
number_type = token_type::value_integer;
|
number_type = token_type::value_integer;
|
||||||
i = 1;
|
i = 1; // avail >= 2: rem == 0 returned above
|
||||||
if (i >= avail)
|
|
||||||
{
|
|
||||||
return token_type::uninitialized;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const std::size_t integer_begin = i;
|
const std::size_t integer_begin = i;
|
||||||
if (data[i] == '0')
|
if (data[i] == '0')
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ class parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
return error_msg;
|
return error_msg;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// callback function
|
/// callback function
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ class json_pointer
|
|||||||
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
||||||
result.reference_tokens.insert(result.reference_tokens.end(), rhs.reference_tokens.begin(), rhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), rhs.reference_tokens.begin(), rhs.reference_tokens.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||||
@@ -315,7 +315,7 @@ class json_pointer
|
|||||||
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
||||||
result.reference_tokens.push_back(std::move(token));
|
result.reference_tokens.push_back(std::move(token));
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||||
@@ -2180,7 +2180,7 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
// create an entry in the array
|
// create an entry in the array
|
||||||
current = ¤t->operator[](array_index<BasicJsonType>(token));
|
current = ¤t->operator[](array_index<BasicJsonType>(token));
|
||||||
break;
|
break; // LCOV_EXCL_LINE (needs an array index with 10 or more digits: more than 1e9 elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2217,7 +2217,7 @@ class json_pointer
|
|||||||
json_pointer<string_t> result;
|
json_pointer<string_t> result;
|
||||||
result.reference_tokens = reference_tokens;
|
result.reference_tokens = reference_tokens;
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
json_pointer<string_t> convert()&&
|
json_pointer<string_t> convert()&&
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -833,7 +833,7 @@ class binary_writer
|
|||||||
while (n != 0);
|
while (n != 0);
|
||||||
std::reverse(result.begin(), result.end());
|
std::reverse(result.begin(), result.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the decimal digits of the integer @a n, with a leading '-' if it
|
@brief the decimal digits of the integer @a n, with a leading '-' if it
|
||||||
@@ -860,7 +860,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
std::reverse(result.begin(), result.end());
|
std::reverse(result.begin(), result.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief throws because the integer @a j is too large for @a format
|
@brief throws because the integer @a j is too large for @a format
|
||||||
@@ -1792,7 +1792,7 @@ class binary_writer
|
|||||||
std::memcpy(out, &n, sizeof(NumberType));
|
std::memcpy(out, &n, sizeof(NumberType));
|
||||||
if (!is_little_endian)
|
if (!is_little_endian)
|
||||||
{
|
{
|
||||||
std::reverse(out, out + sizeof(NumberType));
|
std::reverse(out, out + sizeof(NumberType)); // LCOV_EXCL_LINE (big-endian hosts only)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1921,7 +1921,7 @@ class binary_writer
|
|||||||
const string_t& value = *j.m_data.m_value.string;
|
const string_t& value = *j.m_data.m_value.string;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(value.size() + 1ul)))
|
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(value.size() + 1ul)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a string of 2 GiB or more)
|
||||||
}
|
}
|
||||||
out[0] = to_char_type(0x02);
|
out[0] = to_char_type(0x02);
|
||||||
store_little_endian<std::int32_t>(p, static_cast<std::int32_t>(value.size() + 1ul));
|
store_little_endian<std::int32_t>(p, static_cast<std::int32_t>(value.size() + 1ul));
|
||||||
@@ -2378,7 +2378,7 @@ class binary_writer
|
|||||||
const std::size_t size = oa.written() - pos;
|
const std::size_t size = oa.written() - pos;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(size)))
|
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(size)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
const auto le_size = static_cast<std::uint32_t>(size);
|
const auto le_size = static_cast<std::uint32_t>(size);
|
||||||
oa.overwrite(pos, is_little_endian ? le_size : byteswap(le_size));
|
oa.overwrite(pos, is_little_endian ? le_size : byteswap(le_size));
|
||||||
@@ -2507,7 +2507,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(nested_size_pos)))
|
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(nested_size_pos)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2522,7 +2522,7 @@ class binary_writer
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(current.size_slot)))
|
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(current.size_slot)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
if (parents.empty())
|
if (parents.empty())
|
||||||
{
|
{
|
||||||
@@ -2779,10 +2779,10 @@ class binary_writer
|
|||||||
|
|
||||||
Selected through masks rather than branches, as the type and the sign of
|
Selected through masks rather than branches, as the type and the sign of
|
||||||
the values in an array of mixed signs alternate unpredictably (non-negative
|
the values in an array of mixed signs alternate unpredictably (non-negative
|
||||||
integers are number_unsigned after parsing). Up to 64 bits, the sign is bit
|
integers are number_unsigned after parsing). The sign is bit 63 of the
|
||||||
63 of the result (a narrower integer is sign-extended); computing it with
|
result (a narrower integer is sign-extended); computing it with masks keeps
|
||||||
masks keeps GCC from branching on the type. A wider integer has to be
|
GCC from branching on the type. Only called if @ref integers_fit_64_bits();
|
||||||
compared.
|
a wider number type is written with range checks on the whole value.
|
||||||
*/
|
*/
|
||||||
static std::uint64_t integer_bits(const BasicJsonType& j, std::uint64_t& sign_mask) noexcept
|
static std::uint64_t integer_bits(const BasicJsonType& j, std::uint64_t& sign_mask) noexcept
|
||||||
{
|
{
|
||||||
@@ -2790,9 +2790,7 @@ class binary_writer
|
|||||||
const std::uint64_t raw = is_signed
|
const std::uint64_t raw = is_signed
|
||||||
? static_cast<std::uint64_t>(j.m_data.m_value.number_integer)
|
? static_cast<std::uint64_t>(j.m_data.m_value.number_integer)
|
||||||
: static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned);
|
: static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned);
|
||||||
sign_mask = sizeof(typename BasicJsonType::number_integer_t) <= sizeof(std::uint64_t)
|
sign_mask = (std::uint64_t{0} - static_cast<std::uint64_t>(is_signed)) & (std::uint64_t{0} - (raw >> 63u));
|
||||||
? (std::uint64_t{0} - static_cast<std::uint64_t>(is_signed)) & (std::uint64_t{0} - (raw >> 63u))
|
|
||||||
: std::uint64_t{0} - static_cast<std::uint64_t>(is_signed && j.m_data.m_value.number_integer < 0);
|
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4159,57 +4157,34 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief validate (dry_run) or write one BJData ND-array element of integer dtype @a T
|
@brief whether the BJData ND-array element @a el can be written with dtype 'd' (single precision)
|
||||||
@return whether @a el's value is in range of @a T; always true when @a dry_run is false
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool write_bjdata_ndarray_element(const BasicJsonType& el, const bool dry_run)
|
|
||||||
{
|
|
||||||
if (dry_run)
|
|
||||||
{
|
|
||||||
return bjdata_ndarray_value_in_range<T>(el);
|
|
||||||
}
|
|
||||||
using storage_type = typename std::conditional<std::is_unsigned<T>::value, std::uint64_t, std::int64_t>::type;
|
|
||||||
write_number(static_cast<T>(el.template get<storage_type>()), true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief validate (dry_run) or write one BJData ND-array element of dtype 'd' (single precision)
|
|
||||||
@return whether @a el's value survives narrowing to float and back without any change
|
@return whether @a el's value survives narrowing to float and back without any change
|
||||||
(so the ND-array round-trips exactly), or is infinite or NaN; always true when
|
(so the ND-array round-trips exactly), or is infinite or NaN
|
||||||
@a dry_run is false
|
|
||||||
*/
|
*/
|
||||||
bool write_bjdata_ndarray_float_element(const BasicJsonType& el, const bool dry_run)
|
static bool bjdata_ndarray_float_in_range(const BasicJsonType& el) noexcept
|
||||||
{
|
{
|
||||||
const auto dval = static_cast<double>(el.m_data.m_value.number_float);
|
const auto dval = static_cast<double>(el.m_data.m_value.number_float);
|
||||||
if (dry_run)
|
|
||||||
{
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
||||||
JSON_HEDLEY_PRAGMA(GCC diagnostic ignored "-Wfloat-equal")
|
JSON_HEDLEY_PRAGMA(GCC diagnostic ignored "-Wfloat-equal")
|
||||||
#endif
|
#endif
|
||||||
// a value that would be rounded (rather than exactly represented) by the
|
// a value that would be rounded (rather than exactly represented) by the
|
||||||
// narrowing to float is treated like an out-of-range integer element; this
|
// narrowing to float is treated like an out-of-range integer element; this
|
||||||
// is the same criterion write_compact_float() uses for CBOR/MessagePack
|
// is the same criterion write_compact_float() uses for CBOR/MessagePack
|
||||||
const bool in_range = std::isnan(dval) ||
|
return std::isnan(dval) ||
|
||||||
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
||||||
dval <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
dval <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
||||||
static_cast<double>(static_cast<float>(dval)) == dval) ||
|
static_cast<double>(static_cast<float>(dval)) == dval) ||
|
||||||
std::isinf(dval);
|
std::isinf(dval);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_POP
|
JSON_HEDLEY_DIAGNOSTIC_POP
|
||||||
#endif
|
#endif
|
||||||
return in_range;
|
|
||||||
}
|
|
||||||
write_number(static_cast<float>(dval), true);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief write the elements of an ND-array as the number kind @a dtype names
|
@brief write the elements of an ND-array as the number kind @a dtype names
|
||||||
(see @ref write_bjdata_ndarray), after they have been found to be
|
(see @ref write_bjdata_ndarray), after they have been found to be
|
||||||
in range by a dry run of @ref write_bjdata_ndarray_elements
|
in range by @ref bjdata_ndarray_elements_in_range
|
||||||
|
|
||||||
The elements are encoded in blocks into space reserved from the sink.
|
The elements are encoded in blocks into space reserved from the sink.
|
||||||
*/
|
*/
|
||||||
@@ -4291,20 +4266,13 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief validate or write every element of a BJData ND-array's `_ArrayData_`
|
@brief whether every element of a BJData ND-array's `_ArrayData_` is in range for its dtype
|
||||||
@param[in] array_data the `_ArrayData_` array
|
@param[in] array_data the `_ArrayData_` array
|
||||||
@param[in] dtype the ND-array dtype marker, as returned by bjdata_ndarray_type_marker()
|
@param[in] dtype the ND-array dtype marker, as returned by bjdata_ndarray_type_marker()
|
||||||
@param[in] dry_run true to only range-check each element, false to write it
|
@return whether every element is in range for @a dtype
|
||||||
@return whether every element is in range for @a dtype (always true when @a dry_run is false)
|
|
||||||
*/
|
*/
|
||||||
bool write_bjdata_ndarray_elements(const BasicJsonType& array_data, const CharType dtype, const bool dry_run)
|
static bool bjdata_ndarray_elements_in_range(const BasicJsonType& array_data, const CharType dtype)
|
||||||
{
|
{
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
write_bjdata_ndarray_values(array_data, dtype);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& el : array_data)
|
for (const auto& el : array_data)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
@@ -4312,43 +4280,39 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
case 'U':
|
case 'U':
|
||||||
case 'B':
|
case 'B':
|
||||||
ok = write_bjdata_ndarray_element<std::uint8_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
// BJData limits a char to 0..127 (the intersection of the int8 and uint8 ranges)
|
// BJData limits a char to 0..127 (the intersection of the int8 and uint8 ranges)
|
||||||
ok = bjdata_ndarray_value_in_range<std::int8_t>(el) && bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
ok = bjdata_ndarray_value_in_range<std::int8_t>(el) && bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
ok = write_bjdata_ndarray_element<std::int8_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
ok = write_bjdata_ndarray_element<std::uint16_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint16_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
ok = write_bjdata_ndarray_element<std::int16_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int16_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
ok = write_bjdata_ndarray_element<std::uint32_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint32_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
ok = write_bjdata_ndarray_element<std::int32_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int32_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
ok = write_bjdata_ndarray_element<std::uint64_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint64_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
ok = write_bjdata_ndarray_element<std::int64_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int64_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
ok = write_bjdata_ndarray_float_element(el, dry_run);
|
ok = bjdata_ndarray_float_in_range(el);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
default:
|
default:
|
||||||
// 'D' (double) already spans the full range of number_float_t
|
// 'D' (double) already spans the full range of number_float_t
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
write_number(el.template get<double>(), true);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@@ -4435,7 +4399,7 @@ class binary_writer
|
|||||||
const auto dim = el.template get<std::uint64_t>();
|
const auto dim = el.template get<std::uint64_t>();
|
||||||
if (!value_in_range_of<std::size_t>(dim))
|
if (!value_in_range_of<std::size_t>(dim))
|
||||||
{
|
{
|
||||||
return true;
|
return true; // LCOV_EXCL_LINE (size_t is narrower than 64 bits)
|
||||||
}
|
}
|
||||||
const auto dim_size = static_cast<std::size_t>(dim);
|
const auto dim_size = static_cast<std::size_t>(dim);
|
||||||
|
|
||||||
@@ -4485,7 +4449,7 @@ class binary_writer
|
|||||||
// wrap (integers) or overflow to infinity (the "single" precision
|
// wrap (integers) or overflow to infinity (the "single" precision
|
||||||
// float) instead of being reported, so such an object falls back to
|
// float) instead of being reported, so such an object falls back to
|
||||||
// a plain object encoding as well
|
// a plain object encoding as well
|
||||||
if (!write_bjdata_ndarray_elements(array_data, dtype, true))
|
if (!bjdata_ndarray_elements_in_range(array_data, dtype))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4497,7 +4461,7 @@ class binary_writer
|
|||||||
|
|
||||||
write_ubjson(array_size, use_count, use_type, true, true, bjdata_version);
|
write_ubjson(array_size, use_count, use_type, true, true, bjdata_version);
|
||||||
|
|
||||||
write_bjdata_ndarray_elements(array_data, dtype, false);
|
write_bjdata_ndarray_values(array_data, dtype);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4823,8 +4787,8 @@ class binary_writer
|
|||||||
run are encoded into space reserved from the sink, as in
|
run are encoded into space reserved from the sink, as in
|
||||||
@ref write_array_elements; an integer that BON8 cannot write (an unsigned
|
@ref write_array_elements; an integer that BON8 cannot write (an unsigned
|
||||||
one above the int64 range, or one of a number type wider than 64 bits) throws
|
one above the int64 range, or one of a number type wider than 64 bits) throws
|
||||||
from write_bon8_value, like any other value that is not a number. Kept out
|
out_of_range.407, as write_bon8_value does. Kept out of line, like
|
||||||
of line, like @ref write_cbor_array.
|
@ref write_cbor_array.
|
||||||
*/
|
*/
|
||||||
template<typename ArrayType>
|
template<typename ArrayType>
|
||||||
JSON_HEDLEY_NEVER_INLINE
|
JSON_HEDLEY_NEVER_INLINE
|
||||||
@@ -4874,10 +4838,10 @@ class binary_writer
|
|||||||
string_open = false;
|
string_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unencodable)
|
if (JSON_HEDLEY_UNLIKELY(unencodable))
|
||||||
{
|
{
|
||||||
write_bon8_value(*it, string_open, depth + 1);
|
// an integer beyond the int64 range, as write_bon8_value would report it
|
||||||
++it;
|
throw_integer_out_of_range(*it, input_format_t::bon8, "int64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4912,14 +4876,13 @@ class binary_writer
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
if (JSON_HEDLEY_LIKELY(integer_fits<std::int64_t>(value.m_data.m_value.number_integer)))
|
if (JSON_HEDLEY_UNLIKELY(!integer_fits<std::int64_t>(value.m_data.m_value.number_integer)))
|
||||||
{
|
{
|
||||||
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_integer));
|
// beyond 64 bits (number types wider than that)
|
||||||
string_open = false;
|
throw_integer_out_of_range(value, input_format_t::bon8, "int64");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// beyond 64 bits (number types wider than that): throws
|
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_integer));
|
||||||
write_bon8_value(value, string_open, depth + 1);
|
string_open = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
@@ -4928,14 +4891,13 @@ class binary_writer
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
if (JSON_HEDLEY_LIKELY(integer_fits_max<std::int64_t>(value.m_data.m_value.number_unsigned)))
|
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::int64_t>(value.m_data.m_value.number_unsigned)))
|
||||||
{
|
{
|
||||||
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_unsigned));
|
// too large for BON8
|
||||||
string_open = false;
|
throw_integer_out_of_range(value, input_format_t::bon8, "int64");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// too large for BON8: throws
|
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_unsigned));
|
||||||
write_bon8_value(value, string_open, depth + 1);
|
string_open = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
|
|||||||
@@ -1117,7 +1117,7 @@ class serializer
|
|||||||
// character
|
// character
|
||||||
if (EnsureAscii)
|
if (EnsureAscii)
|
||||||
{
|
{
|
||||||
JSON_ASSERT(codepoint >= 0x7F);
|
JSON_ASSERT(codepoint == 0x7F);
|
||||||
if (error_handler == error_handler_t::keep)
|
if (error_handler == error_handler_t::keep)
|
||||||
{
|
{
|
||||||
// this character was buffered as raw bytes below
|
// this character was buffered as raw bytes below
|
||||||
@@ -1128,21 +1128,13 @@ class serializer
|
|||||||
// character instead
|
// character instead
|
||||||
bytes = bytes_after_last_accept;
|
bytes = bytes_after_last_accept;
|
||||||
}
|
}
|
||||||
if (codepoint <= 0xFFFF)
|
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
||||||
{
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)));
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// copy byte to buffer (all previous bytes of the
|
// copy byte to buffer (all previous bytes of the
|
||||||
// sequence have been copied in the default case below)
|
// sequence have been copied in the default case below)
|
||||||
string_buffer[bytes++] = s[i];
|
string_buffer[bytes++] = s[i]; // LCOV_EXCL_LINE (well-formed sequences are copied in runs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve_string_buffer(bytes);
|
reserve_string_buffer(bytes);
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ inline OutStringType concat(Args && ... args)
|
|||||||
str.reserve(concat_length(args...));
|
str.reserve(concat_length(args...));
|
||||||
concat_into(str, std::forward<Args>(args)...);
|
concat_into(str, std::forward<Args>(args)...);
|
||||||
return str;
|
return str;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -83,10 +83,6 @@ template<typename StringType>
|
|||||||
inline void unescape(StringType& s)
|
inline void unescape(StringType& s)
|
||||||
{
|
{
|
||||||
auto pos = s.find_first_of('~', 0);
|
auto pos = s.find_first_of('~', 0);
|
||||||
if (pos == StringType::npos)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringType result;
|
StringType result;
|
||||||
result.reserve(s.size());
|
result.reserve(s.size());
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ StringType to_string(std::size_t value)
|
|||||||
StringType result;
|
StringType result;
|
||||||
int_to_string(result, value);
|
int_to_string(result, value);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @return a byte as two uppercase hexadecimal digits
|
/// @return a byte as two uppercase hexadecimal digits
|
||||||
inline std::string hex_byte(const std::uint8_t byte)
|
inline std::string hex_byte(const std::uint8_t byte)
|
||||||
@@ -46,7 +46,7 @@ inline std::string hex_byte(const std::uint8_t byte)
|
|||||||
result[0] = nibble_to_hex[byte / 16];
|
result[0] = nibble_to_hex[byte / 16];
|
||||||
result[1] = nibble_to_hex[byte % 16];
|
result[1] = nibble_to_hex[byte % 16];
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief write a UTF-16 code unit as four lowercase hexadecimal digits
|
@brief write a UTF-16 code unit as four lowercase hexadecimal digits
|
||||||
@@ -390,7 +390,7 @@ inline StringType sanitize_utf8(const StringType& s, const error_handler_t error
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -428,28 +428,19 @@ class view_side
|
|||||||
return string_view_t(m_view.m_doc->str(*m_view.m_node), m_view.m_node->len);
|
return string_view_t(m_view.m_doc->str(*m_view.m_node), m_view.m_node->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// a number, boolean, or null as a basic_json value (no allocation)
|
/// a number as a basic_json value (no allocation); only called for numbers
|
||||||
BasicJsonType scalar() const
|
BasicJsonType scalar() const
|
||||||
{
|
{
|
||||||
switch (m_view.type())
|
const value_t t = m_view.type();
|
||||||
|
if (t == value_t::number_integer)
|
||||||
{
|
{
|
||||||
case value_t::number_integer:
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_integer_t>());
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_integer_t>());
|
|
||||||
case value_t::number_unsigned:
|
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_unsigned_t>());
|
|
||||||
case value_t::number_float:
|
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_float_t>());
|
|
||||||
case value_t::boolean:
|
|
||||||
return BasicJsonType(m_view.template get<bool>());
|
|
||||||
case value_t::null:
|
|
||||||
case value_t::object:
|
|
||||||
case value_t::array:
|
|
||||||
case value_t::string:
|
|
||||||
case value_t::binary:
|
|
||||||
case value_t::discarded:
|
|
||||||
default:
|
|
||||||
return BasicJsonType(nullptr);
|
|
||||||
}
|
}
|
||||||
|
if (t == value_t::number_unsigned)
|
||||||
|
{
|
||||||
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_unsigned_t>());
|
||||||
|
}
|
||||||
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_float_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// start at the first element of this array
|
/// start at the first element of this array
|
||||||
|
|||||||
@@ -96,11 +96,11 @@ NLOHMANN_VIEW_NOINLINE inline void check_utf8_scan(const unsigned char* p, std::
|
|||||||
}
|
}
|
||||||
if (*q >= 0x80)
|
if (*q >= 0x80)
|
||||||
{
|
{
|
||||||
check_utf8_bytewise(p, n, static_cast<std::size_t>(q - p));
|
break; // ill-formed UTF-8: reported below
|
||||||
return; // not reached: the scan stopped at ill-formed UTF-8
|
|
||||||
}
|
}
|
||||||
++q; // a quote, backslash, or control character
|
++q; // a quote, backslash, or control character
|
||||||
}
|
}
|
||||||
|
check_utf8_bytewise(p, n, static_cast<std::size_t>(q - p));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void check_utf8(const char* s, std::size_t n)
|
inline void check_utf8(const char* s, std::size_t n)
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ inline node* find_parent(const document_data& d, const node* target)
|
|||||||
}
|
}
|
||||||
if (target == lo)
|
if (target == lo)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr; // LCOV_EXCL_LINE (the root, or a new value's root, which is linked)
|
||||||
}
|
}
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -420,10 +420,12 @@ struct throwing_sax
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LCOV_EXCL_START (throw_parse_failure parses JSON only)
|
||||||
bool binary(binary_t& /*unused*/)
|
bool binary(binary_t& /*unused*/)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
bool start_object(std::size_t /*unused*/)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,14 +65,9 @@ struct position_source
|
|||||||
return token{end - start};
|
return token{end - start};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the range [first, last), or none if either is npos
|
/// the range [first, last)
|
||||||
void set(std::size_t first, std::size_t last) noexcept
|
void set(std::size_t first, std::size_t last) noexcept
|
||||||
{
|
{
|
||||||
if (first == std::string::npos || last == std::string::npos)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
start = first;
|
start = first;
|
||||||
end = last;
|
end = last;
|
||||||
}
|
}
|
||||||
@@ -191,11 +186,11 @@ struct position_source
|
|||||||
first = n.off;
|
first = n.off;
|
||||||
last = n.off + 4u;
|
last = n.off + 4u;
|
||||||
break;
|
break;
|
||||||
case node_kind::object:
|
case node_kind::object: // LCOV_EXCL_LINE
|
||||||
case node_kind::array:
|
case node_kind::array:
|
||||||
case node_kind::link:
|
case node_kind::link:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
// (a crafted image can point past the text)
|
// (a crafted image can point past the text)
|
||||||
if (last == std::string::npos || last > d.size)
|
if (last == std::string::npos || last > d.size)
|
||||||
|
|||||||
@@ -1389,20 +1389,10 @@ class view_serializer
|
|||||||
/// a float node as dump() writes it
|
/// a float node as dump() writes it
|
||||||
void write_float_node(const node& n)
|
void write_float_node(const node& n)
|
||||||
{
|
{
|
||||||
write_float_node(n, fast_double {});
|
// (only for types other than double: doubles go through write_double_ahead())
|
||||||
}
|
|
||||||
|
|
||||||
void write_float_node(const node& n, std::false_type /*other*/)
|
|
||||||
{
|
|
||||||
write_float(float_value<number_float_t>(m_doc, n));
|
write_float(float_value<number_float_t>(m_doc, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_float_node(const node& n, std::true_type /*double*/)
|
|
||||||
{
|
|
||||||
m_out.reserve(64);
|
|
||||||
m_out.set_cursor(write_double_at(m_out.cursor(), n));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief (doubles) the float at n as dump() writes it, at w (64 bytes of room)
|
@brief (doubles) the float at n as dump() writes it, at w (64 bytes of room)
|
||||||
|
|
||||||
@@ -1497,7 +1487,7 @@ class view_serializer
|
|||||||
{
|
{
|
||||||
const string_t dumped = BasicJsonType(string_t(reinterpret_cast<const char*>(s), n)).dump(); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
const string_t dumped = BasicJsonType(string_t(reinterpret_cast<const char*>(s), n)).dump(); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||||
static_cast<void>(dumped);
|
static_cast<void>(dumped);
|
||||||
}
|
} // LCOV_EXCL_LINE (dump() throws: the callers pass only ill-formed UTF-8)
|
||||||
|
|
||||||
template<bool EnsureAscii>
|
template<bool EnsureAscii>
|
||||||
void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len)
|
void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len)
|
||||||
@@ -1530,15 +1520,7 @@ class view_serializer
|
|||||||
}
|
}
|
||||||
if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F))
|
if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F))
|
||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
write_u_escape(codepoint); // (a single byte: the only caller passes s[i])
|
||||||
{
|
|
||||||
write_u_escape(codepoint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_u_escape(0xD7C0u + (codepoint >> 10u));
|
|
||||||
write_u_escape(0xDC00u + (codepoint & 0x3FFu));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_out.put(reinterpret_cast<const char*>(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs)
|
m_out.put(reinterpret_cast<const char*>(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs)
|
||||||
|
|||||||
+13
-13
@@ -400,7 +400,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
|
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||||
result["compiler"] = {{"family", "gcc"}, {"version", detail::concat<string_t>(
|
result["compiler"] = {{"family", "gcc"}, {"version", detail::concat<string_t>(
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC__)), '.',
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC__)), '.', // LCOV_EXCL_LINE
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_MINOR__)), '.',
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_MINOR__)), '.',
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_PATCHLEVEL__)))
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_PATCHLEVEL__)))
|
||||||
}
|
}
|
||||||
@@ -672,14 +672,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
binary = create<binary_t>();
|
binary = create<binary_t>();
|
||||||
break;
|
break;
|
||||||
case value_t::null:
|
case value_t::null: // LCOV_EXCL_LINE
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1034,14 +1034,14 @@ public:
|
|||||||
destroy_container(t);
|
destroy_container(t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null: // LCOV_EXCL_LINE
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1214,9 +1214,9 @@ public:
|
|||||||
return is_array() ? array_capacity() : object_capacity();
|
return is_array() ? array_capacity() : object_capacity();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static constexpr std::size_t container_capacity() noexcept
|
static constexpr std::size_t container_capacity() noexcept // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
return detail::unknown_size();
|
return detail::unknown_size(); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1402,7 +1402,7 @@ public:
|
|||||||
/// into this switch is worth a few percent when copying a value made
|
/// into this switch is worth a few percent when copying a value made
|
||||||
/// mostly of numbers
|
/// mostly of numbers
|
||||||
JSON_HEDLEY_ALWAYS_INLINE
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
static void copy_leaf_value(const basic_json& src, basic_json& dst)
|
static void copy_leaf_value(const basic_json& src, basic_json& dst) // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
switch (src.m_data.m_type)
|
switch (src.m_data.m_type)
|
||||||
{
|
{
|
||||||
@@ -5554,7 +5554,7 @@ public:
|
|||||||
/// their inlined code at each call site small. Binary values are
|
/// their inlined code at each call site small. Binary values are
|
||||||
/// rare and left to equal_general().
|
/// rare and left to equal_general().
|
||||||
JSON_HEDLEY_ALWAYS_INLINE
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
static int equal_leaf(const_reference lhs, const_reference rhs) noexcept
|
static int equal_leaf(const_reference lhs, const_reference rhs) noexcept // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
||||||
@@ -6863,7 +6863,7 @@ public:
|
|||||||
basic_json result(value_t::object);
|
basic_json result(value_t::object);
|
||||||
json_pointer::flatten("", *this, result);
|
json_pointer::flatten("", *this, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief unflatten a previously flattened JSON value
|
/// @brief unflatten a previously flattened JSON value
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/unflatten/
|
/// @sa https://json.nlohmann.me/api/basic_json/unflatten/
|
||||||
@@ -7576,7 +7576,7 @@ public:
|
|||||||
result.append(path.data(), path.size());
|
result.append(path.data(), path.size());
|
||||||
diff_append_key(result, key);
|
diff_append_key(result, key);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief the path of the element @a index of the value at @a path
|
/// @brief the path of the element @a index of the value at @a path
|
||||||
static string_t diff_index_path(const string_t& path, const std::size_t index)
|
static string_t diff_index_path(const string_t& path, const std::size_t index)
|
||||||
@@ -7586,7 +7586,7 @@ public:
|
|||||||
result.append(path.data(), path.size());
|
result.append(path.data(), path.size());
|
||||||
diff_append_index(result, index);
|
diff_append_index(result, index);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief append the "remove" operations for the elements of array
|
/// @brief append the "remove" operations for the elements of array
|
||||||
/// @a source from @a index on, and the "add" operations for the
|
/// @a source from @a index on, and the "add" operations for the
|
||||||
@@ -7746,7 +7746,7 @@ public:
|
|||||||
// operations
|
// operations
|
||||||
if (source == target)
|
if (source == target)
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (equal objects with the same members in the same order return early)
|
||||||
}
|
}
|
||||||
|
|
||||||
// slow path: the common keys are in a different relative
|
// slow path: the common keys are in a different relative
|
||||||
|
|||||||
@@ -1705,9 +1705,11 @@ class basic_json_document
|
|||||||
{
|
{
|
||||||
// (as before: the library's adapter decides what a null stream yields)
|
// (as before: the library's adapter decides what a null stream yields)
|
||||||
detail::view::append_adapter(buf, detail::input_adapter(file));
|
detail::view::append_adapter(buf, detail::input_adapter(file));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
detail::view::append_file(buf, file);
|
else
|
||||||
|
{
|
||||||
|
detail::view::append_file(buf, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Generated
+93
-150
@@ -3637,10 +3637,6 @@ template<typename StringType>
|
|||||||
inline void unescape(StringType& s)
|
inline void unescape(StringType& s)
|
||||||
{
|
{
|
||||||
auto pos = s.find_first_of('~', 0);
|
auto pos = s.find_first_of('~', 0);
|
||||||
if (pos == StringType::npos)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringType result;
|
StringType result;
|
||||||
result.reserve(s.size());
|
result.reserve(s.size());
|
||||||
@@ -5516,7 +5512,7 @@ inline OutStringType concat(Args && ... args)
|
|||||||
str.reserve(concat_length(args...));
|
str.reserve(concat_length(args...));
|
||||||
concat_into(str, std::forward<Args>(args)...);
|
concat_into(str, std::forward<Args>(args)...);
|
||||||
return str;
|
return str;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -6236,7 +6232,7 @@ const typename BasicJsonType::binary_t& binary_value(const BasicJsonType& j)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
template<typename View, enable_if_t<is_json_view<View>::value, int> = 0>
|
||||||
typename View::basic_json_type::binary_t binary_value(const View& /*unused*/)
|
typename View::basic_json_type::binary_t binary_value(const View& /*unused*/) // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
return {}; // LCOV_EXCL_LINE
|
return {}; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
@@ -7162,7 +7158,7 @@ StringType to_string(std::size_t value)
|
|||||||
StringType result;
|
StringType result;
|
||||||
int_to_string(result, value);
|
int_to_string(result, value);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @return a byte as two uppercase hexadecimal digits
|
/// @return a byte as two uppercase hexadecimal digits
|
||||||
inline std::string hex_byte(const std::uint8_t byte)
|
inline std::string hex_byte(const std::uint8_t byte)
|
||||||
@@ -7172,7 +7168,7 @@ inline std::string hex_byte(const std::uint8_t byte)
|
|||||||
result[0] = nibble_to_hex[byte / 16];
|
result[0] = nibble_to_hex[byte / 16];
|
||||||
result[1] = nibble_to_hex[byte % 16];
|
result[1] = nibble_to_hex[byte % 16];
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief write a UTF-16 code unit as four lowercase hexadecimal digits
|
@brief write a UTF-16 code unit as four lowercase hexadecimal digits
|
||||||
@@ -7516,7 +7512,7 @@ inline StringType sanitize_utf8(const StringType& s, const error_handler_t error
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
NLOHMANN_JSON_NAMESPACE_END
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
@@ -9683,7 +9679,7 @@ class input_stream_adapter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current_in_get_area = true;
|
current_in_get_area = true; // LCOV_EXCL_LINE (called only when the get area is exhausted)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return res;
|
return res;
|
||||||
@@ -13475,11 +13471,10 @@ class lexer : public lexer_base<BasicJsonType>
|
|||||||
template<bool Keep>
|
template<bool Keep>
|
||||||
char_int_type get_after_string_run(std::true_type /*bulk*/, std::integral_constant<bool, Keep> keep)
|
char_int_type get_after_string_run(std::true_type /*bulk*/, std::integral_constant<bool, Keep> keep)
|
||||||
{
|
{
|
||||||
// a pending unget must be consumed through the normal path first
|
// scan_string() is entered from scan_after_whitespace(), whose current
|
||||||
if (next_unget)
|
// was read by skip_whitespace() (its first get() clears a pending
|
||||||
{
|
// unget), and nothing in scan_string() calls unget()
|
||||||
return get();
|
JSON_ASSERT(!next_unget);
|
||||||
}
|
|
||||||
const std::size_t remaining = ia.bulk_remaining();
|
const std::size_t remaining = ia.bulk_remaining();
|
||||||
if (remaining == 0)
|
if (remaining == 0)
|
||||||
{
|
{
|
||||||
@@ -14554,11 +14549,9 @@ scan_number_done:
|
|||||||
*/
|
*/
|
||||||
token_type scan_number_bulk_contiguous()
|
token_type scan_number_bulk_contiguous()
|
||||||
{
|
{
|
||||||
// a pending unget offsets the buffer position from current; fall back
|
// called right after scan_after_whitespace() read current (see
|
||||||
if (next_unget)
|
// get_after_string_run()), so no unget is pending
|
||||||
{
|
JSON_ASSERT(!next_unget);
|
||||||
return token_type::uninitialized;
|
|
||||||
}
|
|
||||||
const std::size_t rem = ia.bulk_remaining();
|
const std::size_t rem = ia.bulk_remaining();
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
{
|
{
|
||||||
@@ -14579,11 +14572,7 @@ scan_number_done:
|
|||||||
if (data[0] == '-')
|
if (data[0] == '-')
|
||||||
{
|
{
|
||||||
number_type = token_type::value_integer;
|
number_type = token_type::value_integer;
|
||||||
i = 1;
|
i = 1; // avail >= 2: rem == 0 returned above
|
||||||
if (i >= avail)
|
|
||||||
{
|
|
||||||
return token_type::uninitialized;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const std::size_t integer_begin = i;
|
const std::size_t integer_begin = i;
|
||||||
if (data[i] == '0')
|
if (data[i] == '0')
|
||||||
@@ -16644,7 +16633,7 @@ class json_sax_dom_parser : public json_sax_dom_error_state
|
|||||||
ordered_data.members[f.ordered.dest_member].second = std::move(value);
|
ordered_data.members[f.ordered.dest_member].second = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void place_member(const frame& /*f*/, BasicJsonType&& /*value*/, std::false_type /*indexed*/) noexcept {}
|
static void place_member(const frame& /*f*/, BasicJsonType&& /*value*/, std::false_type /*indexed*/) noexcept {} // LCOV_EXCL_LINE
|
||||||
|
|
||||||
/// store the members of a new object directly in it
|
/// store the members of a new object directly in it
|
||||||
bool start_stored_object(std::size_t len)
|
bool start_stored_object(std::size_t len)
|
||||||
@@ -23773,7 +23762,7 @@ class parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
return error_msg;
|
return error_msg;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// callback function
|
/// callback function
|
||||||
@@ -25084,7 +25073,7 @@ class json_pointer
|
|||||||
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
||||||
result.reference_tokens.insert(result.reference_tokens.end(), rhs.reference_tokens.begin(), rhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), rhs.reference_tokens.begin(), rhs.reference_tokens.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
/// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||||
@@ -25095,7 +25084,7 @@ class json_pointer
|
|||||||
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
result.reference_tokens.insert(result.reference_tokens.end(), lhs.reference_tokens.begin(), lhs.reference_tokens.end());
|
||||||
result.reference_tokens.push_back(std::move(token));
|
result.reference_tokens.push_back(std::move(token));
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
/// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
|
||||||
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
/// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/
|
||||||
@@ -26960,7 +26949,7 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
// create an entry in the array
|
// create an entry in the array
|
||||||
current = ¤t->operator[](array_index<BasicJsonType>(token));
|
current = ¤t->operator[](array_index<BasicJsonType>(token));
|
||||||
break;
|
break; // LCOV_EXCL_LINE (needs an array index with 10 or more digits: more than 1e9 elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -26997,7 +26986,7 @@ class json_pointer
|
|||||||
json_pointer<string_t> result;
|
json_pointer<string_t> result;
|
||||||
result.reference_tokens = reference_tokens;
|
result.reference_tokens = reference_tokens;
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
json_pointer<string_t> convert()&&
|
json_pointer<string_t> convert()&&
|
||||||
{
|
{
|
||||||
@@ -28767,7 +28756,7 @@ class binary_writer
|
|||||||
while (n != 0);
|
while (n != 0);
|
||||||
std::reverse(result.begin(), result.end());
|
std::reverse(result.begin(), result.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief the decimal digits of the integer @a n, with a leading '-' if it
|
@brief the decimal digits of the integer @a n, with a leading '-' if it
|
||||||
@@ -28794,7 +28783,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
std::reverse(result.begin(), result.end());
|
std::reverse(result.begin(), result.end());
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief throws because the integer @a j is too large for @a format
|
@brief throws because the integer @a j is too large for @a format
|
||||||
@@ -29726,7 +29715,7 @@ class binary_writer
|
|||||||
std::memcpy(out, &n, sizeof(NumberType));
|
std::memcpy(out, &n, sizeof(NumberType));
|
||||||
if (!is_little_endian)
|
if (!is_little_endian)
|
||||||
{
|
{
|
||||||
std::reverse(out, out + sizeof(NumberType));
|
std::reverse(out, out + sizeof(NumberType)); // LCOV_EXCL_LINE (big-endian hosts only)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29855,7 +29844,7 @@ class binary_writer
|
|||||||
const string_t& value = *j.m_data.m_value.string;
|
const string_t& value = *j.m_data.m_value.string;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(value.size() + 1ul)))
|
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(value.size() + 1ul)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a string of 2 GiB or more)
|
||||||
}
|
}
|
||||||
out[0] = to_char_type(0x02);
|
out[0] = to_char_type(0x02);
|
||||||
store_little_endian<std::int32_t>(p, static_cast<std::int32_t>(value.size() + 1ul));
|
store_little_endian<std::int32_t>(p, static_cast<std::int32_t>(value.size() + 1ul));
|
||||||
@@ -30312,7 +30301,7 @@ class binary_writer
|
|||||||
const std::size_t size = oa.written() - pos;
|
const std::size_t size = oa.written() - pos;
|
||||||
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(size)))
|
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(size)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
const auto le_size = static_cast<std::uint32_t>(size);
|
const auto le_size = static_cast<std::uint32_t>(size);
|
||||||
oa.overwrite(pos, is_little_endian ? le_size : byteswap(le_size));
|
oa.overwrite(pos, is_little_endian ? le_size : byteswap(le_size));
|
||||||
@@ -30441,7 +30430,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(nested_size_pos)))
|
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(nested_size_pos)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -30456,7 +30445,7 @@ class binary_writer
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(current.size_slot)))
|
if (JSON_HEDLEY_UNLIKELY(!close_bson_container(current.size_slot)))
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (a document of 2 GiB or more)
|
||||||
}
|
}
|
||||||
if (parents.empty())
|
if (parents.empty())
|
||||||
{
|
{
|
||||||
@@ -30713,10 +30702,10 @@ class binary_writer
|
|||||||
|
|
||||||
Selected through masks rather than branches, as the type and the sign of
|
Selected through masks rather than branches, as the type and the sign of
|
||||||
the values in an array of mixed signs alternate unpredictably (non-negative
|
the values in an array of mixed signs alternate unpredictably (non-negative
|
||||||
integers are number_unsigned after parsing). Up to 64 bits, the sign is bit
|
integers are number_unsigned after parsing). The sign is bit 63 of the
|
||||||
63 of the result (a narrower integer is sign-extended); computing it with
|
result (a narrower integer is sign-extended); computing it with masks keeps
|
||||||
masks keeps GCC from branching on the type. A wider integer has to be
|
GCC from branching on the type. Only called if @ref integers_fit_64_bits();
|
||||||
compared.
|
a wider number type is written with range checks on the whole value.
|
||||||
*/
|
*/
|
||||||
static std::uint64_t integer_bits(const BasicJsonType& j, std::uint64_t& sign_mask) noexcept
|
static std::uint64_t integer_bits(const BasicJsonType& j, std::uint64_t& sign_mask) noexcept
|
||||||
{
|
{
|
||||||
@@ -30724,9 +30713,7 @@ class binary_writer
|
|||||||
const std::uint64_t raw = is_signed
|
const std::uint64_t raw = is_signed
|
||||||
? static_cast<std::uint64_t>(j.m_data.m_value.number_integer)
|
? static_cast<std::uint64_t>(j.m_data.m_value.number_integer)
|
||||||
: static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned);
|
: static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned);
|
||||||
sign_mask = sizeof(typename BasicJsonType::number_integer_t) <= sizeof(std::uint64_t)
|
sign_mask = (std::uint64_t{0} - static_cast<std::uint64_t>(is_signed)) & (std::uint64_t{0} - (raw >> 63u));
|
||||||
? (std::uint64_t{0} - static_cast<std::uint64_t>(is_signed)) & (std::uint64_t{0} - (raw >> 63u))
|
|
||||||
: std::uint64_t{0} - static_cast<std::uint64_t>(is_signed && j.m_data.m_value.number_integer < 0);
|
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32093,57 +32080,34 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief validate (dry_run) or write one BJData ND-array element of integer dtype @a T
|
@brief whether the BJData ND-array element @a el can be written with dtype 'd' (single precision)
|
||||||
@return whether @a el's value is in range of @a T; always true when @a dry_run is false
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool write_bjdata_ndarray_element(const BasicJsonType& el, const bool dry_run)
|
|
||||||
{
|
|
||||||
if (dry_run)
|
|
||||||
{
|
|
||||||
return bjdata_ndarray_value_in_range<T>(el);
|
|
||||||
}
|
|
||||||
using storage_type = typename std::conditional<std::is_unsigned<T>::value, std::uint64_t, std::int64_t>::type;
|
|
||||||
write_number(static_cast<T>(el.template get<storage_type>()), true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief validate (dry_run) or write one BJData ND-array element of dtype 'd' (single precision)
|
|
||||||
@return whether @a el's value survives narrowing to float and back without any change
|
@return whether @a el's value survives narrowing to float and back without any change
|
||||||
(so the ND-array round-trips exactly), or is infinite or NaN; always true when
|
(so the ND-array round-trips exactly), or is infinite or NaN
|
||||||
@a dry_run is false
|
|
||||||
*/
|
*/
|
||||||
bool write_bjdata_ndarray_float_element(const BasicJsonType& el, const bool dry_run)
|
static bool bjdata_ndarray_float_in_range(const BasicJsonType& el) noexcept
|
||||||
{
|
{
|
||||||
const auto dval = static_cast<double>(el.m_data.m_value.number_float);
|
const auto dval = static_cast<double>(el.m_data.m_value.number_float);
|
||||||
if (dry_run)
|
|
||||||
{
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
||||||
JSON_HEDLEY_PRAGMA(GCC diagnostic ignored "-Wfloat-equal")
|
JSON_HEDLEY_PRAGMA(GCC diagnostic ignored "-Wfloat-equal")
|
||||||
#endif
|
#endif
|
||||||
// a value that would be rounded (rather than exactly represented) by the
|
// a value that would be rounded (rather than exactly represented) by the
|
||||||
// narrowing to float is treated like an out-of-range integer element; this
|
// narrowing to float is treated like an out-of-range integer element; this
|
||||||
// is the same criterion write_compact_float() uses for CBOR/MessagePack
|
// is the same criterion write_compact_float() uses for CBOR/MessagePack
|
||||||
const bool in_range = std::isnan(dval) ||
|
return std::isnan(dval) ||
|
||||||
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
(dval >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
|
||||||
dval <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
dval <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
||||||
static_cast<double>(static_cast<float>(dval)) == dval) ||
|
static_cast<double>(static_cast<float>(dval)) == dval) ||
|
||||||
std::isinf(dval);
|
std::isinf(dval);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_POP
|
JSON_HEDLEY_DIAGNOSTIC_POP
|
||||||
#endif
|
#endif
|
||||||
return in_range;
|
|
||||||
}
|
|
||||||
write_number(static_cast<float>(dval), true);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief write the elements of an ND-array as the number kind @a dtype names
|
@brief write the elements of an ND-array as the number kind @a dtype names
|
||||||
(see @ref write_bjdata_ndarray), after they have been found to be
|
(see @ref write_bjdata_ndarray), after they have been found to be
|
||||||
in range by a dry run of @ref write_bjdata_ndarray_elements
|
in range by @ref bjdata_ndarray_elements_in_range
|
||||||
|
|
||||||
The elements are encoded in blocks into space reserved from the sink.
|
The elements are encoded in blocks into space reserved from the sink.
|
||||||
*/
|
*/
|
||||||
@@ -32225,20 +32189,13 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief validate or write every element of a BJData ND-array's `_ArrayData_`
|
@brief whether every element of a BJData ND-array's `_ArrayData_` is in range for its dtype
|
||||||
@param[in] array_data the `_ArrayData_` array
|
@param[in] array_data the `_ArrayData_` array
|
||||||
@param[in] dtype the ND-array dtype marker, as returned by bjdata_ndarray_type_marker()
|
@param[in] dtype the ND-array dtype marker, as returned by bjdata_ndarray_type_marker()
|
||||||
@param[in] dry_run true to only range-check each element, false to write it
|
@return whether every element is in range for @a dtype
|
||||||
@return whether every element is in range for @a dtype (always true when @a dry_run is false)
|
|
||||||
*/
|
*/
|
||||||
bool write_bjdata_ndarray_elements(const BasicJsonType& array_data, const CharType dtype, const bool dry_run)
|
static bool bjdata_ndarray_elements_in_range(const BasicJsonType& array_data, const CharType dtype)
|
||||||
{
|
{
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
write_bjdata_ndarray_values(array_data, dtype);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& el : array_data)
|
for (const auto& el : array_data)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
@@ -32246,43 +32203,39 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
case 'U':
|
case 'U':
|
||||||
case 'B':
|
case 'B':
|
||||||
ok = write_bjdata_ndarray_element<std::uint8_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
// BJData limits a char to 0..127 (the intersection of the int8 and uint8 ranges)
|
// BJData limits a char to 0..127 (the intersection of the int8 and uint8 ranges)
|
||||||
ok = bjdata_ndarray_value_in_range<std::int8_t>(el) && bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
ok = bjdata_ndarray_value_in_range<std::int8_t>(el) && bjdata_ndarray_value_in_range<std::uint8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
ok = write_bjdata_ndarray_element<std::int8_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int8_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
ok = write_bjdata_ndarray_element<std::uint16_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint16_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
ok = write_bjdata_ndarray_element<std::int16_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int16_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
ok = write_bjdata_ndarray_element<std::uint32_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint32_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
ok = write_bjdata_ndarray_element<std::int32_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int32_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
ok = write_bjdata_ndarray_element<std::uint64_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::uint64_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
ok = write_bjdata_ndarray_element<std::int64_t>(el, dry_run);
|
ok = bjdata_ndarray_value_in_range<std::int64_t>(el);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
ok = write_bjdata_ndarray_float_element(el, dry_run);
|
ok = bjdata_ndarray_float_in_range(el);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
default:
|
default:
|
||||||
// 'D' (double) already spans the full range of number_float_t
|
// 'D' (double) already spans the full range of number_float_t
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
write_number(el.template get<double>(), true);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@@ -32369,7 +32322,7 @@ class binary_writer
|
|||||||
const auto dim = el.template get<std::uint64_t>();
|
const auto dim = el.template get<std::uint64_t>();
|
||||||
if (!value_in_range_of<std::size_t>(dim))
|
if (!value_in_range_of<std::size_t>(dim))
|
||||||
{
|
{
|
||||||
return true;
|
return true; // LCOV_EXCL_LINE (size_t is narrower than 64 bits)
|
||||||
}
|
}
|
||||||
const auto dim_size = static_cast<std::size_t>(dim);
|
const auto dim_size = static_cast<std::size_t>(dim);
|
||||||
|
|
||||||
@@ -32419,7 +32372,7 @@ class binary_writer
|
|||||||
// wrap (integers) or overflow to infinity (the "single" precision
|
// wrap (integers) or overflow to infinity (the "single" precision
|
||||||
// float) instead of being reported, so such an object falls back to
|
// float) instead of being reported, so such an object falls back to
|
||||||
// a plain object encoding as well
|
// a plain object encoding as well
|
||||||
if (!write_bjdata_ndarray_elements(array_data, dtype, true))
|
if (!bjdata_ndarray_elements_in_range(array_data, dtype))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -32431,7 +32384,7 @@ class binary_writer
|
|||||||
|
|
||||||
write_ubjson(array_size, use_count, use_type, true, true, bjdata_version);
|
write_ubjson(array_size, use_count, use_type, true, true, bjdata_version);
|
||||||
|
|
||||||
write_bjdata_ndarray_elements(array_data, dtype, false);
|
write_bjdata_ndarray_values(array_data, dtype);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32757,8 +32710,8 @@ class binary_writer
|
|||||||
run are encoded into space reserved from the sink, as in
|
run are encoded into space reserved from the sink, as in
|
||||||
@ref write_array_elements; an integer that BON8 cannot write (an unsigned
|
@ref write_array_elements; an integer that BON8 cannot write (an unsigned
|
||||||
one above the int64 range, or one of a number type wider than 64 bits) throws
|
one above the int64 range, or one of a number type wider than 64 bits) throws
|
||||||
from write_bon8_value, like any other value that is not a number. Kept out
|
out_of_range.407, as write_bon8_value does. Kept out of line, like
|
||||||
of line, like @ref write_cbor_array.
|
@ref write_cbor_array.
|
||||||
*/
|
*/
|
||||||
template<typename ArrayType>
|
template<typename ArrayType>
|
||||||
JSON_HEDLEY_NEVER_INLINE
|
JSON_HEDLEY_NEVER_INLINE
|
||||||
@@ -32808,10 +32761,10 @@ class binary_writer
|
|||||||
string_open = false;
|
string_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unencodable)
|
if (JSON_HEDLEY_UNLIKELY(unencodable))
|
||||||
{
|
{
|
||||||
write_bon8_value(*it, string_open, depth + 1);
|
// an integer beyond the int64 range, as write_bon8_value would report it
|
||||||
++it;
|
throw_integer_out_of_range(*it, input_format_t::bon8, "int64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32846,14 +32799,13 @@ class binary_writer
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
if (JSON_HEDLEY_LIKELY(integer_fits<std::int64_t>(value.m_data.m_value.number_integer)))
|
if (JSON_HEDLEY_UNLIKELY(!integer_fits<std::int64_t>(value.m_data.m_value.number_integer)))
|
||||||
{
|
{
|
||||||
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_integer));
|
// beyond 64 bits (number types wider than that)
|
||||||
string_open = false;
|
throw_integer_out_of_range(value, input_format_t::bon8, "int64");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// beyond 64 bits (number types wider than that): throws
|
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_integer));
|
||||||
write_bon8_value(value, string_open, depth + 1);
|
string_open = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
@@ -32862,14 +32814,13 @@ class binary_writer
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
if (JSON_HEDLEY_LIKELY(integer_fits_max<std::int64_t>(value.m_data.m_value.number_unsigned)))
|
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::int64_t>(value.m_data.m_value.number_unsigned)))
|
||||||
{
|
{
|
||||||
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_unsigned));
|
// too large for BON8
|
||||||
string_open = false;
|
throw_integer_out_of_range(value, input_format_t::bon8, "int64");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// too large for BON8: throws
|
write_bon8_integer(static_cast<std::int64_t>(value.m_data.m_value.number_unsigned));
|
||||||
write_bon8_value(value, string_open, depth + 1);
|
string_open = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::object:
|
case value_t::object:
|
||||||
@@ -36326,7 +36277,7 @@ class serializer
|
|||||||
// character
|
// character
|
||||||
if (EnsureAscii)
|
if (EnsureAscii)
|
||||||
{
|
{
|
||||||
JSON_ASSERT(codepoint >= 0x7F);
|
JSON_ASSERT(codepoint == 0x7F);
|
||||||
if (error_handler == error_handler_t::keep)
|
if (error_handler == error_handler_t::keep)
|
||||||
{
|
{
|
||||||
// this character was buffered as raw bytes below
|
// this character was buffered as raw bytes below
|
||||||
@@ -36337,21 +36288,13 @@ class serializer
|
|||||||
// character instead
|
// character instead
|
||||||
bytes = bytes_after_last_accept;
|
bytes = bytes_after_last_accept;
|
||||||
}
|
}
|
||||||
if (codepoint <= 0xFFFF)
|
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
||||||
{
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(codepoint));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)));
|
|
||||||
write_u_escape(bytes, static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// copy byte to buffer (all previous bytes of the
|
// copy byte to buffer (all previous bytes of the
|
||||||
// sequence have been copied in the default case below)
|
// sequence have been copied in the default case below)
|
||||||
string_buffer[bytes++] = s[i];
|
string_buffer[bytes++] = s[i]; // LCOV_EXCL_LINE (well-formed sequences are copied in runs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve_string_buffer(bytes);
|
reserve_string_buffer(bytes);
|
||||||
@@ -38192,7 +38135,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
|
result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||||
result["compiler"] = {{"family", "gcc"}, {"version", detail::concat<string_t>(
|
result["compiler"] = {{"family", "gcc"}, {"version", detail::concat<string_t>(
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC__)), '.',
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC__)), '.', // LCOV_EXCL_LINE
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_MINOR__)), '.',
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_MINOR__)), '.',
|
||||||
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_PATCHLEVEL__)))
|
detail::to_string<string_t>(static_cast<std::size_t>(__GNUC_PATCHLEVEL__)))
|
||||||
}
|
}
|
||||||
@@ -38464,14 +38407,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
case value_t::binary:
|
case value_t::binary:
|
||||||
binary = create<binary_t>();
|
binary = create<binary_t>();
|
||||||
break;
|
break;
|
||||||
case value_t::null:
|
case value_t::null: // LCOV_EXCL_LINE
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38826,14 +38769,14 @@ public:
|
|||||||
destroy_container(t);
|
destroy_container(t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null: // LCOV_EXCL_LINE
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
case value_t::number_integer:
|
case value_t::number_integer:
|
||||||
case value_t::number_unsigned:
|
case value_t::number_unsigned:
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -39006,9 +38949,9 @@ public:
|
|||||||
return is_array() ? array_capacity() : object_capacity();
|
return is_array() ? array_capacity() : object_capacity();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static constexpr std::size_t container_capacity() noexcept
|
static constexpr std::size_t container_capacity() noexcept // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
return detail::unknown_size();
|
return detail::unknown_size(); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -39194,7 +39137,7 @@ public:
|
|||||||
/// into this switch is worth a few percent when copying a value made
|
/// into this switch is worth a few percent when copying a value made
|
||||||
/// mostly of numbers
|
/// mostly of numbers
|
||||||
JSON_HEDLEY_ALWAYS_INLINE
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
static void copy_leaf_value(const basic_json& src, basic_json& dst)
|
static void copy_leaf_value(const basic_json& src, basic_json& dst) // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
switch (src.m_data.m_type)
|
switch (src.m_data.m_type)
|
||||||
{
|
{
|
||||||
@@ -43346,7 +43289,7 @@ public:
|
|||||||
/// their inlined code at each call site small. Binary values are
|
/// their inlined code at each call site small. Binary values are
|
||||||
/// rare and left to equal_general().
|
/// rare and left to equal_general().
|
||||||
JSON_HEDLEY_ALWAYS_INLINE
|
JSON_HEDLEY_ALWAYS_INLINE
|
||||||
static int equal_leaf(const_reference lhs, const_reference rhs) noexcept
|
static int equal_leaf(const_reference lhs, const_reference rhs) noexcept // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
JSON_HEDLEY_DIAGNOSTIC_PUSH
|
||||||
@@ -44655,7 +44598,7 @@ public:
|
|||||||
basic_json result(value_t::object);
|
basic_json result(value_t::object);
|
||||||
json_pointer::flatten("", *this, result);
|
json_pointer::flatten("", *this, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief unflatten a previously flattened JSON value
|
/// @brief unflatten a previously flattened JSON value
|
||||||
/// @sa https://json.nlohmann.me/api/basic_json/unflatten/
|
/// @sa https://json.nlohmann.me/api/basic_json/unflatten/
|
||||||
@@ -45368,7 +45311,7 @@ public:
|
|||||||
result.append(path.data(), path.size());
|
result.append(path.data(), path.size());
|
||||||
diff_append_key(result, key);
|
diff_append_key(result, key);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief the path of the element @a index of the value at @a path
|
/// @brief the path of the element @a index of the value at @a path
|
||||||
static string_t diff_index_path(const string_t& path, const std::size_t index)
|
static string_t diff_index_path(const string_t& path, const std::size_t index)
|
||||||
@@ -45378,7 +45321,7 @@ public:
|
|||||||
result.append(path.data(), path.size());
|
result.append(path.data(), path.size());
|
||||||
diff_append_index(result, index);
|
diff_append_index(result, index);
|
||||||
return result;
|
return result;
|
||||||
}
|
} // LCOV_EXCL_LINE (exception cleanup only)
|
||||||
|
|
||||||
/// @brief append the "remove" operations for the elements of array
|
/// @brief append the "remove" operations for the elements of array
|
||||||
/// @a source from @a index on, and the "add" operations for the
|
/// @a source from @a index on, and the "add" operations for the
|
||||||
@@ -45538,7 +45481,7 @@ public:
|
|||||||
// operations
|
// operations
|
||||||
if (source == target)
|
if (source == target)
|
||||||
{
|
{
|
||||||
return false;
|
return false; // LCOV_EXCL_LINE (equal objects with the same members in the same order return early)
|
||||||
}
|
}
|
||||||
|
|
||||||
// slow path: the common keys are in a different relative
|
// slow path: the common keys are in a different relative
|
||||||
|
|||||||
Generated
+24
-52
@@ -3580,28 +3580,19 @@ class view_side
|
|||||||
return string_view_t(m_view.m_doc->str(*m_view.m_node), m_view.m_node->len);
|
return string_view_t(m_view.m_doc->str(*m_view.m_node), m_view.m_node->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// a number, boolean, or null as a basic_json value (no allocation)
|
/// a number as a basic_json value (no allocation); only called for numbers
|
||||||
BasicJsonType scalar() const
|
BasicJsonType scalar() const
|
||||||
{
|
{
|
||||||
switch (m_view.type())
|
const value_t t = m_view.type();
|
||||||
|
if (t == value_t::number_integer)
|
||||||
{
|
{
|
||||||
case value_t::number_integer:
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_integer_t>());
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_integer_t>());
|
|
||||||
case value_t::number_unsigned:
|
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_unsigned_t>());
|
|
||||||
case value_t::number_float:
|
|
||||||
return BasicJsonType(m_view.template get<typename BasicJsonType::number_float_t>());
|
|
||||||
case value_t::boolean:
|
|
||||||
return BasicJsonType(m_view.template get<bool>());
|
|
||||||
case value_t::null:
|
|
||||||
case value_t::object:
|
|
||||||
case value_t::array:
|
|
||||||
case value_t::string:
|
|
||||||
case value_t::binary:
|
|
||||||
case value_t::discarded:
|
|
||||||
default:
|
|
||||||
return BasicJsonType(nullptr);
|
|
||||||
}
|
}
|
||||||
|
if (t == value_t::number_unsigned)
|
||||||
|
{
|
||||||
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_unsigned_t>());
|
||||||
|
}
|
||||||
|
return BasicJsonType(m_view.template get<typename BasicJsonType::number_float_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// start at the first element of this array
|
/// start at the first element of this array
|
||||||
@@ -4478,14 +4469,9 @@ struct position_source
|
|||||||
return token{end - start};
|
return token{end - start};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the range [first, last), or none if either is npos
|
/// the range [first, last)
|
||||||
void set(std::size_t first, std::size_t last) noexcept
|
void set(std::size_t first, std::size_t last) noexcept
|
||||||
{
|
{
|
||||||
if (first == std::string::npos || last == std::string::npos)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
start = first;
|
start = first;
|
||||||
end = last;
|
end = last;
|
||||||
}
|
}
|
||||||
@@ -4604,11 +4590,11 @@ struct position_source
|
|||||||
first = n.off;
|
first = n.off;
|
||||||
last = n.off + 4u;
|
last = n.off + 4u;
|
||||||
break;
|
break;
|
||||||
case node_kind::object:
|
case node_kind::object: // LCOV_EXCL_LINE
|
||||||
case node_kind::array:
|
case node_kind::array:
|
||||||
case node_kind::link:
|
case node_kind::link:
|
||||||
default:
|
default:
|
||||||
break;
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
// (a crafted image can point past the text)
|
// (a crafted image can point past the text)
|
||||||
if (last == std::string::npos || last > d.size)
|
if (last == std::string::npos || last > d.size)
|
||||||
@@ -5262,10 +5248,12 @@ struct throwing_sax
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LCOV_EXCL_START (throw_parse_failure parses JSON only)
|
||||||
bool binary(binary_t& /*unused*/)
|
bool binary(binary_t& /*unused*/)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
bool start_object(std::size_t /*unused*/)
|
bool start_object(std::size_t /*unused*/)
|
||||||
{
|
{
|
||||||
@@ -5573,7 +5561,7 @@ inline node* find_parent(const document_data& d, const node* target)
|
|||||||
}
|
}
|
||||||
if (target == lo)
|
if (target == lo)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr; // LCOV_EXCL_LINE (the root, or a new value's root, which is linked)
|
||||||
}
|
}
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -6194,11 +6182,11 @@ NLOHMANN_VIEW_NOINLINE inline void check_utf8_scan(const unsigned char* p, std::
|
|||||||
}
|
}
|
||||||
if (*q >= 0x80)
|
if (*q >= 0x80)
|
||||||
{
|
{
|
||||||
check_utf8_bytewise(p, n, static_cast<std::size_t>(q - p));
|
break; // ill-formed UTF-8: reported below
|
||||||
return; // not reached: the scan stopped at ill-formed UTF-8
|
|
||||||
}
|
}
|
||||||
++q; // a quote, backslash, or control character
|
++q; // a quote, backslash, or control character
|
||||||
}
|
}
|
||||||
|
check_utf8_bytewise(p, n, static_cast<std::size_t>(q - p));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void check_utf8(const char* s, std::size_t n)
|
inline void check_utf8(const char* s, std::size_t n)
|
||||||
@@ -9853,20 +9841,10 @@ class view_serializer
|
|||||||
/// a float node as dump() writes it
|
/// a float node as dump() writes it
|
||||||
void write_float_node(const node& n)
|
void write_float_node(const node& n)
|
||||||
{
|
{
|
||||||
write_float_node(n, fast_double {});
|
// (only for types other than double: doubles go through write_double_ahead())
|
||||||
}
|
|
||||||
|
|
||||||
void write_float_node(const node& n, std::false_type /*other*/)
|
|
||||||
{
|
|
||||||
write_float(float_value<number_float_t>(m_doc, n));
|
write_float(float_value<number_float_t>(m_doc, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_float_node(const node& n, std::true_type /*double*/)
|
|
||||||
{
|
|
||||||
m_out.reserve(64);
|
|
||||||
m_out.set_cursor(write_double_at(m_out.cursor(), n));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief (doubles) the float at n as dump() writes it, at w (64 bytes of room)
|
@brief (doubles) the float at n as dump() writes it, at w (64 bytes of room)
|
||||||
|
|
||||||
@@ -9961,7 +9939,7 @@ class view_serializer
|
|||||||
{
|
{
|
||||||
const string_t dumped = BasicJsonType(string_t(reinterpret_cast<const char*>(s), n)).dump(); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
const string_t dumped = BasicJsonType(string_t(reinterpret_cast<const char*>(s), n)).dump(); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||||
static_cast<void>(dumped);
|
static_cast<void>(dumped);
|
||||||
}
|
} // LCOV_EXCL_LINE (dump() throws: the callers pass only ill-formed UTF-8)
|
||||||
|
|
||||||
template<bool EnsureAscii>
|
template<bool EnsureAscii>
|
||||||
void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len)
|
void write_codepoint(std::uint32_t codepoint, const unsigned char* bytes, std::size_t len)
|
||||||
@@ -9994,15 +9972,7 @@ class view_serializer
|
|||||||
}
|
}
|
||||||
if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F))
|
if (codepoint <= 0x1F || (EnsureAscii && codepoint >= 0x7F))
|
||||||
{
|
{
|
||||||
if (codepoint <= 0xFFFF)
|
write_u_escape(codepoint); // (a single byte: the only caller passes s[i])
|
||||||
{
|
|
||||||
write_u_escape(codepoint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_u_escape(0xD7C0u + (codepoint >> 10u));
|
|
||||||
write_u_escape(0xDC00u + (codepoint & 0x3FFu));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_out.put(reinterpret_cast<const char*>(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs)
|
m_out.put(reinterpret_cast<const char*>(bytes), len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) LCOV_EXCL_LINE (printable characters are copied in runs)
|
||||||
@@ -11799,9 +11769,11 @@ class basic_json_document
|
|||||||
{
|
{
|
||||||
// (as before: the library's adapter decides what a null stream yields)
|
// (as before: the library's adapter decides what a null stream yields)
|
||||||
detail::view::append_adapter(buf, detail::input_adapter(file));
|
detail::view::append_adapter(buf, detail::input_adapter(file));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
detail::view::append_file(buf, file);
|
else
|
||||||
|
{
|
||||||
|
detail::view::append_file(buf, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user