webservices: Use sscanf to convert strings to doubles.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8387605959
commit
6d70b1a66e
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -49,6 +50,8 @@ void winsock_init(void)
|
||||||
InitOnceExecuteOnce( &once, winsock_startup, NULL, NULL );
|
InitOnceExecuteOnce( &once, winsock_startup, NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_locale_t c_locale;
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* DllMain (webservices.@)
|
* DllMain (webservices.@)
|
||||||
*/
|
*/
|
||||||
|
@ -59,11 +62,13 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved )
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
webservices_instance = hinst;
|
webservices_instance = hinst;
|
||||||
DisableThreadLibraryCalls( hinst );
|
DisableThreadLibraryCalls( hinst );
|
||||||
|
c_locale = _create_locale( LC_ALL, "C" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
if (reserved) break;
|
||||||
if (winsock_loaded) WSACleanup();
|
if (winsock_loaded) WSACleanup();
|
||||||
|
_free_locale( c_locale );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -3726,15 +3727,13 @@ static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, U
|
||||||
|
|
||||||
static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret )
|
static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret )
|
||||||
{
|
{
|
||||||
|
BOOL found_sign = FALSE, found_exponent = FALSE, found_digit = FALSE, found_decimal = FALSE;
|
||||||
static const unsigned __int64 nan = 0xfff8000000000000;
|
static const unsigned __int64 nan = 0xfff8000000000000;
|
||||||
static const unsigned __int64 inf = 0x7ff0000000000000;
|
static const unsigned __int64 inf = 0x7ff0000000000000;
|
||||||
static const unsigned __int64 inf_min = 0xfff0000000000000;
|
static const unsigned __int64 inf_min = 0xfff0000000000000;
|
||||||
HRESULT hr = WS_E_INVALID_FORMAT;
|
const char *p = (const char *)str;
|
||||||
const unsigned char *p = str, *q;
|
double tmp;
|
||||||
int sign = 1, exp_sign = 1, exp = 0, exp_tmp = 0, neg_exp, i, nb_digits, have_digits;
|
ULONG i;
|
||||||
unsigned __int64 val = 0, tmp;
|
|
||||||
long double exp_val = 1.0, exp_mul = 10.0;
|
|
||||||
unsigned int fpword = _control87( 0, 0 );
|
|
||||||
|
|
||||||
while (len && read_isspace( *p )) { p++; len--; }
|
while (len && read_isspace( *p )) { p++; len--; }
|
||||||
while (len && read_isspace( p[len - 1] )) { len--; }
|
while (len && read_isspace( p[len - 1] )) { len--; }
|
||||||
|
@ -3756,88 +3755,40 @@ static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret )
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = 0.0;
|
for (i = 0; i < len; i++)
|
||||||
if (*p == '-')
|
|
||||||
{
|
{
|
||||||
sign = -1;
|
if (p[i] >= '0' && p[i] <= '9')
|
||||||
p++; len--;
|
|
||||||
}
|
|
||||||
else if (*p == '+') { p++; len--; };
|
|
||||||
if (!len) return S_OK;
|
|
||||||
|
|
||||||
_control87( _MCW_EM | _RC_NEAR | _PC_64, _MCW_EM | _MCW_RC | _MCW_PC );
|
|
||||||
|
|
||||||
q = p;
|
|
||||||
while (len && isdigit( *q )) { q++; len--; }
|
|
||||||
have_digits = nb_digits = q - p;
|
|
||||||
for (i = 0; i < nb_digits; i++)
|
|
||||||
{
|
|
||||||
tmp = val * 10 + p[i] - '0';
|
|
||||||
if (val > MAX_UINT64 / 10 || tmp < val)
|
|
||||||
{
|
{
|
||||||
for (; i < nb_digits; i++) exp++;
|
found_digit = TRUE;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
val = tmp;
|
if (!found_sign && !found_digit && (p[i] == '+' || p[i] == '-'))
|
||||||
}
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
if (*q == '.')
|
|
||||||
{
|
{
|
||||||
p = ++q; len--;
|
found_sign = TRUE;
|
||||||
while (len && isdigit( *q )) { q++; len--; };
|
continue;
|
||||||
have_digits |= nb_digits = q - p;
|
|
||||||
for (i = 0; i < nb_digits; i++)
|
|
||||||
{
|
|
||||||
tmp = val * 10 + p[i] - '0';
|
|
||||||
if (val > MAX_UINT64 / 10 || tmp < val) break;
|
|
||||||
val = tmp;
|
|
||||||
exp--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (len > 1 && tolower(*q) == 'e')
|
if (!found_exponent && found_digit && (p[i] == 'e' || p[i] == 'E'))
|
||||||
{
|
{
|
||||||
if (!have_digits) goto done;
|
found_exponent = found_decimal = TRUE;
|
||||||
p = ++q; len--;
|
found_digit = found_sign = FALSE;
|
||||||
if (*p == '-')
|
continue;
|
||||||
{
|
|
||||||
exp_sign = -1;
|
|
||||||
p++; len--;
|
|
||||||
}
|
|
||||||
else if (*p == '+') { p++; len--; };
|
|
||||||
|
|
||||||
q = p;
|
|
||||||
while (len && isdigit( *q )) { q++; len--; };
|
|
||||||
nb_digits = q - p;
|
|
||||||
if (!nb_digits || len) goto done;
|
|
||||||
for (i = 0; i < nb_digits; i++)
|
|
||||||
{
|
|
||||||
if (exp_tmp > MAX_INT32 / 10 || (exp_tmp = exp_tmp * 10 + p[i] - '0') < 0)
|
|
||||||
exp_tmp = MAX_INT32;
|
|
||||||
}
|
|
||||||
exp_tmp *= exp_sign;
|
|
||||||
|
|
||||||
if (exp < 0 && exp_tmp < 0 && exp + exp_tmp >= 0) exp = MIN_INT32;
|
|
||||||
else if (exp > 0 && exp_tmp > 0 && exp + exp_tmp < 0) exp = MAX_INT32;
|
|
||||||
else exp += exp_tmp;
|
|
||||||
}
|
}
|
||||||
|
if (!found_decimal && p[i] == '.')
|
||||||
|
{
|
||||||
|
found_decimal = TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return WS_E_INVALID_FORMAT;
|
||||||
}
|
}
|
||||||
if (!have_digits || len) goto done;
|
if (!found_digit && !found_exponent)
|
||||||
|
|
||||||
if ((neg_exp = exp < 0)) exp = -exp;
|
|
||||||
for (; exp; exp >>= 1)
|
|
||||||
{
|
{
|
||||||
if (exp & 1) exp_val *= exp_mul;
|
*ret = 0;
|
||||||
exp_mul *= exp_mul;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = sign * (neg_exp ? val / exp_val : val * exp_val);
|
if (_snscanf_l( p, len, "%lf", c_locale, &tmp ) != 1) return WS_E_INVALID_FORMAT;
|
||||||
hr = S_OK;
|
*ret = tmp;
|
||||||
|
return S_OK;
|
||||||
done:
|
|
||||||
_control87( fpword, _MCW_EM | _MCW_RC | _MCW_PC );
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT str_to_float( const unsigned char *str, ULONG len, float *ret )
|
static HRESULT str_to_float( const unsigned char *str, ULONG len, float *ret )
|
||||||
|
|
|
@ -3650,7 +3650,10 @@ static void test_double(void)
|
||||||
{"<t>-0.0</t>", S_OK, 0x8000000000000000},
|
{"<t>-0.0</t>", S_OK, 0x8000000000000000},
|
||||||
{"<t>+0.0</t>", S_OK, 0},
|
{"<t>+0.0</t>", S_OK, 0},
|
||||||
{"<t>-</t>", S_OK, 0},
|
{"<t>-</t>", S_OK, 0},
|
||||||
|
{"<t>-.</t>", S_OK, 0},
|
||||||
{"<t>+</t>", S_OK, 0},
|
{"<t>+</t>", S_OK, 0},
|
||||||
|
{"<t>+.</t>", S_OK, 0},
|
||||||
|
{"<t>.</t>", S_OK, 0},
|
||||||
{"<t>.0</t>", S_OK, 0},
|
{"<t>.0</t>", S_OK, 0},
|
||||||
{"<t>0.</t>", S_OK, 0},
|
{"<t>0.</t>", S_OK, 0},
|
||||||
{"<t>0</t>", S_OK, 0},
|
{"<t>0</t>", S_OK, 0},
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include "winhttp.h"
|
#include "winhttp.h"
|
||||||
|
|
||||||
|
_locale_t c_locale DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#define STREAM_BUFSIZE 4096
|
#define STREAM_BUFSIZE 4096
|
||||||
|
|
||||||
struct xmlbuf
|
struct xmlbuf
|
||||||
|
|
|
@ -191,6 +191,7 @@ int WINAPIV sprintf_s(char*,size_t,const char*,...);
|
||||||
int WINAPIV _scprintf(const char *, ...);
|
int WINAPIV _scprintf(const char *, ...);
|
||||||
int WINAPIV sscanf(const char*,const char*,...);
|
int WINAPIV sscanf(const char*,const char*,...);
|
||||||
int WINAPIV sscanf_s(const char*,const char*,...);
|
int WINAPIV sscanf_s(const char*,const char*,...);
|
||||||
|
int WINAPIV _snscanf_l(const char*,size_t,const char*,_locale_t,...);
|
||||||
FILE* __cdecl tmpfile(void);
|
FILE* __cdecl tmpfile(void);
|
||||||
char* __cdecl tmpnam(char*);
|
char* __cdecl tmpnam(char*);
|
||||||
int __cdecl ungetc(int,FILE*);
|
int __cdecl ungetc(int,FILE*);
|
||||||
|
|
Loading…
Reference in New Issue