forked from bblanchon/ArduinoJson
@ -4,7 +4,8 @@ ArduinoJson: change log
|
|||||||
HEAD
|
HEAD
|
||||||
----
|
----
|
||||||
|
|
||||||
* Fix `unsigned long` printed as `signed long` (issue #170)
|
* Added custom implementation of `ftoa` (issues #266, #267, #269 and #270)
|
||||||
|
* Fixed `unsigned long` printed as `signed long` (issue #170)
|
||||||
|
|
||||||
v5.2.0
|
v5.2.0
|
||||||
------
|
------
|
||||||
|
@ -9,19 +9,8 @@
|
|||||||
|
|
||||||
#ifndef ARDUINO
|
#ifndef ARDUINO
|
||||||
|
|
||||||
#include "../Internals/JsonFloat.hpp"
|
|
||||||
#include "../Internals/JsonInteger.hpp"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
|
||||||
// snprintf has been added in Visual Studio 2015
|
|
||||||
#define ARDUINOJSON_SNPRINTF _snprintf
|
|
||||||
#else
|
|
||||||
#define ARDUINOJSON_SNPRINTF snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This class reproduces Arduino's Print class
|
// This class reproduces Arduino's Print class
|
||||||
class Print {
|
class Print {
|
||||||
@ -38,41 +27,6 @@ class Print {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(ArduinoJson::Internals::JsonFloat value, int digits = 2) {
|
|
||||||
char tmp[32];
|
|
||||||
|
|
||||||
// https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/sam/cores/arduino/Print.cpp#L220
|
|
||||||
bool isBigDouble = value > 4294967040.0 || value < -4294967040.0;
|
|
||||||
|
|
||||||
if (isBigDouble) {
|
|
||||||
// Arduino's implementation prints "ovf"
|
|
||||||
// We prefer using the scientific notation, since we have sprintf
|
|
||||||
ARDUINOJSON_SNPRINTF(tmp, sizeof(tmp), "%g", value);
|
|
||||||
} else {
|
|
||||||
// Here we have the exact same output as Arduino's implementation
|
|
||||||
ARDUINOJSON_SNPRINTF(tmp, sizeof(tmp), "%.*f", digits, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return print(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t print(ArduinoJson::Internals::JsonUInt value) {
|
|
||||||
char buffer[22];
|
|
||||||
|
|
||||||
uint8_t i = 0;
|
|
||||||
do {
|
|
||||||
buffer[i++] = static_cast<char>(value % 10 + '0');
|
|
||||||
value /= 10;
|
|
||||||
} while (value);
|
|
||||||
|
|
||||||
size_t n = 0;
|
|
||||||
while (i > 0) {
|
|
||||||
n += write(buffer[--i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t println() { return write('\r') + write('\n'); }
|
size_t println() { return write('\r') + write('\n'); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Arduino/Print.hpp"
|
#include "../Arduino/Print.hpp"
|
||||||
|
#include "../Polyfills/isNaN.hpp"
|
||||||
|
#include "../Polyfills/isInfinity.hpp"
|
||||||
|
#include "../Polyfills/normalize.hpp"
|
||||||
#include "Encoding.hpp"
|
#include "Encoding.hpp"
|
||||||
#include "ForceInline.hpp"
|
#include "ForceInline.hpp"
|
||||||
#include "JsonFloat.hpp"
|
#include "JsonFloat.hpp"
|
||||||
@ -63,10 +66,70 @@ class JsonWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInteger(JsonUInt value) { _length += _sink.print(value); }
|
void writeFloat(JsonFloat value, int digits = 2) {
|
||||||
|
if (Polyfills::isNaN(value)) return writeRaw("NaN");
|
||||||
|
|
||||||
void writeFloat(JsonFloat value, uint8_t decimals) {
|
if (value < 0.0) {
|
||||||
_length += _sink.print(value, decimals);
|
writeRaw('-');
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
|
||||||
|
|
||||||
|
short powersOf10;
|
||||||
|
if (value > 1000 || value < 0.001) {
|
||||||
|
powersOf10 = Polyfills::normalize(value);
|
||||||
|
} else {
|
||||||
|
powersOf10 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
|
JsonFloat rounding = 0.5;
|
||||||
|
for (uint8_t i = 0; i < digits; ++i) rounding /= 10.0;
|
||||||
|
|
||||||
|
value += rounding;
|
||||||
|
|
||||||
|
// Extract the integer part of the value and print it
|
||||||
|
JsonUInt int_part = static_cast<JsonUInt>(value);
|
||||||
|
JsonFloat remainder = value - static_cast<JsonFloat>(int_part);
|
||||||
|
writeInteger(int_part);
|
||||||
|
|
||||||
|
// Print the decimal point, but only if there are digits beyond
|
||||||
|
if (digits > 0) {
|
||||||
|
writeRaw('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract digits from the remainder one at a time
|
||||||
|
while (digits-- > 0) {
|
||||||
|
remainder *= 10.0;
|
||||||
|
JsonUInt toPrint = JsonUInt(remainder);
|
||||||
|
writeInteger(JsonUInt(remainder));
|
||||||
|
remainder -= static_cast<JsonFloat>(toPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (powersOf10 < 0) {
|
||||||
|
writeRaw("e-");
|
||||||
|
writeInteger(-powersOf10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (powersOf10 > 0) {
|
||||||
|
writeRaw('e');
|
||||||
|
writeInteger(powersOf10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeInteger(JsonUInt value) {
|
||||||
|
char buffer[22];
|
||||||
|
|
||||||
|
uint8_t i = 0;
|
||||||
|
do {
|
||||||
|
buffer[i++] = static_cast<char>(value % 10 + '0');
|
||||||
|
value /= 10;
|
||||||
|
} while (value);
|
||||||
|
|
||||||
|
while (i > 0) {
|
||||||
|
writeRaw(buffer[--i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRaw(const char *s) { _length += _sink.print(s); }
|
void writeRaw(const char *s) { _length += _sink.print(s); }
|
||||||
|
@ -29,6 +29,11 @@ inline long parse<long>(const char *s) {
|
|||||||
return strtol(s, NULL, 10);
|
return strtol(s, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline unsigned long parse<unsigned long>(const char *s) {
|
||||||
|
return strtoul(s, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline int parse<int>(const char *s) {
|
inline int parse<int>(const char *s) {
|
||||||
return atoi(s);
|
return atoi(s);
|
||||||
@ -39,6 +44,11 @@ template <>
|
|||||||
inline long long parse<long long>(const char *s) {
|
inline long long parse<long long>(const char *s) {
|
||||||
return strtoll(s, NULL, 10);
|
return strtoll(s, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline unsigned long long parse<unsigned long long>(const char *s) {
|
||||||
|
return strtoull(s, NULL, 10);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_INT64
|
#if ARDUINOJSON_USE_INT64
|
||||||
@ -46,6 +56,11 @@ template <>
|
|||||||
inline __int64 parse<__int64>(const char *s) {
|
inline __int64 parse<__int64>(const char *s) {
|
||||||
return _strtoi64(s, NULL, 10);
|
return _strtoi64(s, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline unsigned __int64 parse<unsigned __int64>(const char *s) {
|
||||||
|
return _strtoui64(s, NULL, 10);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,23 +63,33 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a JsonVariant containing an integer value.
|
// Create a JsonVariant containing an integer value.
|
||||||
// JsonVariant(short)
|
// JsonVariant(signed short)
|
||||||
// JsonVariant(int)
|
// JsonVariant(signed int)
|
||||||
// JsonVariant(long)
|
// JsonVariant(signed long)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE JsonVariant(
|
FORCE_INLINE JsonVariant(
|
||||||
T value,
|
T value, typename TypeTraits::EnableIf<
|
||||||
typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value>::type * =
|
TypeTraits::IsSignedIntegral<T>::value>::type * = 0) {
|
||||||
0) {
|
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
_type = JSON_POSITIVE_INTEGER;
|
_type = JSON_POSITIVE_INTEGER;
|
||||||
_content.asInteger = static_cast<JsonInteger>(value);
|
_content.asInteger = static_cast<JsonUInt>(value);
|
||||||
} else {
|
} else {
|
||||||
_type = JSON_NEGATIVE_INTEGER;
|
_type = JSON_NEGATIVE_INTEGER;
|
||||||
_content.asInteger = static_cast<JsonInteger>(-value);
|
_content.asInteger = static_cast<JsonUInt>(-value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// JsonVariant(unsigned short)
|
||||||
|
// JsonVariant(unsigned int)
|
||||||
|
// JsonVariant(unsigned long)
|
||||||
|
template <typename T>
|
||||||
|
FORCE_INLINE JsonVariant(
|
||||||
|
T value, typename TypeTraits::EnableIf<
|
||||||
|
TypeTraits::IsUnsignedIntegral<T>::value>::type * = 0) {
|
||||||
|
using namespace Internals;
|
||||||
|
_type = JSON_POSITIVE_INTEGER;
|
||||||
|
_content.asInteger = static_cast<JsonUInt>(value);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a JsonVariant containing a string.
|
// Create a JsonVariant containing a string.
|
||||||
FORCE_INLINE JsonVariant(const char *value);
|
FORCE_INLINE JsonVariant(const char *value);
|
||||||
@ -95,15 +105,26 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
|||||||
|
|
||||||
// Get the variant as the specified type.
|
// Get the variant as the specified type.
|
||||||
//
|
//
|
||||||
// short as<short>() const;
|
// short as<signed short>() const;
|
||||||
// int as<int>() const;
|
// int as<signed int>() const;
|
||||||
// long as<long>() const;
|
// long as<signed long>() const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, T>::type
|
const typename TypeTraits::EnableIf<TypeTraits::IsSignedIntegral<T>::value,
|
||||||
|
T>::type
|
||||||
as() const {
|
as() const {
|
||||||
return static_cast<T>(asInteger());
|
return static_cast<T>(asInteger());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
// short as<unsigned short>() const;
|
||||||
|
// int as<unsigned int>() const;
|
||||||
|
// long as<unsigned long>() const;
|
||||||
|
template <typename T>
|
||||||
|
const typename TypeTraits::EnableIf<TypeTraits::IsUnsignedIntegral<T>::value,
|
||||||
|
T>::type
|
||||||
|
as() const {
|
||||||
|
return static_cast<T>(asUnsignedInteger());
|
||||||
|
}
|
||||||
|
//
|
||||||
// double as<double>() const;
|
// double as<double>() const;
|
||||||
// float as<float>() const;
|
// float as<float>() const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -247,9 +268,16 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
|||||||
JsonObject &asObject() const;
|
JsonObject &asObject() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// It's not allowed to store a char
|
||||||
|
template <typename T>
|
||||||
|
FORCE_INLINE JsonVariant(T value,
|
||||||
|
typename TypeTraits::EnableIf<
|
||||||
|
TypeTraits::IsSame<T, char>::value>::type * = 0);
|
||||||
|
|
||||||
String toString() const;
|
String toString() const;
|
||||||
Internals::JsonFloat asFloat() const;
|
Internals::JsonFloat asFloat() const;
|
||||||
Internals::JsonInteger asInteger() const;
|
Internals::JsonInteger asInteger() const;
|
||||||
|
Internals::JsonUInt asUnsignedInteger() const;
|
||||||
bool isBoolean() const;
|
bool isBoolean() const;
|
||||||
bool isFloat() const;
|
bool isFloat() const;
|
||||||
bool isInteger() const;
|
bool isInteger() const;
|
||||||
|
@ -55,7 +55,7 @@ inline Internals::JsonInteger JsonVariant::asInteger() const {
|
|||||||
case JSON_BOOLEAN:
|
case JSON_BOOLEAN:
|
||||||
return _content.asInteger;
|
return _content.asInteger;
|
||||||
case JSON_NEGATIVE_INTEGER:
|
case JSON_NEGATIVE_INTEGER:
|
||||||
return -_content.asInteger;
|
return -static_cast<Internals::JsonInteger>(_content.asInteger);
|
||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
case JSON_UNPARSED:
|
case JSON_UNPARSED:
|
||||||
if (!_content.asString) return 0;
|
if (!_content.asString) return 0;
|
||||||
@ -66,6 +66,25 @@ inline Internals::JsonInteger JsonVariant::asInteger() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
|
||||||
|
using namespace Internals;
|
||||||
|
switch (_type) {
|
||||||
|
case JSON_UNDEFINED:
|
||||||
|
return 0;
|
||||||
|
case JSON_POSITIVE_INTEGER:
|
||||||
|
case JSON_BOOLEAN:
|
||||||
|
case JSON_NEGATIVE_INTEGER:
|
||||||
|
return _content.asInteger;
|
||||||
|
case JSON_STRING:
|
||||||
|
case JSON_UNPARSED:
|
||||||
|
if (!_content.asString) return 0;
|
||||||
|
if (!strcmp("true", _content.asString)) return 1;
|
||||||
|
return parse<Internals::JsonUInt>(_content.asString);
|
||||||
|
default:
|
||||||
|
return static_cast<Internals::JsonUInt>(_content.asFloat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
|
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
|
||||||
return source.printTo(os);
|
return source.printTo(os);
|
||||||
|
45
include/ArduinoJson/Polyfills/isInfinity.hpp
Normal file
45
include/ArduinoJson/Polyfills/isInfinity.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2016
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
// If you like this project, please add a star!
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// If Visual Studo <= 2012
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||||
|
#include <float.h>
|
||||||
|
#else
|
||||||
|
#include <math.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Polyfills {
|
||||||
|
|
||||||
|
// If Visual Studo <= 2012
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||||
|
template <typename T>
|
||||||
|
bool isInfinity(T x) {
|
||||||
|
return !_finite(x);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
bool isInfinity(T x) {
|
||||||
|
return isinf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
template <>
|
||||||
|
inline bool isInfinity<double>(double x) {
|
||||||
|
return isinfl(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool isInfinity<float>(float x) {
|
||||||
|
return isinff(x);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
46
include/ArduinoJson/Polyfills/isNaN.hpp
Normal file
46
include/ArduinoJson/Polyfills/isNaN.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2016
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
// If you like this project, please add a star!
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// If Visual Studo <= 2012
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||||
|
#include <float.h>
|
||||||
|
#else
|
||||||
|
#include <math.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Polyfills {
|
||||||
|
|
||||||
|
// If Visual Studo <= 2012
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||||
|
template <typename T>
|
||||||
|
bool isNaN(T x) {
|
||||||
|
return _isnan(x) != 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
bool isNaN(T x) {
|
||||||
|
return isnan(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
template <>
|
||||||
|
inline bool isNaN<double>(double x) {
|
||||||
|
return isnanl(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool isNaN<float>(float x) {
|
||||||
|
return isnanf(x);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
47
include/ArduinoJson/Polyfills/normalize.hpp
Normal file
47
include/ArduinoJson/Polyfills/normalize.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2016
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
// If you like this project, please add a star!
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Polyfills {
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
|
// on embedded platform, favor code size over speed
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
short normalize(T& value) {
|
||||||
|
short powersOf10 = 0;
|
||||||
|
while (value && value < 1) {
|
||||||
|
powersOf10--;
|
||||||
|
value *= 10;
|
||||||
|
}
|
||||||
|
while (value > 10) {
|
||||||
|
powersOf10++;
|
||||||
|
value /= 10;
|
||||||
|
}
|
||||||
|
return powersOf10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// on non-embedded platform, favor speed over code size
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
short normalize(T& value) {
|
||||||
|
if (value == 0.0) return 0;
|
||||||
|
|
||||||
|
short powersOf10 = static_cast<short>(floor(log10(value)));
|
||||||
|
value /= pow(T(10), powersOf10);
|
||||||
|
|
||||||
|
return powersOf10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
#include "../Configuration.hpp"
|
#include "../Configuration.hpp"
|
||||||
#include "IsSame.hpp"
|
#include "IsSame.hpp"
|
||||||
|
#include "IsSignedIntegral.hpp"
|
||||||
#include <stdint.h>
|
#include "IsUnsignedIntegral.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace TypeTraits {
|
namespace TypeTraits {
|
||||||
@ -18,23 +18,8 @@ namespace TypeTraits {
|
|||||||
// A meta-function that returns true if T is an integral type.
|
// A meta-function that returns true if T is an integral type.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct IsIntegral {
|
struct IsIntegral {
|
||||||
static const bool value = TypeTraits::IsSame<T, signed char>::value ||
|
static const bool value = TypeTraits::IsSignedIntegral<T>::value ||
|
||||||
TypeTraits::IsSame<T, unsigned char>::value ||
|
TypeTraits::IsUnsignedIntegral<T>::value ||
|
||||||
TypeTraits::IsSame<T, signed short>::value ||
|
|
||||||
TypeTraits::IsSame<T, unsigned short>::value ||
|
|
||||||
TypeTraits::IsSame<T, signed int>::value ||
|
|
||||||
TypeTraits::IsSame<T, unsigned int>::value ||
|
|
||||||
TypeTraits::IsSame<T, signed long>::value ||
|
|
||||||
TypeTraits::IsSame<T, unsigned long>::value ||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
TypeTraits::IsSame<T, long long>::value ||
|
|
||||||
TypeTraits::IsSame<T, unsigned long long>::value ||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_INT64
|
|
||||||
TypeTraits::IsSame<T, __int64>::value ||
|
|
||||||
TypeTraits::IsSame<T, unsigned __int64>::value ||
|
|
||||||
#endif
|
|
||||||
TypeTraits::IsSame<T, char>::value;
|
TypeTraits::IsSame<T, char>::value;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
33
include/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
Normal file
33
include/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2016
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
// If you like this project, please add a star!
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Configuration.hpp"
|
||||||
|
#include "IsSame.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace TypeTraits {
|
||||||
|
|
||||||
|
// A meta-function that returns true if T is an integral type.
|
||||||
|
template <typename T>
|
||||||
|
struct IsSignedIntegral {
|
||||||
|
static const bool value = TypeTraits::IsSame<T, signed char>::value ||
|
||||||
|
TypeTraits::IsSame<T, signed short>::value ||
|
||||||
|
TypeTraits::IsSame<T, signed int>::value ||
|
||||||
|
TypeTraits::IsSame<T, signed long>::value ||
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
TypeTraits::IsSame<T, signed long long>::value ||
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_INT64
|
||||||
|
TypeTraits::IsSame<T, signed __int64>::value ||
|
||||||
|
#endif
|
||||||
|
false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
33
include/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
Normal file
33
include/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2016
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
// If you like this project, please add a star!
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Configuration.hpp"
|
||||||
|
#include "IsSame.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace TypeTraits {
|
||||||
|
|
||||||
|
// A meta-function that returns true if T is an integral type.
|
||||||
|
template <typename T>
|
||||||
|
struct IsUnsignedIntegral {
|
||||||
|
static const bool value = TypeTraits::IsSame<T, unsigned char>::value ||
|
||||||
|
TypeTraits::IsSame<T, unsigned short>::value ||
|
||||||
|
TypeTraits::IsSame<T, unsigned int>::value ||
|
||||||
|
TypeTraits::IsSame<T, unsigned long>::value ||
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
TypeTraits::IsSame<T, unsigned long long>::value ||
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_INT64
|
||||||
|
TypeTraits::IsSame<T, unsigned __int64>::value ||
|
||||||
|
#endif
|
||||||
|
false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ if [[ $(uname) == MINGW* ]]
|
|||||||
then
|
then
|
||||||
build-env "Make" "MinGW Makefiles"
|
build-env "Make" "MinGW Makefiles"
|
||||||
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||||
build-env "VisualStudio" "Visual Studio 12 2013"
|
build-env "VisualStudio" "Visual Studio 14 2015"
|
||||||
else
|
else
|
||||||
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||||
build-env "Make" "Unix Makefiles"
|
build-env "Make" "Unix Makefiles"
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2016
|
|
||||||
// MIT License
|
|
||||||
//
|
|
||||||
// Arduino JSON library
|
|
||||||
// https://github.com/bblanchon/ArduinoJson
|
|
||||||
// If you like this project, please add a star!
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
class Issue67 : public testing::Test {
|
|
||||||
public:
|
|
||||||
void whenInputIs(double value) { _variant = value; }
|
|
||||||
|
|
||||||
void outputMustBe(const char* expected) {
|
|
||||||
char buffer[1024];
|
|
||||||
_variant.printTo(buffer, sizeof(buffer));
|
|
||||||
ASSERT_STREQ(expected, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
JsonVariant _variant;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(Issue67, BigPositiveDouble) {
|
|
||||||
whenInputIs(1e100);
|
|
||||||
outputMustBe("1e+100");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(Issue67, BigNegativeDouble) {
|
|
||||||
whenInputIs(-1e100);
|
|
||||||
outputMustBe("-1e+100");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(Issue67, Zero) {
|
|
||||||
whenInputIs(0.0);
|
|
||||||
outputMustBe("0.00");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(Issue67, SmallPositiveDouble) {
|
|
||||||
whenInputIs(111.111);
|
|
||||||
outputMustBe("111.11");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(Issue67, SmallNegativeDouble) {
|
|
||||||
whenInputIs(-111.111);
|
|
||||||
outputMustBe("-111.11");
|
|
||||||
}
|
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
class JsonVariant_PrintTo_Tests : public testing::Test {
|
class JsonVariant_PrintTo_Tests : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
@ -15,8 +16,8 @@ class JsonVariant_PrintTo_Tests : public testing::Test {
|
|||||||
void outputMustBe(const char *expected) {
|
void outputMustBe(const char *expected) {
|
||||||
char buffer[256] = "";
|
char buffer[256] = "";
|
||||||
size_t n = variant.printTo(buffer, sizeof(buffer));
|
size_t n = variant.printTo(buffer, sizeof(buffer));
|
||||||
EXPECT_STREQ(expected, buffer);
|
ASSERT_STREQ(expected, buffer);
|
||||||
EXPECT_EQ(strlen(expected), n);
|
ASSERT_EQ(strlen(expected), n);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,6 +48,46 @@ TEST_F(JsonVariant_PrintTo_Tests, DoubleFourDigits) {
|
|||||||
outputMustBe("3.1416");
|
outputMustBe("3.1416");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, Infinity) {
|
||||||
|
variant = std::numeric_limits<double>::infinity();
|
||||||
|
outputMustBe("Infinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, MinusInfinity) {
|
||||||
|
variant = -std::numeric_limits<double>::infinity();
|
||||||
|
outputMustBe("-Infinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, SignalingNaN) {
|
||||||
|
variant = std::numeric_limits<double>::signaling_NaN();
|
||||||
|
outputMustBe("NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, QuietNaN) {
|
||||||
|
variant = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
outputMustBe("NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, VeryBigPositiveDouble) {
|
||||||
|
variant = JsonVariant(3.14159265358979323846e42, 4);
|
||||||
|
outputMustBe("3.1416e42");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, VeryBigNegativeDouble) {
|
||||||
|
variant = JsonVariant(-3.14159265358979323846e42, 4);
|
||||||
|
outputMustBe("-3.1416e42");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, VerySmallPositiveDouble) {
|
||||||
|
variant = JsonVariant(3.14159265358979323846e-42, 4);
|
||||||
|
outputMustBe("3.1416e-42");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonVariant_PrintTo_Tests, VerySmallNegativeDouble) {
|
||||||
|
variant = JsonVariant(-3.14159265358979323846e-42, 4);
|
||||||
|
outputMustBe("-3.1416e-42");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_PrintTo_Tests, Integer) {
|
TEST_F(JsonVariant_PrintTo_Tests, Integer) {
|
||||||
variant = 42;
|
variant = 42;
|
||||||
outputMustBe("42");
|
outputMustBe("42");
|
||||||
@ -62,11 +103,6 @@ TEST_F(JsonVariant_PrintTo_Tests, UnsignedLong) {
|
|||||||
outputMustBe("4294967295");
|
outputMustBe("4294967295");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_PrintTo_Tests, Char) {
|
|
||||||
variant = '*';
|
|
||||||
outputMustBe("42");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(JsonVariant_PrintTo_Tests, True) {
|
TEST_F(JsonVariant_PrintTo_Tests, True) {
|
||||||
variant = true;
|
variant = true;
|
||||||
outputMustBe("true");
|
outputMustBe("true");
|
||||||
|
Reference in New Issue
Block a user