mirror of
https://github.com/eledio-devices/thirdparty-ArduinoJson.git
synced 2025-11-01 08:48:30 +01:00
Added custom implementation of strtod() (issue #453)
This commit is contained in:
21
include/ArduinoJson/Polyfills/ctype.hpp
Normal file
21
include/ArduinoJson/Polyfills/ctype.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// 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 {
|
||||
|
||||
inline bool isdigit(char c) {
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
inline bool issign(char c) {
|
||||
return '-' == c || c == '+';
|
||||
}
|
||||
}
|
||||
}
|
||||
40
include/ArduinoJson/Polyfills/isFloat.hpp
Normal file
40
include/ArduinoJson/Polyfills/isFloat.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./ctype.hpp"
|
||||
#include "./math.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
|
||||
inline bool isFloat(const char* s) {
|
||||
if (!strcmp(s, "NaN")) return true;
|
||||
if (issign(*s)) s++;
|
||||
if (!strcmp(s, "Infinity")) return true;
|
||||
|
||||
while (isdigit(*s)) s++;
|
||||
|
||||
bool has_dot = *s == '.';
|
||||
if (has_dot) {
|
||||
s++;
|
||||
while (isdigit(*s)) s++;
|
||||
}
|
||||
|
||||
bool has_exponent = *s == 'e' || *s == 'E';
|
||||
if (has_exponent) {
|
||||
s++;
|
||||
if (issign(*s)) s++;
|
||||
if (!isdigit(*s)) return false;
|
||||
while (isdigit(*s)) s++;
|
||||
}
|
||||
|
||||
return (has_dot || has_exponent) && *s == '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// If Visual Studo
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#include <float.h>
|
||||
#include <limits>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
@@ -23,6 +24,16 @@ template <typename T>
|
||||
bool isInfinity(T x) {
|
||||
return !_finite(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T nan() {
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T inf() {
|
||||
return std::numeric_limits<T>::infinity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +112,16 @@ inline bool isInfinity<float>(float x) {
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
T nan() {
|
||||
return static_cast<T>(NAN);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T inf() {
|
||||
return static_cast<T>(INFINITY);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
87
include/ArduinoJson/Polyfills/parseFloat.hpp
Normal file
87
include/ArduinoJson/Polyfills/parseFloat.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../TypeTraits/FloatTraits.hpp"
|
||||
#include "./ctype.hpp"
|
||||
#include "./math.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
|
||||
template <typename T>
|
||||
inline T parseFloat(const char* s) {
|
||||
typedef TypeTraits::FloatTraits<T> traits;
|
||||
typedef typename traits::mantissa_type mantissa_t;
|
||||
typedef typename traits::exponent_type exponent_t;
|
||||
|
||||
bool negative_result = false;
|
||||
switch (*s) {
|
||||
case '-':
|
||||
negative_result = true;
|
||||
case '+':
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == 'n' || *s == 'N') return traits::nan();
|
||||
if (*s == 'i' || *s == 'I')
|
||||
return negative_result ? -traits::inf() : traits::inf();
|
||||
|
||||
mantissa_t mantissa = 0;
|
||||
exponent_t exponent_offset = 0;
|
||||
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10)
|
||||
mantissa = mantissa * 10 + (*s - '0');
|
||||
else
|
||||
exponent_offset++;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10) {
|
||||
mantissa = mantissa * 10 + (*s - '0');
|
||||
exponent_offset--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
bool negative_exponent = false;
|
||||
if (*s == '-') {
|
||||
negative_exponent = true;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
exponent = exponent * 10 + (*s - '0');
|
||||
if (exponent + exponent_offset > traits::exponent_max) {
|
||||
if (negative_exponent)
|
||||
return negative_result ? -0.0f : 0.0f;
|
||||
else
|
||||
return negative_result ? -traits::inf() : traits::inf();
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (negative_exponent) exponent = -exponent;
|
||||
}
|
||||
exponent += exponent_offset;
|
||||
|
||||
T result = traits::make_float(static_cast<T>(mantissa), exponent);
|
||||
|
||||
return negative_result ? -result : result;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
include/ArduinoJson/Polyfills/parseInteger.hpp
Normal file
56
include/ArduinoJson/Polyfills/parseInteger.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
template <typename T>
|
||||
T parseInteger(const char *s);
|
||||
|
||||
template <>
|
||||
inline long parseInteger<long>(const char *s) {
|
||||
return ::strtol(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned long parseInteger<unsigned long>(const char *s) {
|
||||
return ::strtoul(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int parseInteger<int>(const char *s) {
|
||||
return ::atoi(s);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
template <>
|
||||
inline long long parseInteger<long long>(const char *s) {
|
||||
return ::strtoll(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned long long parseInteger<unsigned long long>(const char *s) {
|
||||
return ::strtoull(s, NULL, 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_INT64
|
||||
template <>
|
||||
inline __int64 parseInteger<__int64>(const char *s) {
|
||||
return ::_strtoi64(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned __int64 parseInteger<unsigned __int64>(const char *s) {
|
||||
return ::_strtoui64(s, NULL, 10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user