Compare commits

..

9 Commits

Author SHA1 Message Date
Daniel Lemire 980f2ad3af 4.2.4 2025-12-17 20:33:11 -05:00
Daniel Lemire 7ad9fe63a6 fixing issue 2549 (#2567)
* fixing issue 2549

* saving.
2025-12-17 20:32:36 -05:00
Daniel Lemire 7987418b1f adding the official simdjson logo files 2025-12-13 12:14:40 -05:00
Daniel Lemire 5e871f6724 improving slightly the documentation. 2025-12-12 19:04:34 -05:00
Daniel Lemire 5d16fd5f31 4.2.3 2025-12-12 17:51:39 -05:00
Jake S. Del Mastro 4e9ff03af5 Make it possible to provide custom serializers for range types ( (#2550)
If you provide a custom serializer for range types it is currently never used due to the requires clause for string_builder::append with ranges is overly broad
2025-12-12 17:50:52 -05:00
Daniel Lemire aa7489060a Fix typo in bug report template 2025-12-12 15:24:48 -05:00
Daniel Lemire ae32422891 a few additional tests and removing a bad remark in the documentation... 2025-12-03 19:35:18 -05:00
Liqiang TAO 667d0ed3c7 make code branchless (#2546) 2025-11-18 16:57:06 -05:00
32 changed files with 368 additions and 200 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ If we cannot reproduce the issue, then we cannot address it. Note that a stack t
It should be possible to trigger the bug by using solely simdjson with our default build setup. If you can only observe the bug within some specific context, with some other software, please reduce the issue first. It should be possible to trigger the bug by using solely simdjson with our default build setup. If you can only observe the bug within some specific context, with some other software, please reduce the issue first.
**simjson release** **simdjson release**
Unless you plan to contribute to simdjson, you should only work from releases. Please be mindful that our main branch may have additional features, bugs and documentation items. Unless you plan to contribute to simdjson, you should only work from releases. Please be mindful that our main branch may have additional features, bugs and documentation items.
+1 -1
View File
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
project( project(
simdjson simdjson
# The version number is modified by tools/release.py # The version number is modified by tools/release.py
VERSION 4.2.2 VERSION 4.2.4
DESCRIPTION "Parsing gigabytes of JSON per second" DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/" HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C LANGUAGES CXX C
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = "4.2.2" PROJECT_NUMBER = "4.2.4"
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
+1 -6
View File
@@ -8,16 +8,11 @@
* Minifies by first parsing, then minifying. * Minifies by first parsing, then minifying.
*/ */
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
simdjson::padded_string str(reinterpret_cast<const char *>(Data), Size);
auto begin = as_chars(Data);
auto end = begin + Size;
std::string str(begin, end);
simdjson::dom::parser parser; simdjson::dom::parser parser;
simdjson::dom::element elem; simdjson::dom::element elem;
auto error = parser.parse(str).get(elem); auto error = parser.parse(str).get(elem);
if (error) { return 0; } if (error) { return 0; }
std::string minified = simdjson::minify(elem); std::string minified = simdjson::minify(elem);
(void)minified; (void)minified;
return 0; return 0;
Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 136 KiB

+2 -5
View File
@@ -204,10 +204,7 @@ public:
* *
* ### std::string references * ### std::string references
* *
* If you pass a mutable std::string reference (std::string&), the parser will seek to extend * Whenever you pass an std::string reference, the parser may access the bytes beyond the end of
* its capacity to SIMDJSON_PADDING bytes beyond the end of the string.
*
* Whenever you pass an std::string reference, the parser will access the bytes beyond the end of
* the string but before the end of the allocated memory (std::string::capacity()). * the string but before the end of the allocated memory (std::string::capacity()).
* If you are using a sanitizer that checks for reading uninitialized bytes or std::string's * If you are using a sanitizer that checks for reading uninitialized bytes or std::string's
* container-overflow checks, you may encounter sanitizer warnings. * container-overflow checks, you may encounter sanitizer warnings.
@@ -239,7 +236,7 @@ public:
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
simdjson_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) & noexcept; simdjson_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) & noexcept;
simdjson_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) && =delete; simdjson_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) && =delete;
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ /** @overload parse(const std::string &) */
simdjson_inline simdjson_result<element> parse(const std::string &s) & noexcept; simdjson_inline simdjson_result<element> parse(const std::string &s) & noexcept;
simdjson_inline simdjson_result<element> parse(const std::string &s) && =delete; simdjson_inline simdjson_result<element> parse(const std::string &s) && =delete;
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */ /** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
+5 -2
View File
@@ -403,7 +403,9 @@ public:
simdjson_inline simdjson_result<array_iterator> end() & noexcept; simdjson_inline simdjson_result<array_iterator> end() & noexcept;
/** /**
* Look up a field by name on an object (order-sensitive). * Look up a field by name on an object (order-sensitive). By order-sensitive, we mean that
* fields must be accessed in the order they appear in the JSON text (although you can
* skip fields). See find_field_unordered() and operator[] for an order-insensitive version.
* *
* The following code reads z, then y, then x, and thus will not retrieve x or y if fed the * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the
* JSON `{ "x": 1, "y": 2, "z": 3 }`: * JSON `{ "x": 1, "y": 2, "z": 3 }`:
@@ -447,7 +449,8 @@ public:
* missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object
* in question is large. The fact that the extra code is there also bumps the executable size. * in question is large. The fact that the extra code is there also bumps the executable size.
* *
* It is the default, however, because it would be highly surprising (and hard to debug) if the * We default operator[] on find_field_unordered() for convenience.
* It is the default because it would be highly surprising (and hard to debug) if the
* default behavior failed to look up a field just because it was in the wrong order--and many * default behavior failed to look up a field just because it was in the wrong order--and many
* APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order.
* *
@@ -519,8 +519,8 @@ simdjson_inline void string_builder::append(const T &opt) {
template <typename T> template <typename T>
requires(require_custom_serialization<T>) requires(require_custom_serialization<T>)
simdjson_inline void string_builder::append(const T &val) { simdjson_inline void string_builder::append(T &&val) {
serialize(*this, val); serialize(*this, std::forward<T>(val));
} }
template <typename T> template <typename T>
@@ -534,7 +534,7 @@ simdjson_inline void string_builder::append(const T &value) {
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
// Support for range-based appending (std::ranges::view, etc.) // Support for range-based appending (std::ranges::view, etc.)
template <std::ranges::range R> template <std::ranges::range R>
requires(!std::is_convertible<R, std::string_view>::value) requires(!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(range); auto end = std::ranges::end(range);
@@ -24,9 +24,8 @@ struct has_custom_serialization : std::false_type {};
inline constexpr struct serialize_tag { inline constexpr struct serialize_tag {
template <typename T> template <typename T>
requires custom_deserializable<T> constexpr void operator()(SIMDJSON_IMPLEMENTATION::builder::string_builder& b, T&& obj) const{
constexpr void operator()(SIMDJSON_IMPLEMENTATION::builder::string_builder& b, T& obj) const{ return tag_invoke(*this, b, std::forward<T>(obj));
return tag_invoke(*this, b, obj);
} }
@@ -165,7 +164,7 @@ public:
template <typename T> template <typename T>
requires(require_custom_serialization<T>) requires(require_custom_serialization<T>)
simdjson_inline void append(const T &val); simdjson_inline void append(T &&val);
// Support for string-like types // Support for string-like types
template <typename T> template <typename T>
@@ -176,7 +175,7 @@ public:
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
// Support for range-based appending (std::ranges::view, etc.) // Support for range-based appending (std::ranges::view, etc.)
template <std::ranges::range R> template <std::ranges::range R>
requires (!std::is_convertible<R, std::string_view>::value) requires (!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
simdjson_inline void append(const R &range) noexcept; simdjson_inline void append(const R &range) noexcept;
#endif #endif
/** /**
@@ -301,4 +300,4 @@ simdjson_warn_unused simdjson_error to_json(const Z &z, std::string &s, size_t i
} // namespace simdjson } // namespace simdjson
#endif // SIMDJSON_GENERIC_STRING_BUILDER_H #endif // SIMDJSON_GENERIC_STRING_BUILDER_H
+5 -2
View File
@@ -30,7 +30,9 @@ public:
simdjson_inline simdjson_result<object_iterator> begin() noexcept; simdjson_inline simdjson_result<object_iterator> begin() noexcept;
simdjson_inline simdjson_result<object_iterator> end() noexcept; simdjson_inline simdjson_result<object_iterator> end() noexcept;
/** /**
* Look up a field by name on an object (order-sensitive). * Look up a field by name on an object (order-sensitive). By order-sensitive, we mean that
* fields must be accessed in the order they appear in the JSON text (although you can
* skip fields). See find_field_unordered() and operator[] for an order-insensitive version.
* *
* The following code reads z, then y, then x, and thus will not retrieve x or y if fed the * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the
* JSON `{ "x": 1, "y": 2, "z": 3 }`: * JSON `{ "x": 1, "y": 2, "z": 3 }`:
@@ -78,7 +80,8 @@ public:
* missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object
* in question is large. The fact that the extra code is there also bumps the executable size. * in question is large. The fact that the extra code is there also bumps the executable size.
* *
* It is the default, however, because it would be highly surprising (and hard to debug) if the * We default operator[] on find_field_unordered() for convenience.
* It is the default because it would be highly surprising (and hard to debug) if the
* default behavior failed to look up a field just because it was in the wrong order--and many * default behavior failed to look up a field just because it was in the wrong order--and many
* APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order.
* *
+10 -4
View File
@@ -395,7 +395,9 @@ public:
*/ */
simdjson_inline simdjson_result<value> at(size_t index) noexcept; simdjson_inline simdjson_result<value> at(size_t index) noexcept;
/** /**
* Look up a field by name on an object (order-sensitive). * Look up a field by name on an object (order-sensitive). By order-sensitive, we mean that
* fields must be accessed in the order they appear in the JSON text (although you can
* skip fields). See find_field_unordered() and operator[] for an order-insensitive version.
* *
* The following code reads z, then y, then x, and thus will not retrieve x or y if fed the * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the
* JSON `{ "x": 1, "y": 2, "z": 3 }`: * JSON `{ "x": 1, "y": 2, "z": 3 }`:
@@ -429,7 +431,8 @@ public:
* missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object
* in question is large. The fact that the extra code is there also bumps the executable size. * in question is large. The fact that the extra code is there also bumps the executable size.
* *
* It is the default, however, because it would be highly surprising (and hard to debug) if the * We default operator[] on find_field_unordered() for convenience.
* It is the default because it would be highly surprising (and hard to debug) if the
* default behavior failed to look up a field just because it was in the wrong order--and many * default behavior failed to look up a field just because it was in the wrong order--and many
* APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order.
* *
@@ -776,7 +779,9 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept; simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;
/** /**
* Look up a field by name on an object (order-sensitive). * Look up a field by name on an object (order-sensitive). By order-sensitive, we mean that
* fields must be accessed in the order they appear in the JSON text (although you can
* skip fields). See find_field_unordered() and operator[] for an order-insensitive version.
* *
* The following code reads z, then y, then x, and thus will not retrieve x or y if fed the * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the
* JSON `{ "x": 1, "y": 2, "z": 3 }`: * JSON `{ "x": 1, "y": 2, "z": 3 }`:
@@ -808,7 +813,8 @@ public:
* missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object
* in question is large. The fact that the extra code is there also bumps the executable size. * in question is large. The fact that the extra code is there also bumps the executable size.
* *
* It is the default, however, because it would be highly surprising (and hard to debug) if the * We default operator[] on find_field_unordered() for convenience.
* It is the defaul because it would be highly surprising (and hard to debug) if the
* default behavior failed to look up a field just because it was in the wrong order--and many * default behavior failed to look up a field just because it was in the wrong order--and many
* APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order. * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order.
* *
+2 -2
View File
@@ -4,7 +4,7 @@
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION "4.2.2" #define SIMDJSON_VERSION "4.2.4"
namespace simdjson { namespace simdjson {
enum { enum {
@@ -19,7 +19,7 @@ enum {
/** /**
* The revision (major.minor.REVISION) of simdjson being used. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 2 SIMDJSON_VERSION_REVISION = 4
}; };
} // namespace simdjson } // namespace simdjson
+5 -11
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2025-11-11 14:17:08 -0500. version 4.2.2 Do not edit! */ /* auto-generated on 2025-12-17 20:32:36 -0500. version 4.2.4 Do not edit! */
/* including simdjson.cpp: */ /* including simdjson.cpp: */
/* begin file simdjson.cpp */ /* begin file simdjson.cpp */
#define SIMDJSON_SRC_SIMDJSON_CPP #define SIMDJSON_SRC_SIMDJSON_CPP
@@ -4047,20 +4047,14 @@ void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) {
*/ */
inline char *append_exponent(char *buf, int e) { inline char *append_exponent(char *buf, int e) {
if (e < 0) { bool isNegative = e < 0;
e = -e; e = isNegative ? -e : e;
*buf++ = '-'; *buf++ = isNegative ? '-' : '+';
} else {
*buf++ = '+';
}
auto k = static_cast<std::uint32_t>(e); auto k = static_cast<std::uint32_t>(e);
if (k < 10) { if (k < 100) {
// Always print at least two digits in the exponent. // Always print at least two digits in the exponent.
// This is for compatibility with printf("%g"). // This is for compatibility with printf("%g").
*buf++ = '0';
*buf++ = static_cast<char>('0' + k);
} else if (k < 100) {
*buf++ = static_cast<char>('0' + k / 10); *buf++ = static_cast<char>('0' + k / 10);
k %= 10; k %= 10;
*buf++ = static_cast<char>('0' + k); *buf++ = static_cast<char>('0' + k);
+221 -136
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+4 -10
View File
@@ -814,20 +814,14 @@ void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value) {
*/ */
inline char *append_exponent(char *buf, int e) { inline char *append_exponent(char *buf, int e) {
if (e < 0) { bool isNegative = e < 0;
e = -e; e = isNegative ? -e : e;
*buf++ = '-'; *buf++ = isNegative ? '-' : '+';
} else {
*buf++ = '+';
}
auto k = static_cast<std::uint32_t>(e); auto k = static_cast<std::uint32_t>(e);
if (k < 10) { if (k < 100) {
// Always print at least two digits in the exponent. // Always print at least two digits in the exponent.
// This is for compatibility with printf("%g"). // This is for compatibility with printf("%g").
*buf++ = '0';
*buf++ = static_cast<char>('0' + k);
} else if (k < 100) {
*buf++ = static_cast<char>('0' + k / 10); *buf++ = static_cast<char>('0' + k / 10);
k %= 10; k %= 10;
*buf++ = static_cast<char>('0' + k); *buf++ = static_cast<char>('0' + k);
+43 -1
View File
@@ -17,6 +17,33 @@ struct Car {
std::vector<double> tire_pressure; std::vector<double> tire_pressure;
}; // Car }; // Car
#if SIMDJSON_SUPPORTS_CONCEPTS
struct Car2549 {
std::string make;
std::string model;
int64_t year;
std::vector<float> tire_pressure;
};
namespace simdjson {
// we intentionally pass by non-const reference to car.
template <typename builder_type>
void tag_invoke(serialize_tag, builder_type& builder, Car2549& car) {
builder.start_object();
builder.append_key_value("make", car.make);
builder.append_comma();
builder.append_key_value("model", car.model);
builder.append_comma();
builder.append_key_value("year", car.year);
builder.append_comma();
builder.append_key_value("tire_pressure", car.tire_pressure);
builder.end_object();
}
} // namespace simdjson
static_assert(simdjson::require_custom_serialization<Car2549>);
#endif
namespace builder_tests { namespace builder_tests {
using namespace std; using namespace std;
@@ -428,6 +455,21 @@ bool car_test() {
TEST_SUCCEED(); TEST_SUCCEED();
} }
#if SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_CONCEPTS
bool issue2549() {
TEST_START();
simdjson::builder::string_builder sb;
Car2549 c = { "Toyota", "Corolla", 2017, {1.0f,2.0f,3.0f} };
sb.start_object();
sb.append_key_value("car", c);
sb.end_object();
std::string_view p;
auto result = sb.view().get(p);
ASSERT_SUCCESS(result);
ASSERT_EQUAL(p, "{\"car\":{\"make\":\"Toyota\",\"model\":\"Corolla\",\"year\":2017,\"tire_pressure\":[1.0,2.0,3.0]}}");
TEST_SUCCEED();
}
bool car_test_template() { bool car_test_template() {
TEST_START(); TEST_START();
simdjson::builder::string_builder sb; simdjson::builder::string_builder sb;
@@ -616,7 +658,7 @@ bool run() {
#endif #endif
#endif #endif
#if SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_CONCEPTS
car_test_template() && serialize_optional() && issue2549() && car_test_template() && serialize_optional() &&
#endif #endif
append_char() && append_integer() && append_float() && append_null() && append_char() && append_integer() && append_float() && append_null() &&
clear() && escape_and_append() && escape_and_append_with_quotes() && clear() && escape_and_append() && escape_and_append_with_quotes() &&
@@ -661,6 +661,8 @@ bool test_array_of_objects_with_concept() {
TEST_SUCCEED(); TEST_SUCCEED();
} }
#if defined(__cpp_pp_embed) && __cpp_pp_embed >= 202502L
#define TEST_EMBED_SUPPORTED
/** /**
* Test: #embed support for external JSON files (C++26) * Test: #embed support for external JSON files (C++26)
*/ */
@@ -688,6 +690,7 @@ bool test_embed_twitter_json() {
TEST_SUCCEED(); TEST_SUCCEED();
} }
#endif // defined(__cpp_pp_embed) && __cpp_pp_embed >= 202502L
bool run() { bool run() {
return test_basic_object() && return test_basic_object() &&
@@ -713,8 +716,11 @@ bool run() {
test_user_config_example() && test_user_config_example() &&
test_nested_servers_example() && test_nested_servers_example() &&
test_top_level_array_example() && test_top_level_array_example() &&
test_array_of_objects_with_concept() && test_array_of_objects_with_concept()
test_embed_twitter_json(); #ifdef TEST_EMBED_SUPPORTED
&& test_embed_twitter_json()
#endif
;
} }
} // namespace compile_time_json_tests } // namespace compile_time_json_tests
+48 -7
View File
@@ -1951,18 +1951,39 @@ namespace minify_tests {
return false; return false;
} }
bool test_empty() {
std::cout << "Running " << __func__ << std::endl;
const std::string_view test = "";
const std::string_view minified = "";
return check_minification(test.data(), test.size(), minified.data(), minified.size());
}
bool test_two_quotes() {
std::cout << "Running " << __func__ << std::endl;
const std::string_view test = R"("")";
const std::string_view minified = R"("")";
return check_minification(test.data(), test.size(), minified.data(), minified.size());
}
bool test_number() {
std::cout << "Running " << __func__ << std::endl;
const std::string_view test = R"(3.41)";
const std::string_view minified = R"(3.41)";
return check_minification(test.data(), test.size(), minified.data(), minified.size());
}
bool test_minify() { bool test_minify() {
std::cout << "Running " << __func__ << std::endl; std::cout << "Running " << __func__ << std::endl;
const std::string test = R"({ "foo" : 1, "bar" : [ 1, 2, 0.11111111111111113 ], "baz": { "a": 3.1415926535897936, "b": 2, "c": 3.141592653589794 } })"; const std::string_view test = R"({ "foo" : 1, "bar" : [ 1, 2, 0.11111111111111113 ], "baz": { "a": 3.1415926535897936, "b": 2, "c": 3.141592653589794 } })";
const std::string minified(R"({"foo":1,"bar":[1,2,0.11111111111111113],"baz":{"a":3.1415926535897936,"b":2,"c":3.141592653589794}})"); const std::string_view minified = R"({"foo":1,"bar":[1,2,0.11111111111111113],"baz":{"a":3.1415926535897936,"b":2,"c":3.141592653589794}})";
return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size()); return check_minification(test.data(), test.size(), minified.data(), minified.size());
} }
bool test_minify_array() { bool test_minify_array() {
std::cout << "Running " << __func__ << std::endl; std::cout << "Running " << __func__ << std::endl;
std::string test("[ 1, 2, 3]"); std::string_view test("[ 1, 2, 3]");
std::string minified("[1,2,3]"); std::string_view minified("[1,2,3]");
return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size()); return check_minification(test.data(), test.size(), minified.data(), minified.size());
} }
bool test_minify_object() { bool test_minify_object() {
@@ -1972,7 +1993,10 @@ namespace minify_tests {
return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size()); return check_minification(test.c_str(), test.size(), minified.c_str(), minified.size());
} }
bool run() { bool run() {
return test_various_lengths2() && return test_two_quotes() &&
test_empty() &&
test_number() &&
test_various_lengths2() &&
test_various_lengths() && test_various_lengths() &&
test_single_quote() && test_single_quote() &&
test_minify() && test_minify() &&
@@ -2194,6 +2218,22 @@ namespace format_tests {
s << minify(object); s << minify(object);
return assert_minified(s, R"({"a":3.1415926535897936,"b":2,"c":3.141592653589794})"); return assert_minified(s, R"({"a":3.1415926535897936,"b":2,"c":3.141592653589794})");
} }
bool print_minify_empty_string() {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
dom::element e = parser.parse(R"("")"_padded);
ostringstream s;
s << minify(e);
return assert_minified(s, R"("")");
}
bool print_minify_number_string() {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
dom::element e = parser.parse("3.41"_padded);
ostringstream s;
s << minify(e);
return assert_minified(s, "3.41");
}
#endif // SIMDJSON_EXCEPTIONS #endif // SIMDJSON_EXCEPTIONS
bool run() { bool run() {
@@ -2209,6 +2249,7 @@ namespace format_tests {
print_element_exception() && print_minify_element_exception() && print_element_exception() && print_minify_element_exception() &&
print_array_exception() && print_minify_array_exception() && print_array_exception() && print_minify_array_exception() &&
print_object_exception() && print_minify_object_exception() && print_object_exception() && print_minify_object_exception() &&
print_minify_empty_string() && print_minify_number_string() &&
#endif #endif
true; true;
} }