forked from bblanchon/ArduinoJson
Break build if using 64-bit integers with ARDUINOJSON_USE_LONG_LONG==0
This commit is contained in:
@ -11,6 +11,7 @@ HEAD
|
||||
* Added support for `enum`s in `as<T>()` and `is<T>()` (issue #1256)
|
||||
* Added `JsonVariant` as an input type for `deserializeXxx()`
|
||||
For example, you can do: `deserializeJson(doc2, doc1["payload"])`
|
||||
* Break the build if using 64-bit integers with ARDUINOJSON_USE_LONG_LONG==0
|
||||
|
||||
v6.15.1 (2020-04-08)
|
||||
-------
|
||||
|
@ -28,3 +28,11 @@ build_should_fail(Issue978)
|
||||
|
||||
add_executable(Issue1189 Issue1189.cpp)
|
||||
build_should_fail(Issue1189)
|
||||
|
||||
add_executable(read_long_long read_long_long.cpp)
|
||||
set_property(TARGET read_long_long PROPERTY CXX_STANDARD 11)
|
||||
build_should_fail(read_long_long)
|
||||
|
||||
add_executable(write_long_long write_long_long.cpp)
|
||||
set_property(TARGET write_long_long PROPERTY CXX_STANDARD 11)
|
||||
build_should_fail(write_long_long)
|
||||
|
20
extras/tests/FailingBuilds/read_long_long.cpp
Normal file
20
extras/tests/FailingBuilds/read_long_long.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#if defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ >= 8
|
||||
#error This test requires sizeof(long) < 8
|
||||
#endif
|
||||
|
||||
#if !ARDUINOJSON_HAS_LONG_LONG
|
||||
#error This test requires C++11
|
||||
#endif
|
||||
|
||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(long long)
|
||||
int main() {
|
||||
DynamicJsonDocument doc(1024);
|
||||
doc["dummy"].as<long long>();
|
||||
}
|
19
extras/tests/FailingBuilds/write_long_long.cpp
Normal file
19
extras/tests/FailingBuilds/write_long_long.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#if defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ >= 8
|
||||
#error This test requires sizeof(long) < 8
|
||||
#endif
|
||||
|
||||
#if !ARDUINOJSON_HAS_LONG_LONG
|
||||
#error This test requires C++11
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
DynamicJsonDocument doc(1024);
|
||||
doc["dummy"] = static_cast<long long>(42);
|
||||
}
|
@ -3,28 +3,14 @@
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
template <size_t size_of_long>
|
||||
std::string get_expected_json();
|
||||
|
||||
template <>
|
||||
std::string get_expected_json<4>() {
|
||||
return "{\"A\":2899336981,\"B\":2129924785}";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string get_expected_json<8>() {
|
||||
return "{\"A\":123456789123456789,\"B\":987654321987654321}";
|
||||
}
|
||||
|
||||
TEST_CASE("ARDUINOJSON_USE_LONG_LONG == 0") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonObject root = doc.to<JsonObject>();
|
||||
|
||||
root["A"] = 123456789123456789;
|
||||
root["B"] = 987654321987654321;
|
||||
doc["A"] = 42;
|
||||
doc["B"] = 84;
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
|
||||
REQUIRE(json == get_expected_json<sizeof(long)>());
|
||||
REQUIRE(json == "{\"A\":42,\"B\":84}");
|
||||
}
|
||||
|
@ -18,4 +18,15 @@ typedef uint64_t UInt;
|
||||
typedef long Integer;
|
||||
typedef unsigned long UInt;
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if ARDUINOJSON_HAS_LONG_LONG && !ARDUINOJSON_USE_LONG_LONG
|
||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
||||
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
|
||||
"To use 64-bit integers with ArduinoJson, you must set " \
|
||||
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
|
||||
"https://arduinojson.org/v6/api/config/use_long_long/");
|
||||
#else
|
||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
|
||||
#endif
|
||||
|
@ -55,6 +55,7 @@ struct VariantConstAs<ArrayRef> {
|
||||
template <typename T>
|
||||
inline typename enable_if<is_integral<T>::value, T>::type variantAs(
|
||||
const VariantData* data) {
|
||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||
return data != 0 ? data->asIntegral<T>() : T(0);
|
||||
}
|
||||
|
||||
|
@ -258,6 +258,11 @@ class VariantData {
|
||||
}
|
||||
}
|
||||
|
||||
void setUnsignedInteger(UInt value) {
|
||||
setType(VALUE_IS_POSITIVE_INTEGER);
|
||||
_content.asInteger = static_cast<UInt>(value);
|
||||
}
|
||||
|
||||
void setPositiveInteger(UInt value) {
|
||||
setType(VALUE_IS_POSITIVE_INTEGER);
|
||||
_content.asInteger = value;
|
||||
@ -301,11 +306,6 @@ class VariantData {
|
||||
return setOwnedString(value.save(pool));
|
||||
}
|
||||
|
||||
void setUnsignedInteger(UInt value) {
|
||||
setType(VALUE_IS_POSITIVE_INTEGER);
|
||||
_content.asInteger = static_cast<UInt>(value);
|
||||
}
|
||||
|
||||
CollectionData &toArray() {
|
||||
setType(VALUE_IS_ARRAY);
|
||||
_content.asCollection.clear();
|
||||
|
@ -105,14 +105,6 @@ inline bool variantSetOwnedRaw(VariantData *var, SerializedValue<T> value,
|
||||
return var != 0 && var->setOwnedRaw(value, pool);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool variantSetSignedInteger(VariantData *var, T value) {
|
||||
if (!var)
|
||||
return false;
|
||||
var->setSignedInteger(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool variantSetLinkedString(VariantData *var, const char *value) {
|
||||
if (!var)
|
||||
return false;
|
||||
@ -138,10 +130,12 @@ inline bool variantSetOwnedString(VariantData *var, T value, MemoryPool *pool) {
|
||||
return var != 0 && var->setOwnedString(value, pool);
|
||||
}
|
||||
|
||||
inline bool variantSetUnsignedInteger(VariantData *var, UInt value) {
|
||||
template <typename T>
|
||||
inline bool variantSetInteger(VariantData *var, T value) {
|
||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||
if (!var)
|
||||
return false;
|
||||
var->setUnsignedInteger(value);
|
||||
var->setInteger(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -178,22 +178,13 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
// set(signed int)
|
||||
// set(signed long)
|
||||
// set(signed char)
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
T value,
|
||||
typename enable_if<is_integral<T>::value && is_signed<T>::value>::type * =
|
||||
0) const {
|
||||
return variantSetSignedInteger(_data, value);
|
||||
}
|
||||
|
||||
// set(unsigned short)
|
||||
// set(unsigned int)
|
||||
// set(unsigned long)
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
T value, typename enable_if<is_integral<T>::value &&
|
||||
is_unsigned<T>::value>::type * = 0) const {
|
||||
return variantSetUnsignedInteger(_data, static_cast<UInt>(value));
|
||||
T value, typename enable_if<is_integral<T>::value>::type * = 0) const {
|
||||
return variantSetInteger<T>(_data, value);
|
||||
}
|
||||
|
||||
// set(SerializedValue<const char *>)
|
||||
@ -248,7 +239,7 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
T value, typename enable_if<is_enum<T>::value>::type * = 0) const {
|
||||
return variantSetSignedInteger(_data, static_cast<Integer>(value));
|
||||
return variantSetInteger(_data, static_cast<Integer>(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
Reference in New Issue
Block a user