diff --git a/lib/dconv_wrapper.cc b/lib/dconv_wrapper.cc index 2b38f6d..29ccfaf 100644 --- a/lib/dconv_wrapper.cc +++ b/lib/dconv_wrapper.cc @@ -2,12 +2,10 @@ namespace double_conversion { - static StringToDoubleConverter* s2d_instance = NULL; - static DoubleToStringConverter* d2s_instance = NULL; - extern "C" { - void dconv_d2s_init(int flags, + void dconv_d2s_init(void **d2s, + int flags, const char* infinity_symbol, const char* nan_symbol, char exponent_character, @@ -16,43 +14,43 @@ namespace double_conversion int max_leading_padding_zeroes_in_precision_mode, int max_trailing_padding_zeroes_in_precision_mode) { - d2s_instance = new DoubleToStringConverter(flags, infinity_symbol, nan_symbol, + *d2s = new DoubleToStringConverter(flags, infinity_symbol, nan_symbol, exponent_character, decimal_in_shortest_low, decimal_in_shortest_high, max_leading_padding_zeroes_in_precision_mode, max_trailing_padding_zeroes_in_precision_mode); } - int dconv_d2s(double value, char* buf, int buflen, int* strlength) + int dconv_d2s(void *d2s, double value, char* buf, int buflen, int* strlength) { StringBuilder sb(buf, buflen); - int success = static_cast(d2s_instance->ToShortest(value, &sb)); + int success = static_cast(static_cast(d2s)->ToShortest(value, &sb)); *strlength = success ? sb.position() : -1; return success; } - void dconv_d2s_free() + void dconv_d2s_free(void **d2s) { - delete d2s_instance; - d2s_instance = NULL; + delete static_cast(*d2s); + *d2s = NULL; } - void dconv_s2d_init(int flags, double empty_string_value, + void dconv_s2d_init(void **s2d, int flags, double empty_string_value, double junk_string_value, const char* infinity_symbol, const char* nan_symbol) { - s2d_instance = new StringToDoubleConverter(flags, empty_string_value, + *s2d = new StringToDoubleConverter(flags, empty_string_value, junk_string_value, infinity_symbol, nan_symbol); } - double dconv_s2d(const char* buffer, int length, int* processed_characters_count) + double dconv_s2d(void *s2d, const char* buffer, int length, int* processed_characters_count) { - return s2d_instance->StringToDouble(buffer, length, processed_characters_count); + return static_cast(s2d)->StringToDouble(buffer, length, processed_characters_count); } - void dconv_s2d_free() + void dconv_s2d_free(void **s2d) { - delete s2d_instance; - s2d_instance = NULL; + delete static_cast(*s2d); + *s2d = NULL; } } } diff --git a/lib/ultrajson.h b/lib/ultrajson.h index 885f9f7..c686bd0 100644 --- a/lib/ultrajson.h +++ b/lib/ultrajson.h @@ -274,6 +274,10 @@ typedef struct __JSONObjectEncoder Private pointer to be used by the caller. Passed as encoder_prv in JSONTypeContext */ void *prv; + /* + Pointer to the DoubleToStringConverter instance */ + void *d2s; + /* Set to an error message if error occured */ const char *errorMsg; @@ -331,6 +335,7 @@ typedef struct __JSONObjectDecoder char *errorStr; char *errorOffset; void *prv; + void *s2d; } JSONObjectDecoder; EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer); @@ -357,7 +362,8 @@ enum dconv_s2d_flags DCONV_S2D_ALLOW_SPACES_AFTER_SIGN = 32 }; -void dconv_d2s_init(int flags, +void dconv_d2s_init(void **d2s, + int flags, const char* infinity_symbol, const char* nan_symbol, char exponent_character, @@ -365,13 +371,13 @@ void dconv_d2s_init(int flags, int decimal_in_shortest_high, int max_leading_padding_zeroes_in_precision_mode, int max_trailing_padding_zeroes_in_precision_mode); -int dconv_d2s(double value, char* buf, int buflen, int* strlength); -void dconv_d2s_free(void); +int dconv_d2s(void *d2s, double value, char* buf, int buflen, int* strlength); +void dconv_d2s_free(void **d2s); -void dconv_s2d_init(int flags, double empty_string_value, +void dconv_s2d_init(void **s2d, int flags, double empty_string_value, double junk_string_value, const char* infinity_symbol, const char* nan_symbol); -double dconv_s2d(const char* buffer, int length, int* processed_characters_count); -void dconv_s2d_free(void); +double dconv_s2d(void *s2d, const char* buffer, int length, int* processed_characters_count); +void dconv_s2d_free(void **s2d); #endif diff --git a/lib/ultrajsondec.c b/lib/ultrajsondec.c index 8f79b41..05b1452 100644 --- a/lib/ultrajsondec.c +++ b/lib/ultrajsondec.c @@ -81,7 +81,7 @@ static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodeDouble(struct DecoderState *ds) { int processed_characters_count; int len = (int)(ds->end - ds->start); - double value = dconv_s2d(ds->start, len, &processed_characters_count); + double value = dconv_s2d(ds->dec->s2d, ds->start, len, &processed_characters_count); ds->lastType = JT_DOUBLE; ds->start += processed_characters_count; return ds->dec->newDouble(ds->prv, value); diff --git a/lib/ultrajsonenc.c b/lib/ultrajsonenc.c index 756f5f2..a9f3ef1 100644 --- a/lib/ultrajsonenc.c +++ b/lib/ultrajsonenc.c @@ -569,7 +569,7 @@ static int Buffer_AppendDoubleDconv(JSOBJ obj, JSONObjectEncoder *enc, double va { char buf[128]; int strlength; - if(!dconv_d2s(value, buf, sizeof(buf), &strlength)) + if(!dconv_d2s(enc->d2s, value, buf, sizeof(buf), &strlength)) { SetError (obj, enc, "Invalid value when encoding double"); return FALSE; diff --git a/python/JSONtoObj.c b/python/JSONtoObj.c index 1c7232b..cc752a4 100644 --- a/python/JSONtoObj.c +++ b/python/JSONtoObj.c @@ -170,11 +170,12 @@ PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs) decoder.errorStr = NULL; decoder.errorOffset = NULL; - dconv_s2d_init(DCONV_S2D_ALLOW_TRAILING_JUNK, 0.0, 0.0, "Infinity", "NaN"); + decoder.s2d = NULL; + dconv_s2d_init(&decoder.s2d, DCONV_S2D_ALLOW_TRAILING_JUNK, 0.0, 0.0, "Infinity", "NaN"); ret = JSON_DecodeObject(&decoder, PyBytes_AsString(sarg), PyBytes_Size(sarg)); - dconv_s2d_free(); + dconv_s2d_free(&decoder.s2d); if (sarg != arg) { diff --git a/python/objToJSON.c b/python/objToJSON.c index b6ceff2..1297856 100644 --- a/python/objToJSON.c +++ b/python/objToJSON.c @@ -826,15 +826,15 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) encoder.rejectBytes = orejectBytes; } - - dconv_d2s_init(DCONV_D2S_EMIT_TRAILING_DECIMAL_POINT | DCONV_D2S_EMIT_TRAILING_ZERO_AFTER_POINT | DCONV_D2S_EMIT_POSITIVE_EXPONENT_SIGN, + encoder.d2s = NULL; + dconv_d2s_init(&encoder.d2s, DCONV_D2S_EMIT_TRAILING_DECIMAL_POINT | DCONV_D2S_EMIT_TRAILING_ZERO_AFTER_POINT | DCONV_D2S_EMIT_POSITIVE_EXPONENT_SIGN, csInf, csNan, 'e', DCONV_DECIMAL_IN_SHORTEST_LOW, DCONV_DECIMAL_IN_SHORTEST_HIGH, 0, 0); PRINTMARK(); ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer)); PRINTMARK(); - dconv_d2s_free(); + dconv_d2s_free(&encoder.d2s); if (PyErr_Occurred()) {