1
0
Fork 0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-05-18 20:46:02 +02:00

dconv no longer uses global instances of StringToDoubleConverter/DoubleToStringConverter

This commit is contained in:
Dr. Nick 2021-08-03 10:17:10 -04:00
parent ea7cb916b4
commit e00caaebd5
6 changed files with 35 additions and 30 deletions

View File

@ -2,12 +2,10 @@
namespace double_conversion namespace double_conversion
{ {
static StringToDoubleConverter* s2d_instance = NULL;
static DoubleToStringConverter* d2s_instance = NULL;
extern "C" extern "C"
{ {
void dconv_d2s_init(int flags, void dconv_d2s_init(void **d2s,
int flags,
const char* infinity_symbol, const char* infinity_symbol,
const char* nan_symbol, const char* nan_symbol,
char exponent_character, char exponent_character,
@ -16,43 +14,43 @@ namespace double_conversion
int max_leading_padding_zeroes_in_precision_mode, int max_leading_padding_zeroes_in_precision_mode,
int max_trailing_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, exponent_character, decimal_in_shortest_low,
decimal_in_shortest_high, max_leading_padding_zeroes_in_precision_mode, decimal_in_shortest_high, max_leading_padding_zeroes_in_precision_mode,
max_trailing_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); StringBuilder sb(buf, buflen);
int success = static_cast<int>(d2s_instance->ToShortest(value, &sb)); int success = static_cast<int>(static_cast<DoubleToStringConverter*>(d2s)->ToShortest(value, &sb));
*strlength = success ? sb.position() : -1; *strlength = success ? sb.position() : -1;
return success; return success;
} }
void dconv_d2s_free() void dconv_d2s_free(void **d2s)
{ {
delete d2s_instance; delete static_cast<DoubleToStringConverter*>(*d2s);
d2s_instance = NULL; *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, double junk_string_value, const char* infinity_symbol,
const char* nan_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); 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<StringToDoubleConverter*>(s2d)->StringToDouble(buffer, length, processed_characters_count);
} }
void dconv_s2d_free() void dconv_s2d_free(void **s2d)
{ {
delete s2d_instance; delete static_cast<StringToDoubleConverter*>(*s2d);
s2d_instance = NULL; *s2d = NULL;
} }
} }
} }

View File

@ -274,6 +274,10 @@ typedef struct __JSONObjectEncoder
Private pointer to be used by the caller. Passed as encoder_prv in JSONTypeContext */ Private pointer to be used by the caller. Passed as encoder_prv in JSONTypeContext */
void *prv; void *prv;
/*
Pointer to the DoubleToStringConverter instance */
void *d2s;
/* /*
Set to an error message if error occured */ Set to an error message if error occured */
const char *errorMsg; const char *errorMsg;
@ -331,6 +335,7 @@ typedef struct __JSONObjectDecoder
char *errorStr; char *errorStr;
char *errorOffset; char *errorOffset;
void *prv; void *prv;
void *s2d;
} JSONObjectDecoder; } JSONObjectDecoder;
EXPORTFUNCTION JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer); 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 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* infinity_symbol,
const char* nan_symbol, const char* nan_symbol,
char exponent_character, char exponent_character,
@ -365,13 +371,13 @@ void dconv_d2s_init(int flags,
int decimal_in_shortest_high, int decimal_in_shortest_high,
int max_leading_padding_zeroes_in_precision_mode, int max_leading_padding_zeroes_in_precision_mode,
int max_trailing_padding_zeroes_in_precision_mode); int 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);
void dconv_d2s_free(void); 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, double junk_string_value, const char* infinity_symbol,
const char* nan_symbol); const char* 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);
void dconv_s2d_free(void); void dconv_s2d_free(void **s2d);
#endif #endif

View File

@ -81,7 +81,7 @@ static FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodeDouble(struct DecoderState *ds)
{ {
int processed_characters_count; int processed_characters_count;
int len = (int)(ds->end - ds->start); 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->lastType = JT_DOUBLE;
ds->start += processed_characters_count; ds->start += processed_characters_count;
return ds->dec->newDouble(ds->prv, value); return ds->dec->newDouble(ds->prv, value);

View File

@ -569,7 +569,7 @@ static int Buffer_AppendDoubleDconv(JSOBJ obj, JSONObjectEncoder *enc, double va
{ {
char buf[128]; char buf[128];
int strlength; 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"); SetError (obj, enc, "Invalid value when encoding double");
return FALSE; return FALSE;

View File

@ -170,11 +170,12 @@ PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs)
decoder.errorStr = NULL; decoder.errorStr = NULL;
decoder.errorOffset = 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)); ret = JSON_DecodeObject(&decoder, PyBytes_AsString(sarg), PyBytes_Size(sarg));
dconv_s2d_free(); dconv_s2d_free(&decoder.s2d);
if (sarg != arg) if (sarg != arg)
{ {

View File

@ -826,15 +826,15 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
encoder.rejectBytes = orejectBytes; encoder.rejectBytes = orejectBytes;
} }
encoder.d2s = NULL;
dconv_d2s_init(DCONV_D2S_EMIT_TRAILING_DECIMAL_POINT | DCONV_D2S_EMIT_TRAILING_ZERO_AFTER_POINT | DCONV_D2S_EMIT_POSITIVE_EXPONENT_SIGN, 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); csInf, csNan, 'e', DCONV_DECIMAL_IN_SHORTEST_LOW, DCONV_DECIMAL_IN_SHORTEST_HIGH, 0, 0);
PRINTMARK(); PRINTMARK();
ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer)); ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer));
PRINTMARK(); PRINTMARK();
dconv_d2s_free(); dconv_d2s_free(&encoder.d2s);
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {