From 377aee58ecacc5e0c9a468c0bb45b92589d21a63 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 10 Oct 2017 12:42:03 +0200 Subject: [PATCH] [c] Replaced call to locale dependent strtof with customer float parser. Closes #1009 --- spine-c/spine-c/src/spine/Json.c | 74 ++++++++++++++++++------ spine-c/spine-c/src/spine/SkeletonJson.c | 12 ---- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/spine-c/spine-c/src/spine/Json.c b/spine-c/spine-c/src/spine/Json.c index 6225ff00c..c260bb39f 100644 --- a/spine-c/spine-c/src/spine/Json.c +++ b/spine-c/spine-c/src/spine/Json.c @@ -92,29 +92,65 @@ void Json_dispose (Json *c) { /* Parse the input text to generate a number, and populate the result into item. */ static const char* parse_number (Json *item, const char* num) { - char * endptr; - float n; + double result = 0.0; + int negative = 0; + char* ptr = (char*)num; - /* Using strtod and strtof is slightly more permissive than RFC4627, - * accepting for example hex-encoded floating point, but either - * is often leagues faster than any manual implementation. - * - * We also already know that this starts with [-0-9] from parse_value. - */ -#if __STDC_VERSION__ >= 199901L - n = strtof(num, &endptr); -#else - n = (float)strtod( num, &endptr ); -#endif - /* ignore errno's ERANGE, which returns +/-HUGE_VAL */ - /* n is 0 on any other error */ + if (*ptr == '-') { + negative = -1; + ++ptr; + } - if (endptr != num) { + while (*ptr >= '0' && *ptr <= '9') { + result = result * 10.0 + (*ptr - '0'); + ++ptr; + } + + if (*ptr == '.') { + double fraction = 0.0; + int n = 0; + ++ptr; + + while (*ptr >= '0' && *ptr <= '9') { + fraction = (fraction * 10.0) + (*ptr - '0'); + ++ptr; + ++n; + } + result += fraction / POW(10.0, n); + } + if (negative) result = -result; + + if (*ptr == 'e' || *ptr == 'E') { + double exponent = 0; + int expNegative = 0; + int n = 0; + ++ptr; + + if (*ptr == '-') { + expNegative = -1; + ++ptr; + } else if (*ptr == '+') { + ++ptr; + } + + while (*ptr >= '0' && *ptr <= '9') { + exponent = (exponent * 10.0) + (*ptr - '0'); + ++ptr; + ++n; + } + + if (expNegative) + result = result / POW(10, exponent); + else + result = result * POW(10, exponent); + } + + if (ptr != num) { /* Parse success, number found. */ - item->valueFloat = n; - item->valueInt = (int)n; + item->valueFloat = result; + item->valueInt = (int)result; item->type = Json_Number; - return endptr; + return ptr; } else { /* Parse failure, ep is set. */ ep = num; diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index c6136c66c..48322bad5 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/spine-c/src/spine/SkeletonJson.c @@ -30,7 +30,6 @@ #include #include -#include #include "Json.h" #include #include @@ -579,25 +578,14 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha int i, ii; spSkeletonData* skeletonData; Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *path, *slots, *skins, *animations, *events; - char* oldLocale; _spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self); FREE(self->error); CONST_CAST(char*, self->error) = 0; internal->linkedMeshCount = 0; -#ifndef __ANDROID__ - oldLocale = strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "C"); -#endif - root = Json_create(json); -#ifndef __ANDROID__ - setlocale(LC_NUMERIC, oldLocale); - free(oldLocale); -#endif - if (!root) { _spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError()); return 0;