diff --git a/OpenXLSX/external/pugixml/pugixml.cpp b/OpenXLSX/external/pugixml/pugixml.cpp index 62b65593..1771e3fe 100644 --- a/OpenXLSX/external/pugixml/pugixml.cpp +++ b/OpenXLSX/external/pugixml/pugixml.cpp @@ -22,14 +22,7 @@ #include #include -#if (!defined(PUGIXML_HAS_CXX17)) && ((__cplusplus >= 201703L) || \ - (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L)) -# define PUGIXML_HAS_CXX17 -#endif -#if defined(PUGIXML_HAS_CXX17) -# include -#endif #ifdef PUGIXML_WCHAR_MODE # include @@ -188,6 +181,147 @@ namespace pugi # include #endif + + +// code from https://github.com/michael-hartmann/parsefloat +#include +#include +#include + +#define USE_STR_TO_DOUBLE 1 + +static double strtodouble(const char *str, int *success) +{ + double intpart = 0, fracpart = 0, exponent = 0; + int sign = +1, len = 0, conversion = 0; + + // skip whitespace + while(isspace(*str)) + str++; + + // check for sign (optional; either + or -) + if(*str == '-') + { + sign = -1; + str++; + } + else if(*str == '+') + str++; + + // check for nan and inf + if(tolower(str[0]) == 'n' && tolower(str[1]) == 'a' && tolower(str[2]) == 'n') + { + if(success != NULL) + *success = 1; + return NAN; + } + if(tolower(str[0]) == 'i' && tolower(str[1]) == 'n' && tolower(str[2]) == 'f') + { + if(success != NULL) + *success = 1; + return sign*INFINITY; + } + + // find number of digits before decimal point + { + const char *p = str; + len = 0; + while(isdigit(*p)) + { + p++; + len++; + } + } + + if(len) + conversion = 1; + + // convert intpart part of decimal point to a float + { + double f = 1; + for(int i = 0; i < len; i++) + { + int v = str[len-1-i] - '0'; + intpart += v*f; + f *= 10; + } + str += len; + } + + // check for decimal point (optional) + if(*str == '.') + { + const char *p = ++str; + + // find number of digits after decimal point + len = 0; + while(isdigit(*p)) + { + p++; + len++; + } + + if(len) + conversion = 1; + + // convert fracpart part of decimal point to a float + double f = 0.1; + for(int i = 0; i < len; i++) + { + int v = str[i] - '0'; + fracpart += v*f; + f *= 0.1; + } + + str = p; + } + + if(conversion && (*str == 'e' || *str == 'E')) + { + int expsign = +1; + const char *p = ++str; + + if(*p == '+') + p++; + else if(*p == '-') + { + expsign = -1; + p++; + } + + str = p; + len = 0; + while(isdigit(*p)) + { + len++; + p++; + } + + int f = 1; + for(int i = 0; i < len; i++) + { + int v = str[len-1-i]-'0'; + exponent += v*f; + f *= 10; + } + + exponent *= expsign; + } + + if(!conversion) + { + if(success != NULL) + *success = 0; + return NAN; + } + + if(success != NULL) + *success = 1; + + return sign*(intpart+fracpart)*pow(10, exponent); +} + + // Memory allocation PUGI__NS_BEGIN PUGI__FN void* default_allocate(size_t size) @@ -4600,10 +4734,8 @@ class xml_buffered_writer #ifdef PUGIXML_WCHAR_MODE return wcstod(value, 0); #else - #if defined(PUGIXML_HAS_CXX17) - double result_double = 0.0; - std::from_chars(value, (value + strlen(value)), result_double); - return result_double; + #if defined(USE_STR_TO_DOUBLE) + double result_double = strtodouble(value, NULL); #else return strtod(value, 0); #endif @@ -4615,9 +4747,8 @@ class xml_buffered_writer #ifdef PUGIXML_WCHAR_MODE return static_cast(wcstod(value, 0)); #else - #if defined(PUGIXML_HAS_CXX17) - double result_double = 0.0; - std::from_chars(value, value + strlen(value), result_double); + #if defined(USE_STR_TO_DOUBLE) + double result_double = strtodouble(value, NULL); return static_cast(result_double); #else return static_cast(strtod(value, 0)); @@ -8436,9 +8567,8 @@ PUGI__FN double convert_string_to_number(const char_t* string) #ifdef PUGIXML_WCHAR_MODE return wcstod(string, 0); #else - #if defined(PUGIXML_HAS_CXX17) - double result_double = 0.0; - std::from_chars(string, string + strlen(string), result_double); + #if defined(USE_STR_TO_DOUBLE) + double result_double = strtodouble(value, NULL); return static_cast(result_double); #else return strtod(string, 0);