1
0
Fork 0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-05-05 20:16:10 +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
{
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<int>(d2s_instance->ToShortest(value, &sb));
int success = static_cast<int>(static_cast<DoubleToStringConverter*>(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<DoubleToStringConverter*>(*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<StringToDoubleConverter*>(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<StringToDoubleConverter*>(*s2d);
*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 */
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

View File

@ -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);

View File

@ -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;

View File

@ -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)
{

View File

@ -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())
{