Skip to content

Commit

Permalink
Fix pugixml float parsing local dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
gvollant committed Mar 2, 2022
1 parent 2cf4d3f commit 882c3bd
Showing 1 changed file with 147 additions and 17 deletions.
164 changes: 147 additions & 17 deletions OpenXLSX/external/pugixml/pugixml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,7 @@
#include <assert.h>
#include <limits.h>

#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 <charconv>
#endif

#ifdef PUGIXML_WCHAR_MODE
# include <wchar.h>
Expand Down Expand Up @@ -188,6 +181,147 @@ namespace pugi
# include <stdint.h>
#endif



// code from https://github.com/michael-hartmann/parsefloat
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

#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)
Expand Down Expand Up @@ -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
Expand All @@ -4615,9 +4747,8 @@ class xml_buffered_writer
#ifdef PUGIXML_WCHAR_MODE
return static_cast<float>(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<float>(result_double);
#else
return static_cast<float>(strtod(value, 0));
Expand Down Expand Up @@ -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<float>(result_double);
#else
return strtod(string, 0);
Expand Down

0 comments on commit 882c3bd

Please sign in to comment.