diff --git a/ci/lint.sh b/ci/lint.sh index 7ab97bfc6d328..d7df6215450b4 100755 --- a/ci/lint.sh +++ b/ci/lint.sh @@ -38,13 +38,22 @@ if [ "$LINT" ]; then # readability/casting: Warnings about C casting instead of C++ casting # runtime/int: Warnings about using C number types instead of C++ ones # build/include_subdir: Warnings about prefacing included header files with directory + + # We don't lint all C files because we don't want to lint any that are built + # from Cython files nor do we want to lint C files that we didn't modify for + # this particular codebase (e.g. src/headers, src/klib, src/msgpack). However, + # we can lint all header files since they aren't "generated" like C files are. pip install cpplint echo "Linting *.c and *.h" - cpplint --extensions=c,h --headers=h --filter=-readability/casting,-runtime/int,-build/include_subdir --recursive pandas/src/parser - if [ $? -ne "0" ]; then - RET=1 - fi + for path in '*.h' 'period_helper.c' 'datetime' 'parser' 'ujson' + do + echo "linting -> pandas/src/$path" + cpplint --extensions=c,h --headers=h --filter=-readability/casting,-runtime/int,-build/include_subdir --recursive pandas/src/$path + if [ $? -ne "0" ]; then + RET=1 + fi + done echo "Linting *.c and *.h DONE" echo "Check for invalid testing" diff --git a/pandas/src/datetime/np_datetime.c b/pandas/src/datetime/np_datetime.c index d4b9de45618f3..8458418988863 100644 --- a/pandas/src/datetime/np_datetime.c +++ b/pandas/src/datetime/np_datetime.c @@ -1,65 +1,65 @@ /* - * This is derived from Numpy 1.7 - * - * See NP_LICENSE.txt - */ + +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. + +Copyright (c) 2005-2011, NumPy Developers +All rights reserved. + +This file is derived from NumPy 1.7. See NUMPY_LICENSE.txt + +*/ #define NO_IMPORT #include #include -/* #define __MSVCRT_VERSION__ 0x0700 /\* whatever above 0x0601 *\/ */ -/* #include */ -/* #define time_t __time64_t */ -/* #define localtime _localtime64 */ -/* #define time _time64 */ - #include #include #include "np_datetime.h" #if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask +#define PyIntObject PyLongObject +#define PyInt_Type PyLong_Type +#define PyInt_Check(op) PyLong_Check(op) +#define PyInt_CheckExact(op) PyLong_CheckExact(op) +#define PyInt_FromString PyLong_FromString +#define PyInt_FromUnicode PyLong_FromUnicode +#define PyInt_FromLong PyLong_FromLong +#define PyInt_FromSize_t PyLong_FromSize_t +#define PyInt_FromSsize_t PyLong_FromSsize_t +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AS_LONG PyLong_AS_LONG +#define PyInt_AsSsize_t PyLong_AsSsize_t +#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask +#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #endif const int days_per_month_table[2][12] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; /* * Returns 1 if the given year is a leap year, 0 otherwise. */ -int is_leapyear(npy_int64 year) -{ +int is_leapyear(npy_int64 year) { return (year & 0x3) == 0 && /* year % 4 == 0 */ - ((year % 100) != 0 || - (year % 400) == 0); + ((year % 100) != 0 || (year % 400) == 0); } /* * Sakamoto's method, from wikipedia */ -int dayofweek(int y, int m, int d) -{ +int dayofweek(int y, int m, int d) { int day; static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; y -= m < 3; - day = (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; + day = (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7; // convert to python day return (day + 6) % 7; } @@ -68,9 +68,7 @@ int dayofweek(int y, int m, int d) * Adjusts a datetimestruct based on a minutes offset. Assumes * the current values are valid.g */ -void -add_minutes_to_datetimestruct(pandas_datetimestruct *dts, int minutes) -{ +void add_minutes_to_datetimestruct(pandas_datetimestruct *dts, int minutes) { int isleap; /* MINUTES */ @@ -102,12 +100,11 @@ add_minutes_to_datetimestruct(pandas_datetimestruct *dts, int minutes) dts->month = 12; } isleap = is_leapyear(dts->year); - dts->day += days_per_month_table[isleap][dts->month-1]; - } - else if (dts->day > 28) { + dts->day += days_per_month_table[isleap][dts->month - 1]; + } else if (dts->day > 28) { isleap = is_leapyear(dts->year); - if (dts->day > days_per_month_table[isleap][dts->month-1]) { - dts->day -= days_per_month_table[isleap][dts->month-1]; + if (dts->day > days_per_month_table[isleap][dts->month - 1]) { + dts->day -= days_per_month_table[isleap][dts->month - 1]; dts->month++; if (dts->month > 12) { dts->year++; @@ -120,9 +117,7 @@ add_minutes_to_datetimestruct(pandas_datetimestruct *dts, int minutes) /* * Calculates the days offset from the 1970 epoch. */ -npy_int64 -get_datetimestruct_days(const pandas_datetimestruct *dts) -{ +npy_int64 get_datetimestruct_days(const pandas_datetimestruct *dts) { int i, month; npy_int64 year, days = 0; const int *month_lengths; @@ -147,8 +142,7 @@ get_datetimestruct_days(const pandas_datetimestruct *dts) year += 300; /* Add one day for each 400 years */ days += year / 400; - } - else { + } else { /* * 1972 is the closest later year after 1970. * Include the current year, so subtract 2. @@ -183,20 +177,17 @@ get_datetimestruct_days(const pandas_datetimestruct *dts) * Modifies '*days_' to be the day offset within the year, * and returns the year. */ -static npy_int64 -days_to_yearsdays(npy_int64 *days_) -{ - const npy_int64 days_per_400years = (400*365 + 100 - 4 + 1); +static npy_int64 days_to_yearsdays(npy_int64 *days_) { + const npy_int64 days_per_400years = (400 * 365 + 100 - 4 + 1); /* Adjust so it's relative to the year 2000 (divisible by 400) */ - npy_int64 days = (*days_) - (365*30 + 7); + npy_int64 days = (*days_) - (365 * 30 + 7); npy_int64 year; /* Break down the 400 year cycle to get the year and day within the year */ if (days >= 0) { year = 400 * (days / days_per_400years); days = days % days_per_400years; - } - else { + } else { year = 400 * ((days - (days_per_400years - 1)) / days_per_400years); days = days % days_per_400years; if (days < 0) { @@ -206,14 +197,14 @@ days_to_yearsdays(npy_int64 *days_) /* Work out the year/day within the 400 year cycle */ if (days >= 366) { - year += 100 * ((days-1) / (100*365 + 25 - 1)); - days = (days-1) % (100*365 + 25 - 1); + year += 100 * ((days - 1) / (100 * 365 + 25 - 1)); + days = (days - 1) % (100 * 365 + 25 - 1); if (days >= 365) { - year += 4 * ((days+1) / (4*365 + 1)); - days = (days+1) % (4*365 + 1); + year += 4 * ((days + 1) / (4 * 365 + 1)); + days = (days + 1) % (4 * 365 + 1); if (days >= 366) { - year += (days-1) / 365; - days = (days-1) % 365; + year += (days - 1) / 365; + days = (days - 1) % 365; } } } @@ -226,9 +217,8 @@ days_to_yearsdays(npy_int64 *days_) * Adjusts a datetimestruct based on a seconds offset. Assumes * the current values are valid. */ -NPY_NO_EXPORT void -add_seconds_to_datetimestruct(pandas_datetimestruct *dts, int seconds) -{ +NPY_NO_EXPORT void add_seconds_to_datetimestruct(pandas_datetimestruct *dts, + int seconds) { int minutes; dts->sec += seconds; @@ -240,8 +230,7 @@ add_seconds_to_datetimestruct(pandas_datetimestruct *dts, int seconds) dts->sec += 60; } add_minutes_to_datetimestruct(dts, minutes); - } - else if (dts->sec >= 60) { + } else if (dts->sec >= 60) { minutes = dts->sec / 60; dts->sec = dts->sec % 60; add_minutes_to_datetimestruct(dts, minutes); @@ -252,9 +241,8 @@ add_seconds_to_datetimestruct(pandas_datetimestruct *dts, int seconds) * Fills in the year, month, day in 'dts' based on the days * offset from 1970. */ -static void -set_datetimestruct_days(npy_int64 days, pandas_datetimestruct *dts) -{ +static void set_datetimestruct_days(npy_int64 days, + pandas_datetimestruct *dts) { const int *month_lengths; int i; @@ -266,8 +254,7 @@ set_datetimestruct_days(npy_int64 days, pandas_datetimestruct *dts) dts->month = i + 1; dts->day = days + 1; return; - } - else { + } else { days -= month_lengths[i]; } } @@ -276,9 +263,8 @@ set_datetimestruct_days(npy_int64 days, pandas_datetimestruct *dts) /* * Compares two pandas_datetimestruct objects chronologically */ -int -cmp_pandas_datetimestruct(pandas_datetimestruct *a, pandas_datetimestruct *b) -{ +int cmp_pandas_datetimestruct(pandas_datetimestruct *a, + pandas_datetimestruct *b) { if (a->year > b->year) { return 1; } else if (a->year < b->year) { @@ -355,11 +341,10 @@ cmp_pandas_datetimestruct(pandas_datetimestruct *a, pandas_datetimestruct *b) * Returns -1 on error, 0 on success, and 1 (with no error set) * if obj doesn't have the neeeded date or datetime attributes. */ -int -convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, - PANDAS_DATETIMEUNIT *out_bestunit, - int apply_tzinfo) -{ +int convert_pydatetime_to_datetimestruct(PyObject *obj, + pandas_datetimestruct *out, + PANDAS_DATETIMEUNIT *out_bestunit, + int apply_tzinfo) { PyObject *tmp; int isleap; @@ -370,8 +355,8 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, /* Need at least year/month/day attributes */ if (!PyObject_HasAttrString(obj, "year") || - !PyObject_HasAttrString(obj, "month") || - !PyObject_HasAttrString(obj, "day")) { + !PyObject_HasAttrString(obj, "month") || + !PyObject_HasAttrString(obj, "day")) { return 1; } @@ -417,15 +402,15 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, } isleap = is_leapyear(out->year); if (out->day < 1 || - out->day > days_per_month_table[isleap][out->month-1]) { + out->day > days_per_month_table[isleap][out->month - 1]) { goto invalid_date; } /* Check for time attributes (if not there, return success as a date) */ if (!PyObject_HasAttrString(obj, "hour") || - !PyObject_HasAttrString(obj, "minute") || - !PyObject_HasAttrString(obj, "second") || - !PyObject_HasAttrString(obj, "microsecond")) { + !PyObject_HasAttrString(obj, "minute") || + !PyObject_HasAttrString(obj, "second") || + !PyObject_HasAttrString(obj, "microsecond")) { /* The best unit for date is 'D' */ if (out_bestunit != NULL) { *out_bestunit = PANDAS_FR_D; @@ -481,10 +466,8 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, } Py_DECREF(tmp); - if (out->hour < 0 || out->hour >= 24 || - out->min < 0 || out->min >= 60 || - out->sec < 0 || out->sec >= 60 || - out->us < 0 || out->us >= 1000000) { + if (out->hour < 0 || out->hour >= 24 || out->min < 0 || out->min >= 60 || + out->sec < 0 || out->sec >= 60 || out->us < 0 || out->us >= 1000000) { goto invalid_time; } @@ -496,8 +479,7 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, } if (tmp == Py_None) { Py_DECREF(tmp); - } - else { + } else { PyObject *offset; int seconds_offset, minutes_offset; @@ -540,20 +522,20 @@ convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, invalid_date: PyErr_Format(PyExc_ValueError, - "Invalid date (%d,%d,%d) when converting to NumPy datetime", - (int)out->year, (int)out->month, (int)out->day); + "Invalid date (%d,%d,%d) when converting to NumPy datetime", + (int)out->year, (int)out->month, (int)out->day); return -1; invalid_time: PyErr_Format(PyExc_ValueError, - "Invalid time (%d,%d,%d,%d) when converting " - "to NumPy datetime", - (int)out->hour, (int)out->min, (int)out->sec, (int)out->us); + "Invalid time (%d,%d,%d,%d) when converting " + "to NumPy datetime", + (int)out->hour, (int)out->min, (int)out->sec, (int)out->us); return -1; } -npy_datetime pandas_datetimestruct_to_datetime(PANDAS_DATETIMEUNIT fr, pandas_datetimestruct *d) -{ +npy_datetime pandas_datetimestruct_to_datetime(PANDAS_DATETIMEUNIT fr, + pandas_datetimestruct *d) { pandas_datetime_metadata meta; npy_datetime result = PANDAS_DATETIME_NAT; @@ -565,8 +547,7 @@ npy_datetime pandas_datetimestruct_to_datetime(PANDAS_DATETIMEUNIT fr, pandas_da } void pandas_datetime_to_datetimestruct(npy_datetime val, PANDAS_DATETIMEUNIT fr, - pandas_datetimestruct *result) -{ + pandas_datetimestruct *result) { pandas_datetime_metadata meta; meta.base = fr; @@ -576,10 +557,9 @@ void pandas_datetime_to_datetimestruct(npy_datetime val, PANDAS_DATETIMEUNIT fr, } PANDAS_DATETIMEUNIT get_datetime64_unit(PyObject *obj) { - return (PANDAS_DATETIMEUNIT)((PyDatetimeScalarObject *) obj)->obmeta.base; + return (PANDAS_DATETIMEUNIT)((PyDatetimeScalarObject *)obj)->obmeta.base; } - /* * Converts a datetime from a datetimestruct to a datetime based * on some metadata. The date is assumed to be valid. @@ -588,23 +568,19 @@ PANDAS_DATETIMEUNIT get_datetime64_unit(PyObject *obj) { * * Returns 0 on success, -1 on failure. */ -int -convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, - const pandas_datetimestruct *dts, - npy_datetime *out) -{ +int convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, + const pandas_datetimestruct *dts, + npy_datetime *out) { npy_datetime ret; PANDAS_DATETIMEUNIT base = meta->base; if (base == PANDAS_FR_Y) { /* Truncate to the year */ ret = dts->year - 1970; - } - else if (base == PANDAS_FR_M) { + } else if (base == PANDAS_FR_M) { /* Truncate to the month */ ret = 12 * (dts->year - 1970) + (dts->month - 1); - } - else { + } else { /* Otherwise calculate the number of days to start */ npy_int64 days = get_datetimestruct_days(dts); @@ -613,8 +589,7 @@ convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, /* Truncate to weeks */ if (days >= 0) { ret = days / 7; - } - else { + } else { ret = (days - 6) / 7; } break; @@ -622,74 +597,69 @@ convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, ret = days; break; case PANDAS_FR_h: - ret = days * 24 + - dts->hour; + ret = days * 24 + dts->hour; break; case PANDAS_FR_m: - ret = (days * 24 + - dts->hour) * 60 + - dts->min; + ret = (days * 24 + dts->hour) * 60 + dts->min; break; case PANDAS_FR_s: - ret = ((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec; + ret = ((days * 24 + dts->hour) * 60 + dts->min) * 60 + dts->sec; break; case PANDAS_FR_ms: - ret = (((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000 + + ret = (((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000 + dts->us / 1000; break; case PANDAS_FR_us: - ret = (((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000000 + + ret = (((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000000 + dts->us; break; case PANDAS_FR_ns: - ret = ((((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000000 + - dts->us) * 1000 + + ret = ((((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000000 + + dts->us) * + 1000 + dts->ps / 1000; break; case PANDAS_FR_ps: - ret = ((((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000000 + - dts->us) * 1000000 + + ret = ((((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000000 + + dts->us) * + 1000000 + dts->ps; break; case PANDAS_FR_fs: /* only 2.6 hours */ - ret = (((((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000000 + - dts->us) * 1000000 + - dts->ps) * 1000 + + ret = (((((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000000 + + dts->us) * + 1000000 + + dts->ps) * + 1000 + dts->as / 1000; break; case PANDAS_FR_as: /* only 9.2 secs */ - ret = (((((days * 24 + - dts->hour) * 60 + - dts->min) * 60 + - dts->sec) * 1000000 + - dts->us) * 1000000 + - dts->ps) * 1000000 + + ret = (((((days * 24 + dts->hour) * 60 + dts->min) * 60 + + dts->sec) * + 1000000 + + dts->us) * + 1000000 + + dts->ps) * + 1000000 + dts->as; break; default: /* Something got corrupted */ - PyErr_SetString(PyExc_ValueError, - "NumPy datetime metadata with corrupt unit value"); + PyErr_SetString( + PyExc_ValueError, + "NumPy datetime metadata with corrupt unit value"); return -1; } } @@ -698,8 +668,7 @@ convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, if (meta->num > 1) { if (ret >= 0) { ret /= meta->num; - } - else { + } else { ret = (ret - meta->num + 1) / meta->num; } } @@ -709,18 +678,15 @@ convert_datetimestruct_to_datetime(pandas_datetime_metadata *meta, return 0; } - /* * This provides the casting rules for the TIMEDELTA data type units. * * Notably, there is a barrier between the nonlinear years and * months units, and all the other units. */ -npy_bool -can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, - PANDAS_DATETIMEUNIT dst_unit, - NPY_CASTING casting) -{ +npy_bool can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, + PANDAS_DATETIMEUNIT dst_unit, + NPY_CASTING casting) { switch (casting) { /* Allow anything with unsafe casting */ case NPY_UNSAFE_CASTING: @@ -732,7 +698,7 @@ can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, */ case NPY_SAME_KIND_CASTING: return (src_unit <= PANDAS_FR_M && dst_unit <= PANDAS_FR_M) || - (src_unit > PANDAS_FR_M && dst_unit > PANDAS_FR_M); + (src_unit > PANDAS_FR_M && dst_unit > PANDAS_FR_M); /* * Enforce the 'date units' vs 'time units' barrier and that @@ -741,7 +707,7 @@ can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, */ case NPY_SAFE_CASTING: return (src_unit <= dst_unit) && - ((src_unit <= PANDAS_FR_M && dst_unit <= PANDAS_FR_M) || + ((src_unit <= PANDAS_FR_M && dst_unit <= PANDAS_FR_M) || (src_unit > PANDAS_FR_M && dst_unit > PANDAS_FR_M)); /* Enforce equality with 'no' or 'equiv' casting */ @@ -756,11 +722,9 @@ can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, * Notably, there is a barrier between 'date units' and 'time units' * for all but 'unsafe' casting. */ -npy_bool -can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, - PANDAS_DATETIMEUNIT dst_unit, - NPY_CASTING casting) -{ +npy_bool can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, + PANDAS_DATETIMEUNIT dst_unit, + NPY_CASTING casting) { switch (casting) { /* Allow anything with unsafe casting */ case NPY_UNSAFE_CASTING: @@ -772,7 +736,7 @@ can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, */ case NPY_SAME_KIND_CASTING: return (src_unit <= PANDAS_FR_D && dst_unit <= PANDAS_FR_D) || - (src_unit > PANDAS_FR_D && dst_unit > PANDAS_FR_D); + (src_unit > PANDAS_FR_D && dst_unit > PANDAS_FR_D); /* * Enforce the 'date units' vs 'time units' barrier and that @@ -781,7 +745,7 @@ can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, */ case NPY_SAFE_CASTING: return (src_unit <= dst_unit) && - ((src_unit <= PANDAS_FR_D && dst_unit <= PANDAS_FR_D) || + ((src_unit <= PANDAS_FR_D && dst_unit <= PANDAS_FR_D) || (src_unit > PANDAS_FR_D && dst_unit > PANDAS_FR_D)); /* Enforce equality with 'no' or 'equiv' casting */ @@ -793,11 +757,9 @@ can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, /* * Converts a datetime based on the given metadata into a datetimestruct */ -int -convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, - npy_datetime dt, - pandas_datetimestruct *out) -{ +int convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, + npy_datetime dt, + pandas_datetimestruct *out) { npy_int64 perday; /* Initialize the output to all zeros */ @@ -820,12 +782,11 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, case PANDAS_FR_M: if (dt >= 0) { - out->year = 1970 + dt / 12; + out->year = 1970 + dt / 12; out->month = dt % 12 + 1; - } - else { - out->year = 1969 + (dt + 1) / 12; - out->month = 12 + (dt + 1)% 12; + } else { + out->year = 1969 + (dt + 1) / 12; + out->month = 12 + (dt + 1) % 12; } break; @@ -843,12 +804,11 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; - } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } out->hour = dt; break; @@ -858,12 +818,11 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; - } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } out->hour = dt / 60; out->min = dt % 60; @@ -874,14 +833,13 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; - } - out->hour = dt / (60*60); + out->hour = dt / (60 * 60); out->min = (dt / 60) % 60; out->sec = dt % 60; break; @@ -891,15 +849,14 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; - } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } - out->hour = dt / (60*60*1000LL); - out->min = (dt / (60*1000LL)) % 60; + out->hour = dt / (60 * 60 * 1000LL); + out->min = (dt / (60 * 1000LL)) % 60; out->sec = (dt / 1000LL) % 60; out->us = (dt % 1000LL) * 1000; break; @@ -909,15 +866,14 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; - } - out->hour = dt / (60*60*1000000LL); - out->min = (dt / (60*1000000LL)) % 60; + out->hour = dt / (60 * 60 * 1000000LL); + out->min = (dt / (60 * 1000000LL)) % 60; out->sec = (dt / 1000000LL) % 60; out->us = dt % 1000000LL; break; @@ -927,15 +883,14 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; - } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } - out->hour = dt / (60*60*1000000000LL); - out->min = (dt / (60*1000000000LL)) % 60; + out->hour = dt / (60 * 60 * 1000000000LL); + out->min = (dt / (60 * 1000000000LL)) % 60; out->sec = (dt / 1000000000LL) % 60; out->us = (dt / 1000LL) % 1000000LL; out->ps = (dt % 1000LL) * 1000; @@ -946,15 +901,14 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, if (dt >= 0) { set_datetimestruct_days(dt / perday, out); - dt = dt % perday; + dt = dt % perday; + } else { + set_datetimestruct_days( + dt / perday - (dt % perday == 0 ? 0 : 1), out); + dt = (perday - 1) + (dt + 1) % perday; } - else { - set_datetimestruct_days(dt / perday - (dt % perday == 0 ? 0 : 1), - out); - dt = (perday-1) + (dt + 1) % perday; - } - out->hour = dt / (60*60*1000000000000LL); - out->min = (dt / (60*1000000000000LL)) % 60; + out->hour = dt / (60 * 60 * 1000000000000LL); + out->min = (dt / (60 * 1000000000000LL)) % 60; out->sec = (dt / 1000000000000LL) % 60; out->us = (dt / 1000000LL) % 1000000LL; out->ps = dt % 1000000LL; @@ -963,20 +917,19 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, case PANDAS_FR_fs: /* entire range is only +- 2.6 hours */ if (dt >= 0) { - out->hour = dt / (60*60*1000000000000000LL); - out->min = (dt / (60*1000000000000000LL)) % 60; + out->hour = dt / (60 * 60 * 1000000000000000LL); + out->min = (dt / (60 * 1000000000000000LL)) % 60; out->sec = (dt / 1000000000000000LL) % 60; out->us = (dt / 1000000000LL) % 1000000LL; out->ps = (dt / 1000LL) % 1000000LL; out->as = (dt % 1000LL) * 1000; - } - else { + } else { npy_datetime minutes; - minutes = dt / (60*1000000000000000LL); - dt = dt % (60*1000000000000000LL); + minutes = dt / (60 * 1000000000000000LL); + dt = dt % (60 * 1000000000000000LL); if (dt < 0) { - dt += (60*1000000000000000LL); + dt += (60 * 1000000000000000LL); --minutes; } /* Offset the negative minutes */ @@ -995,8 +948,7 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, out->us = (dt / 1000000000000LL) % 1000000LL; out->ps = (dt / 1000000LL) % 1000000LL; out->as = dt % 1000000LL; - } - else { + } else { npy_datetime seconds; seconds = dt / 1000000000000000000LL; @@ -1015,11 +967,10 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, default: PyErr_SetString(PyExc_RuntimeError, - "NumPy datetime metadata is corrupted with invalid " - "base unit"); + "NumPy datetime metadata is corrupted with invalid " + "base unit"); return -1; } return 0; } - diff --git a/pandas/src/datetime/np_datetime.h b/pandas/src/datetime/np_datetime.h index f200d3a289c06..3445fc3e48376 100644 --- a/pandas/src/datetime/np_datetime.h +++ b/pandas/src/datetime/np_datetime.h @@ -1,29 +1,41 @@ /* - * This is derived from numpy 1.7 - * See NP_LICENSE.TXT - */ -#ifndef _PANDAS_DATETIME_H_ -#define _PANDAS_DATETIME_H_ +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. + +Copyright (c) 2005-2011, NumPy Developers +All rights reserved. + +This file is derived from NumPy 1.7. See NUMPY_LICENSE.txt + +*/ + +#ifndef PANDAS_SRC_DATETIME_NP_DATETIME_H_ +#define PANDAS_SRC_DATETIME_NP_DATETIME_H_ #include typedef enum { - PANDAS_FR_Y = 0, /* Years */ - PANDAS_FR_M = 1, /* Months */ - PANDAS_FR_W = 2, /* Weeks */ - /* Gap where NPY_FR_B was */ - PANDAS_FR_D = 4, /* Days */ - PANDAS_FR_h = 5, /* hours */ - PANDAS_FR_m = 6, /* minutes */ - PANDAS_FR_s = 7, /* seconds */ - PANDAS_FR_ms = 8,/* milliseconds */ - PANDAS_FR_us = 9,/* microseconds */ - PANDAS_FR_ns = 10,/* nanoseconds */ - PANDAS_FR_ps = 11,/* picoseconds */ - PANDAS_FR_fs = 12,/* femtoseconds */ - PANDAS_FR_as = 13,/* attoseconds */ - PANDAS_FR_GENERIC = 14 /* Generic, unbound units, can convert to anything */ + PANDAS_FR_Y = 0, // Years + PANDAS_FR_M = 1, // Months + PANDAS_FR_W = 2, // Weeks + // Gap where NPY_FR_B was + PANDAS_FR_D = 4, // Days + PANDAS_FR_h = 5, // hours + PANDAS_FR_m = 6, // minutes + PANDAS_FR_s = 7, // seconds + PANDAS_FR_ms = 8, // milliseconds + PANDAS_FR_us = 9, // microseconds + PANDAS_FR_ns = 10, // nanoseconds + PANDAS_FR_ps = 11, // picoseconds + PANDAS_FR_fs = 12, // femtoseconds + PANDAS_FR_as = 13, // attoseconds + PANDAS_FR_GENERIC = 14 // Generic, unbound units, can + // convert to anything } PANDAS_DATETIMEUNIT; #define PANDAS_DATETIME_NUMUNITS 13 @@ -45,7 +57,8 @@ typedef struct { // stuff pandas needs // ---------------------------------------------------------------------------- -int convert_pydatetime_to_datetimestruct(PyObject *obj, pandas_datetimestruct *out, +int convert_pydatetime_to_datetimestruct(PyObject *obj, + pandas_datetimestruct *out, PANDAS_DATETIMEUNIT *out_bestunit, int apply_tzinfo); @@ -96,11 +109,6 @@ add_minutes_to_datetimestruct(pandas_datetimestruct *dts, int minutes); * Notably, there is a barrier between the nonlinear years and * months units, and all the other units. */ -//npy_bool -//can_cast_timedelta64_units(PANDAS_DATETIMEUNIT src_unit, -// PANDAS_DATETIMEUNIT dst_unit, -// NPY_CASTING casting); - npy_bool can_cast_datetime64_units(PANDAS_DATETIMEUNIT src_unit, PANDAS_DATETIMEUNIT dst_unit, @@ -116,4 +124,4 @@ convert_datetime_to_datetimestruct(pandas_datetime_metadata *meta, PANDAS_DATETIMEUNIT get_datetime64_unit(PyObject *obj); -#endif +#endif // PANDAS_SRC_DATETIME_NP_DATETIME_H_ diff --git a/pandas/src/datetime/np_datetime_strings.c b/pandas/src/datetime/np_datetime_strings.c index b633d6cde0820..5307d394423ff 100644 --- a/pandas/src/datetime/np_datetime_strings.c +++ b/pandas/src/datetime/np_datetime_strings.c @@ -1,11 +1,23 @@ /* - * This file implements string parsing and creation for NumPy datetime. - * - * Written by Mark Wiebe (mwwiebe@gmail.com) - * Copyright (c) 2011 by Enthought, Inc. - * - * See NP_LICENSE.txt for the license. - */ + +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. + +Written by Mark Wiebe (mwwiebe@gmail.com) +Copyright (c) 2011 by Enthought, Inc. + +Copyright (c) 2005-2011, NumPy Developers +All rights reserved. + +See NUMPY_LICENSE.txt for the license. + +This file implements string parsing and creation for NumPy datetime. + +*/ #define PY_SSIZE_T_CLEAN #define NO_IMPORT @@ -20,9 +32,7 @@ #include "np_datetime.h" #include "np_datetime_strings.h" -NPY_NO_EXPORT const char * -npy_casting_to_string(NPY_CASTING casting) -{ +NPY_NO_EXPORT const char *npy_casting_to_string(NPY_CASTING casting) { switch (casting) { case NPY_NO_CASTING: return "'no'"; @@ -42,35 +52,23 @@ npy_casting_to_string(NPY_CASTING casting) /* Platform-specific time_t typedef */ typedef time_t NPY_TIME_T; -/*// We *do* want these symbols, but for cython, not for C. fine in mac osx,*/ -/*// linux complains.*/ -/*static void _suppress_unused_variable_warning(void)*/ -/*{*/ -/* int x = days_per_month_table[0][0];*/ -/* x = x;*/ +/* We *do* want these symbols, but for Cython, not for C. + Fine in Mac OSX, but Linux complains. + +static void _suppress_unused_variable_warning(void) { + int x = days_per_month_table[0][0]; + x = x; -/* int y = _month_offset[0][0];*/ -/* y = y;*/ + int y = _month_offset[0][0]; + y = y; -/* char *z = _datetime_strings[0];*/ -/* z = z;*/ -/*}*/ + char *z = _datetime_strings[0]; + z = z; +} */ /* Exported as DATETIMEUNITS in multiarraymodule.c */ static char *_datetime_strings[PANDAS_DATETIME_NUMUNITS] = { - "Y", - "M", - "W", - "D", - "h", - "m", - "s", - "ms", - "us", - "ns", - "ps", - "fs", - "as", + "Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as", }; /* * Wraps `localtime` functionality for multiple platforms. This @@ -78,30 +76,28 @@ static char *_datetime_strings[PANDAS_DATETIME_NUMUNITS] = { * * Returns 0 on success, -1 on failure. */ -static int -get_localtime(NPY_TIME_T *ts, struct tm *tms) -{ +static int get_localtime(NPY_TIME_T *ts, struct tm *tms) { char *func_name = ""; #if defined(_WIN32) - #if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) if (localtime_s(tms, ts) != 0) { func_name = "localtime_s"; goto fail; } - #elif defined(__GNUC__) && defined(NPY_MINGW_USE_CUSTOM_MSVCR) +#elif defined(__GNUC__) && defined(NPY_MINGW_USE_CUSTOM_MSVCR) if (_localtime64_s(tms, ts) != 0) { func_name = "_localtime64_s"; goto fail; } - #else +#else struct tm *tms_tmp; - tms_tmp = localtime(ts); + localtime_r(ts, tms_tmp); if (tms_tmp == NULL) { func_name = "localtime"; goto fail; } memcpy(tms, tms_tmp, sizeof(struct tm)); - #endif +#endif #else if (localtime_r(ts, tms) == NULL) { func_name = "localtime_r"; @@ -112,8 +108,10 @@ get_localtime(NPY_TIME_T *ts, struct tm *tms) return 0; fail: - PyErr_Format(PyExc_OSError, "Failed to use '%s' to convert " - "to a local time", func_name); + PyErr_Format(PyExc_OSError, + "Failed to use '%s' to convert " + "to a local time", + func_name); return -1; } @@ -125,29 +123,28 @@ get_localtime(NPY_TIME_T *ts, struct tm *tms) * Returns 0 on success, -1 on failure. */ static int -get_gmtime(NPY_TIME_T *ts, struct tm *tms) -{ +get_gmtime(NPY_TIME_T *ts, struct tm *tms) { char *func_name = ""; #if defined(_WIN32) - #if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) if (gmtime_s(tms, ts) != 0) { func_name = "gmtime_s"; goto fail; } - #elif defined(__GNUC__) && defined(NPY_MINGW_USE_CUSTOM_MSVCR) +#elif defined(__GNUC__) && defined(NPY_MINGW_USE_CUSTOM_MSVCR) if (_gmtime64_s(tms, ts) != 0) { func_name = "_gmtime64_s"; goto fail; } - #else +#else struct tm *tms_tmp; - tms_tmp = gmtime(ts); + gmtime_r(ts, tms_tmp); if (tms_tmp == NULL) { func_name = "gmtime"; goto fail; } memcpy(tms, tms_tmp, sizeof(struct tm)); - #endif +#endif #else if (gmtime_r(ts, tms) == NULL) { func_name = "gmtime_r"; @@ -170,10 +167,9 @@ get_gmtime(NPY_TIME_T *ts, struct tm *tms) * * Returns 0 on success, -1 on failure. */ -static int -convert_datetimestruct_utc_to_local(pandas_datetimestruct *out_dts_local, - const pandas_datetimestruct *dts_utc, int *out_timezone_offset) -{ +static int convert_datetimestruct_utc_to_local( + pandas_datetimestruct *out_dts_local, const pandas_datetimestruct *dts_utc, + int *out_timezone_offset) { NPY_TIME_T rawtime = 0, localrawtime; struct tm tm_; npy_int64 year_correction = 0; @@ -187,8 +183,7 @@ convert_datetimestruct_utc_to_local(pandas_datetimestruct *out_dts_local, /* 2036 is a leap year */ year_correction = out_dts_local->year - 2036; out_dts_local->year -= year_correction; - } - else { + } else { /* 2037 is not a leap year */ year_correction = out_dts_local->year - 2037; out_dts_local->year -= year_correction; @@ -239,8 +234,7 @@ convert_datetimestruct_utc_to_local(pandas_datetimestruct *out_dts_local, */ static int convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, - const pandas_datetimestruct *dts_local) -{ + const pandas_datetimestruct *dts_local) { npy_int64 year_correction = 0; /* Make a copy of the input 'dts' to modify */ @@ -252,8 +246,7 @@ convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, /* 2036 is a leap year */ year_correction = out_dts_utc->year - 2036; out_dts_utc->year -= year_correction; - } - else { + } else { /* 2037 is not a leap year */ year_correction = out_dts_utc->year - 2037; out_dts_utc->year -= year_correction; @@ -332,7 +325,8 @@ convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, /* } */ /* /\* Parse the ISO date *\/ */ -/* if (parse_iso_8601_datetime(str, len, PANDAS_FR_us, NPY_UNSAFE_CASTING, */ +/* if (parse_iso_8601_datetime(str, len, PANDAS_FR_us, NPY_UNSAFE_CASTING, + */ /* dts, NULL, &bestunit, NULL) < 0) { */ /* Py_DECREF(bytes); */ /* return -1; */ @@ -342,7 +336,6 @@ convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, /* return 0; */ /* } */ - /* * Parses (almost) standard ISO 8601 date strings. The differences are: * @@ -365,7 +358,7 @@ convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, * to be cast to the 'unit' parameter. * * 'out' gets filled with the parsed date-time. - * 'out_local' gets set to 1 if the parsed time contains timezone, + * 'out_local' gets set to 1 if the parsed time contains timezone, * to 0 otherwise. * 'out_tzoffset' gets set to timezone offset by minutes * if the parsed time was in local time, @@ -381,16 +374,11 @@ convert_datetimestruct_local_to_utc(pandas_datetimestruct *out_dts_utc, * * Returns 0 on success, -1 on failure. */ -int -parse_iso_8601_datetime(char *str, int len, - PANDAS_DATETIMEUNIT unit, - NPY_CASTING casting, - pandas_datetimestruct *out, - int *out_local, - int *out_tzoffset, - PANDAS_DATETIMEUNIT *out_bestunit, - npy_bool *out_special) -{ +int parse_iso_8601_datetime(char *str, int len, PANDAS_DATETIMEUNIT unit, + NPY_CASTING casting, pandas_datetimestruct *out, + int *out_local, int *out_tzoffset, + PANDAS_DATETIMEUNIT *out_bestunit, + npy_bool *out_special) { int year_leap = 0; int i, numdigits; char *substr, sublen; @@ -417,7 +405,6 @@ parse_iso_8601_datetime(char *str, int len, out->month = 1; out->day = 1; - /* * The string "today" means take today's date in local time, and * convert it to a date representation. This date representation, if @@ -427,11 +414,9 @@ parse_iso_8601_datetime(char *str, int len, * switching to an adjacent day depending on the current time and your * timezone. */ - if (len == 5 && tolower(str[0]) == 't' && - tolower(str[1]) == 'o' && - tolower(str[2]) == 'd' && - tolower(str[3]) == 'a' && - tolower(str[4]) == 'y') { + if (len == 5 && tolower(str[0]) == 't' && tolower(str[1]) == 'o' && + tolower(str[2]) == 'd' && tolower(str[3]) == 'a' && + tolower(str[4]) == 'y') { NPY_TIME_T rawtime = 0; struct tm tm_; @@ -460,9 +445,9 @@ parse_iso_8601_datetime(char *str, int len, } /* Check the casting rule */ - if (!can_cast_datetime64_units(bestunit, unit, - casting)) { - PyErr_Format(PyExc_TypeError, "Cannot parse \"%s\" as unit " + if (!can_cast_datetime64_units(bestunit, unit, casting)) { + PyErr_Format(PyExc_TypeError, + "Cannot parse \"%s\" as unit " "'%s' using casting rule %s", str, _datetime_strings[unit], npy_casting_to_string(casting)); @@ -473,9 +458,8 @@ parse_iso_8601_datetime(char *str, int len, } /* The string "now" resolves to the current UTC time */ - if (len == 3 && tolower(str[0]) == 'n' && - tolower(str[1]) == 'o' && - tolower(str[2]) == 'w') { + if (len == 3 && tolower(str[0]) == 'n' && tolower(str[1]) == 'o' && + tolower(str[2]) == 'w') { NPY_TIME_T rawtime = 0; pandas_datetime_metadata meta; @@ -503,9 +487,9 @@ parse_iso_8601_datetime(char *str, int len, } /* Check the casting rule */ - if (!can_cast_datetime64_units(bestunit, unit, - casting)) { - PyErr_Format(PyExc_TypeError, "Cannot parse \"%s\" as unit " + if (!can_cast_datetime64_units(bestunit, unit, casting)) { + PyErr_Format(PyExc_TypeError, + "Cannot parse \"%s\" as unit " "'%s' using casting rule %s", str, _datetime_strings[unit], npy_casting_to_string(casting)); @@ -543,12 +527,11 @@ parse_iso_8601_datetime(char *str, int len, out->year = 0; if (sublen >= 4 && isdigit(substr[0]) && isdigit(substr[1]) && isdigit(substr[2]) && isdigit(substr[3])) { - out->year = 1000 * (substr[0] - '0') + 100 * (substr[1] - '0') + - 10 * (substr[2] - '0') + (substr[3] - '0'); + 10 * (substr[2] - '0') + (substr[3] - '0'); substr += 4; - sublen -= 4;; + sublen -= 4; } /* Negate the year if necessary */ @@ -596,8 +579,7 @@ parse_iso_8601_datetime(char *str, int len, out->month = 10 * out->month + (*substr - '0'); ++substr; --sublen; - } - else if (!has_ymd_sep) { + } else if (!has_ymd_sep) { goto parse_error; } if (out->month < 1 || out->month > 12) { @@ -610,7 +592,7 @@ parse_iso_8601_datetime(char *str, int len, if (sublen == 0) { /* Forbid YYYYMM. Parsed instead as YYMMDD by someone else. */ if (!has_ymd_sep) { - goto parse_error; + goto parse_error; } if (out_local != NULL) { *out_local = 0; @@ -631,7 +613,7 @@ parse_iso_8601_datetime(char *str, int len, /* PARSE THE DAY */ /* First digit required */ if (!isdigit(*substr)) { - goto parse_error; + goto parse_error; } out->day = (*substr - '0'); ++substr; @@ -641,13 +623,11 @@ parse_iso_8601_datetime(char *str, int len, out->day = 10 * out->day + (*substr - '0'); ++substr; --sublen; - } - else if (!has_ymd_sep) { + } else if (!has_ymd_sep) { goto parse_error; } if (out->day < 1 || - out->day > days_per_month_table[year_leap][out->month-1]) - { + out->day > days_per_month_table[year_leap][out->month - 1]) { PyErr_Format(PyExc_ValueError, "Day out of range in datetime string \"%s\"", str); goto error; @@ -684,7 +664,7 @@ parse_iso_8601_datetime(char *str, int len, --sublen; if (out->hour >= 24) { PyErr_Format(PyExc_ValueError, - "Hours out of range in datetime string \"%s\"", str); + "Hours out of range in datetime string \"%s\"", str); goto error; } } @@ -706,8 +686,7 @@ parse_iso_8601_datetime(char *str, int len, if (sublen == 0 || !isdigit(*substr)) { goto parse_error; } - } - else if (!isdigit(*substr)) { + } else if (!isdigit(*substr)) { if (!hour_was_2_digits) { goto parse_error; } @@ -730,8 +709,7 @@ parse_iso_8601_datetime(char *str, int len, "Minutes out of range in datetime string \"%s\"", str); goto error; } - } - else if (!has_hms_sep) { + } else if (!has_hms_sep) { goto parse_error; } @@ -749,10 +727,8 @@ parse_iso_8601_datetime(char *str, int len, if (sublen == 0 || !isdigit(*substr)) { goto parse_error; } - } - else if (!has_hms_sep && isdigit(*substr)) { - } - else { + } else if (!has_hms_sep && isdigit(*substr)) { + } else { bestunit = PANDAS_FR_m; goto parse_timezone; } @@ -772,8 +748,7 @@ parse_iso_8601_datetime(char *str, int len, "Seconds out of range in datetime string \"%s\"", str); goto error; } - } - else if (!has_hms_sep) { + } else if (!has_hms_sep) { goto parse_error; } @@ -781,8 +756,7 @@ parse_iso_8601_datetime(char *str, int len, if (sublen > 0 && *substr == '.') { ++substr; --sublen; - } - else { + } else { bestunit = PANDAS_FR_s; goto parse_timezone; } @@ -791,7 +765,7 @@ parse_iso_8601_datetime(char *str, int len, numdigits = 0; for (i = 0; i < 6; ++i) { out->us *= 10; - if (sublen > 0 && isdigit(*substr)) { + if (sublen > 0 && isdigit(*substr)) { out->us += (*substr - '0'); ++substr; --sublen; @@ -802,8 +776,7 @@ parse_iso_8601_datetime(char *str, int len, if (sublen == 0 || !isdigit(*substr)) { if (numdigits > 3) { bestunit = PANDAS_FR_us; - } - else { + } else { bestunit = PANDAS_FR_ms; } goto parse_timezone; @@ -824,8 +797,7 @@ parse_iso_8601_datetime(char *str, int len, if (sublen == 0 || !isdigit(*substr)) { if (numdigits > 3) { bestunit = PANDAS_FR_ps; - } - else { + } else { bestunit = PANDAS_FR_ns; } goto parse_timezone; @@ -845,16 +817,15 @@ parse_iso_8601_datetime(char *str, int len, if (numdigits > 3) { bestunit = PANDAS_FR_as; - } - else { + } else { bestunit = PANDAS_FR_fs; } parse_timezone: /* trim any whitepsace between time/timeezone */ while (sublen > 0 && isspace(*substr)) { - ++substr; - --sublen; + ++substr; + --sublen; } if (sublen == 0) { @@ -871,18 +842,16 @@ parse_iso_8601_datetime(char *str, int len, if (out_tzoffset != NULL) { *out_tzoffset = 0; - } + } if (sublen == 1) { goto finish; - } - else { + } else { ++substr; --sublen; } - } - /* Time zone offset */ - else if (*substr == '-' || *substr == '+') { + } else if (*substr == '-' || *substr == '+') { + /* Time zone offset */ int offset_neg = 0, offset_hour = 0, offset_minute = 0; /* @@ -903,17 +872,16 @@ parse_iso_8601_datetime(char *str, int len, sublen -= 2; if (offset_hour >= 24) { PyErr_Format(PyExc_ValueError, - "Timezone hours offset out of range " - "in datetime string \"%s\"", str); + "Timezone hours offset out of range " + "in datetime string \"%s\"", + str); goto error; } - } - else if (sublen >= 1 && isdigit(substr[0])) { + } else if (sublen >= 1 && isdigit(substr[0])) { offset_hour = substr[0] - '0'; ++substr; --sublen; - } - else { + } else { goto parse_error; } @@ -932,17 +900,16 @@ parse_iso_8601_datetime(char *str, int len, sublen -= 2; if (offset_minute >= 60) { PyErr_Format(PyExc_ValueError, - "Timezone minutes offset out of range " - "in datetime string \"%s\"", str); + "Timezone minutes offset out of range " + "in datetime string \"%s\"", + str); goto error; } - } - else if (sublen >= 1 && isdigit(substr[0])) { + } else if (sublen >= 1 && isdigit(substr[0])) { offset_minute = substr[0] - '0'; ++substr; --sublen; - } - else { + } else { goto parse_error; } } @@ -975,9 +942,9 @@ parse_iso_8601_datetime(char *str, int len, } /* Check the casting rule */ - if (!can_cast_datetime64_units(bestunit, unit, - casting)) { - PyErr_Format(PyExc_TypeError, "Cannot parse \"%s\" as unit " + if (!can_cast_datetime64_units(bestunit, unit, casting)) { + PyErr_Format(PyExc_TypeError, + "Cannot parse \"%s\" as unit " "'%s' using casting rule %s", str, _datetime_strings[unit], npy_casting_to_string(casting)); @@ -988,8 +955,8 @@ parse_iso_8601_datetime(char *str, int len, parse_error: PyErr_Format(PyExc_ValueError, - "Error parsing datetime string \"%s\" at position %d", - str, (int)(substr-str)); + "Error parsing datetime string \"%s\" at position %d", str, + (int)(substr - str)); return -1; error: @@ -1000,9 +967,7 @@ parse_iso_8601_datetime(char *str, int len, * Provides a string length to use for converting datetime * objects with the given local and unit settings. */ -int -get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) -{ +int get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) { int len = 0; switch (base) { @@ -1010,28 +975,28 @@ get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) /*case PANDAS_FR_GENERIC:*/ /* return 4;*/ case PANDAS_FR_as: - len += 3; /* "###" */ + len += 3; /* "###" */ case PANDAS_FR_fs: - len += 3; /* "###" */ + len += 3; /* "###" */ case PANDAS_FR_ps: - len += 3; /* "###" */ + len += 3; /* "###" */ case PANDAS_FR_ns: - len += 3; /* "###" */ + len += 3; /* "###" */ case PANDAS_FR_us: - len += 3; /* "###" */ + len += 3; /* "###" */ case PANDAS_FR_ms: - len += 4; /* ".###" */ + len += 4; /* ".###" */ case PANDAS_FR_s: - len += 3; /* ":##" */ + len += 3; /* ":##" */ case PANDAS_FR_m: - len += 3; /* ":##" */ + len += 3; /* ":##" */ case PANDAS_FR_h: - len += 3; /* "T##" */ + len += 3; /* "T##" */ case PANDAS_FR_D: case PANDAS_FR_W: - len += 3; /* "-##" */ + len += 3; /* "-##" */ case PANDAS_FR_M: - len += 3; /* "-##" */ + len += 3; /* "-##" */ case PANDAS_FR_Y: len += 21; /* 64-bit year */ break; @@ -1042,10 +1007,9 @@ get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) if (base >= PANDAS_FR_h) { if (local) { - len += 5; /* "+####" or "-####" */ - } - else { - len += 1; /* "Z" */ + len += 5; /* "+####" or "-####" */ + } else { + len += 1; /* "Z" */ } } @@ -1058,43 +1022,31 @@ get_datetime_iso_8601_strlen(int local, PANDAS_DATETIMEUNIT base) * Finds the largest unit whose value is nonzero, and for which * the remainder for the rest of the units is zero. */ -static PANDAS_DATETIMEUNIT -lossless_unit_from_datetimestruct(pandas_datetimestruct *dts) -{ +static PANDAS_DATETIMEUNIT lossless_unit_from_datetimestruct( + pandas_datetimestruct *dts) { if (dts->as % 1000 != 0) { return PANDAS_FR_as; - } - else if (dts->as != 0) { + } else if (dts->as != 0) { return PANDAS_FR_fs; - } - else if (dts->ps % 1000 != 0) { + } else if (dts->ps % 1000 != 0) { return PANDAS_FR_ps; - } - else if (dts->ps != 0) { + } else if (dts->ps != 0) { return PANDAS_FR_ns; - } - else if (dts->us % 1000 != 0) { + } else if (dts->us % 1000 != 0) { return PANDAS_FR_us; - } - else if (dts->us != 0) { + } else if (dts->us != 0) { return PANDAS_FR_ms; - } - else if (dts->sec != 0) { + } else if (dts->sec != 0) { return PANDAS_FR_s; - } - else if (dts->min != 0) { + } else if (dts->min != 0) { return PANDAS_FR_m; - } - else if (dts->hour != 0) { + } else if (dts->hour != 0) { return PANDAS_FR_h; - } - else if (dts->day != 1) { + } else if (dts->day != 1) { return PANDAS_FR_D; - } - else if (dts->month != 1) { + } else if (dts->month != 1) { return PANDAS_FR_M; - } - else { + } else { return PANDAS_FR_Y; } } @@ -1125,11 +1077,9 @@ lossless_unit_from_datetimestruct(pandas_datetimestruct *dts) * Returns 0 on success, -1 on failure (for example if the output * string was too short). */ -int -make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, - int local, PANDAS_DATETIMEUNIT base, int tzoffset, - NPY_CASTING casting) -{ +int make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, + int local, PANDAS_DATETIMEUNIT base, int tzoffset, + NPY_CASTING casting) { pandas_datetimestruct dts_local; int timezone_offset = 0; @@ -1160,10 +1110,9 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, /* Set dts to point to our local time instead of the UTC time */ dts = &dts_local; - } - /* Use the manually provided tzoffset */ - else if (local) { - /* Make a copy of the pandas_datetimestruct we can modify */ + } else if (local) { + // Use the manually provided tzoffset. + // Make a copy of the pandas_datetimestruct we can modify. dts_local = *dts; dts = &dts_local; @@ -1180,22 +1129,23 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, if (casting != NPY_UNSAFE_CASTING) { /* Producing a date as a local time is always 'unsafe' */ if (base <= PANDAS_FR_D && local) { - PyErr_SetString(PyExc_TypeError, "Cannot create a local " - "timezone-based date string from a NumPy " - "datetime without forcing 'unsafe' casting"); + PyErr_SetString(PyExc_TypeError, + "Cannot create a local " + "timezone-based date string from a NumPy " + "datetime without forcing 'unsafe' casting"); return -1; - } - /* Only 'unsafe' and 'same_kind' allow data loss */ - else { + } else { + /* Only 'unsafe' and 'same_kind' allow data loss */ PANDAS_DATETIMEUNIT unitprec; unitprec = lossless_unit_from_datetimestruct(dts); if (casting != NPY_SAME_KIND_CASTING && unitprec > base) { - PyErr_Format(PyExc_TypeError, "Cannot create a " - "string with unit precision '%s' " - "from the NumPy datetime, which has data at " - "unit precision '%s', " - "requires 'unsafe' or 'same_kind' casting", + PyErr_Format(PyExc_TypeError, + "Cannot create a " + "string with unit precision '%s' " + "from the NumPy datetime, which has data at " + "unit precision '%s', " + "requires 'unsafe' or 'same_kind' casting", _datetime_strings[base], _datetime_strings[unitprec]); return -1; @@ -1203,12 +1153,12 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } } - /* YEAR */ - /* - * Can't use PyOS_snprintf, because it always produces a '\0' - * character at the end, and NumPy string types are permitted - * to have data all the way to the end of the buffer. - */ +/* YEAR */ +/* + * Can't use PyOS_snprintf, because it always produces a '\0' + * character at the end, and NumPy string types are permitted + * to have data all the way to the end of the buffer. + */ #ifdef _WIN32 tmplen = _snprintf(substr, sublen, "%04" NPY_INT64_FMT, dts->year); #else @@ -1230,15 +1180,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* MONTH */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = '-'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->month / 10) + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->month % 10) + '0'); @@ -1254,15 +1204,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* DAY */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = '-'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->day / 10) + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->day % 10) + '0'); @@ -1278,15 +1228,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* HOUR */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = 'T'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->hour / 10) + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->hour % 10) + '0'); @@ -1299,15 +1249,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* MINUTE */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = ':'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->min / 10) + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->min % 10) + '0'); @@ -1320,15 +1270,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* SECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = ':'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->sec / 10) + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->sec % 10) + '0'); @@ -1341,19 +1291,19 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* MILLISECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = '.'; - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->us / 100000) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->us / 10000) % 10 + '0'); - if (sublen < 4 ) { + if (sublen < 4) { goto string_too_short; } substr[3] = (char)((dts->us / 1000) % 10 + '0'); @@ -1366,15 +1316,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* MICROSECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = (char)((dts->us / 100) % 10 + '0'); - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->us / 10) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)(dts->us % 10 + '0'); @@ -1387,15 +1337,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* NANOSECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = (char)((dts->ps / 100000) % 10 + '0'); - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->ps / 10000) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->ps / 1000) % 10 + '0'); @@ -1408,15 +1358,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* PICOSECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = (char)((dts->ps / 100) % 10 + '0'); - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->ps / 10) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)(dts->ps % 10 + '0'); @@ -1429,15 +1379,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* FEMTOSECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = (char)((dts->as / 100000) % 10 + '0'); - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->as / 10000) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)((dts->as / 1000) % 10 + '0'); @@ -1450,15 +1400,15 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, } /* ATTOSECOND */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } substr[0] = (char)((dts->as / 100) % 10 + '0'); - if (sublen < 2 ) { + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((dts->as / 10) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)(dts->as % 10 + '0'); @@ -1474,35 +1424,33 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, if (timezone_offset < 0) { substr[0] = '-'; timezone_offset = -timezone_offset; - } - else { + } else { substr[0] = '+'; } substr += 1; sublen -= 1; /* Add the timezone offset */ - if (sublen < 1 ) { + if (sublen < 1) { goto string_too_short; } - substr[0] = (char)((timezone_offset / (10*60)) % 10 + '0'); - if (sublen < 2 ) { + substr[0] = (char)((timezone_offset / (10 * 60)) % 10 + '0'); + if (sublen < 2) { goto string_too_short; } substr[1] = (char)((timezone_offset / 60) % 10 + '0'); - if (sublen < 3 ) { + if (sublen < 3) { goto string_too_short; } substr[2] = (char)(((timezone_offset % 60) / 10) % 10 + '0'); - if (sublen < 4 ) { + if (sublen < 4) { goto string_too_short; } substr[3] = (char)((timezone_offset % 60) % 10 + '0'); substr += 4; sublen -= 4; - } - /* UTC "Zulu" time */ - else { + } else { + /* UTC "Zulu" time */ if (sublen < 1) { goto string_too_short; } @@ -1520,8 +1468,8 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, string_too_short: PyErr_Format(PyExc_RuntimeError, - "The string provided for NumPy ISO datetime formatting " - "was too short, with length %d", - outlen); + "The string provided for NumPy ISO datetime formatting " + "was too short, with length %d", + outlen); return -1; } diff --git a/pandas/src/datetime/np_datetime_strings.h b/pandas/src/datetime/np_datetime_strings.h index 0d9a0944310fb..1114ec5eae064 100644 --- a/pandas/src/datetime/np_datetime_strings.h +++ b/pandas/src/datetime/np_datetime_strings.h @@ -1,9 +1,26 @@ /* - * This is derived from numpy 1.7. See NP_LICENSE.txt - */ -#ifndef _NPY_PRIVATE__DATETIME_STRINGS_H_ -#define _NPY_PRIVATE__DATETIME_STRINGS_H_ +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. + +Written by Mark Wiebe (mwwiebe@gmail.com) +Copyright (c) 2011 by Enthought, Inc. + +Copyright (c) 2005-2011, NumPy Developers +All rights reserved. + +See NUMPY_LICENSE.txt for the license. + +This file implements string parsing and creation for NumPy datetime. + +*/ + +#ifndef PANDAS_SRC_DATETIME_NP_DATETIME_STRINGS_H_ +#define PANDAS_SRC_DATETIME_NP_DATETIME_STRINGS_H_ /* * Parses (almost) standard ISO 8601 date strings. The differences are: @@ -86,4 +103,4 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, int local, PANDAS_DATETIMEUNIT base, int tzoffset, NPY_CASTING casting); -#endif +#endif // PANDAS_SRC_DATETIME_NP_DATETIME_STRINGS_H_ diff --git a/pandas/src/datetime_helper.h b/pandas/src/datetime_helper.h index 11399181fa4e7..2b24028ff3d8c 100644 --- a/pandas/src/datetime_helper.h +++ b/pandas/src/datetime_helper.h @@ -1,7 +1,19 @@ +/* +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. +*/ + +#ifndef PANDAS_SRC_DATETIME_HELPER_H_ +#define PANDAS_SRC_DATETIME_HELPER_H_ + +#include #include "datetime.h" #include "numpy/arrayobject.h" #include "numpy/arrayscalars.h" -#include #if PY_MAJOR_VERSION >= 3 #define PyInt_AS_LONG PyLong_AsLong @@ -10,7 +22,8 @@ npy_int64 get_long_attr(PyObject *o, const char *attr) { npy_int64 long_val; PyObject *value = PyObject_GetAttrString(o, attr); - long_val = (PyLong_Check(value) ? PyLong_AsLongLong(value) : PyInt_AS_LONG(value)); + long_val = (PyLong_Check(value) ? + PyLong_AsLongLong(value) : PyInt_AS_LONG(value)); Py_DECREF(value); return long_val; } @@ -23,3 +36,5 @@ npy_float64 total_seconds(PyObject *td) { npy_int64 days_in_seconds = days * 24LL * 3600LL; return (microseconds + (seconds + days_in_seconds) * 1000000.0) / 1000000.0; } + +#endif // PANDAS_SRC_DATETIME_HELPER_H_ diff --git a/pandas/src/helper.h b/pandas/src/helper.h index b8c3cecbb2dc7..39bcf27e074df 100644 --- a/pandas/src/helper.h +++ b/pandas/src/helper.h @@ -1,16 +1,25 @@ -#ifndef C_HELPER_H -#define C_HELPER_H +/* +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. +*/ + +#ifndef PANDAS_SRC_HELPER_H_ +#define PANDAS_SRC_HELPER_H_ #ifndef PANDAS_INLINE #if defined(__GNUC__) #define PANDAS_INLINE static __inline__ #elif defined(_MSC_VER) #define PANDAS_INLINE static __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define PANDAS_INLINE static inline #else #define PANDAS_INLINE #endif #endif -#endif +#endif // PANDAS_SRC_HELPER_H_ diff --git a/pandas/src/numpy_helper.h b/pandas/src/numpy_helper.h index 9f406890c4e68..17d5ec12f4f79 100644 --- a/pandas/src/numpy_helper.h +++ b/pandas/src/numpy_helper.h @@ -1,7 +1,19 @@ +/* +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. +*/ + +#ifndef PANDAS_SRC_NUMPY_HELPER_H_ +#define PANDAS_SRC_NUMPY_HELPER_H_ + #include "Python.h" +#include "helper.h" #include "numpy/arrayobject.h" #include "numpy/arrayscalars.h" -#include "helper.h" #define PANDAS_FLOAT 0 #define PANDAS_INT 1 @@ -10,111 +22,87 @@ #define PANDAS_OBJECT 4 #define PANDAS_DATETIME 5 -PANDAS_INLINE int -infer_type(PyObject* obj) { - if (PyBool_Check(obj)) { - return PANDAS_BOOL; - } - else if (PyArray_IsIntegerScalar(obj)) { - return PANDAS_INT; - } - else if (PyArray_IsScalar(obj, Datetime)) { - return PANDAS_DATETIME; - } - else if (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)) { - return PANDAS_FLOAT; - } - else if (PyString_Check(obj) || PyUnicode_Check(obj)) { - return PANDAS_STRING; - } - else { - return PANDAS_OBJECT; - } +PANDAS_INLINE int infer_type(PyObject* obj) { + if (PyBool_Check(obj)) { + return PANDAS_BOOL; + } else if (PyArray_IsIntegerScalar(obj)) { + return PANDAS_INT; + } else if (PyArray_IsScalar(obj, Datetime)) { + return PANDAS_DATETIME; + } else if (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)) { + return PANDAS_FLOAT; + } else if (PyString_Check(obj) || PyUnicode_Check(obj)) { + return PANDAS_STRING; + } else { + return PANDAS_OBJECT; + } } -PANDAS_INLINE npy_int64 -get_nat(void) { - return NPY_MIN_INT64; -} +PANDAS_INLINE npy_int64 get_nat(void) { return NPY_MIN_INT64; } -PANDAS_INLINE npy_datetime -get_datetime64_value(PyObject* obj) { - return ((PyDatetimeScalarObject*) obj)->obval; +PANDAS_INLINE npy_datetime get_datetime64_value(PyObject* obj) { + return ((PyDatetimeScalarObject*)obj)->obval; } -PANDAS_INLINE npy_timedelta -get_timedelta64_value(PyObject* obj) { - return ((PyTimedeltaScalarObject*) obj)->obval; +PANDAS_INLINE npy_timedelta get_timedelta64_value(PyObject* obj) { + return ((PyTimedeltaScalarObject*)obj)->obval; } -PANDAS_INLINE int -is_integer_object(PyObject* obj) { - return (!PyBool_Check(obj)) && PyArray_IsIntegerScalar(obj); -// return PyArray_IsIntegerScalar(obj); +PANDAS_INLINE int is_integer_object(PyObject* obj) { + return (!PyBool_Check(obj)) && PyArray_IsIntegerScalar(obj); } -PANDAS_INLINE int -is_float_object(PyObject* obj) { - return (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)); +PANDAS_INLINE int is_float_object(PyObject* obj) { + return (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)); } -PANDAS_INLINE int -is_complex_object(PyObject* obj) { - return (PyComplex_Check(obj) || PyArray_IsScalar(obj, ComplexFloating)); +PANDAS_INLINE int is_complex_object(PyObject* obj) { + return (PyComplex_Check(obj) || PyArray_IsScalar(obj, ComplexFloating)); } -PANDAS_INLINE int -is_bool_object(PyObject* obj) { - return (PyBool_Check(obj) || PyArray_IsScalar(obj, Bool)); +PANDAS_INLINE int is_bool_object(PyObject* obj) { + return (PyBool_Check(obj) || PyArray_IsScalar(obj, Bool)); } -PANDAS_INLINE int -is_string_object(PyObject* obj) { - return (PyString_Check(obj) || PyUnicode_Check(obj)); +PANDAS_INLINE int is_string_object(PyObject* obj) { + return (PyString_Check(obj) || PyUnicode_Check(obj)); } -PANDAS_INLINE int -is_datetime64_object(PyObject *obj) { - return PyArray_IsScalar(obj, Datetime); +PANDAS_INLINE int is_datetime64_object(PyObject* obj) { + return PyArray_IsScalar(obj, Datetime); } -PANDAS_INLINE int -is_timedelta64_object(PyObject *obj) { - return PyArray_IsScalar(obj, Timedelta); +PANDAS_INLINE int is_timedelta64_object(PyObject* obj) { + return PyArray_IsScalar(obj, Timedelta); } -PANDAS_INLINE int -assign_value_1d(PyArrayObject* ap, Py_ssize_t _i, PyObject* v) { - npy_intp i = (npy_intp) _i; - char *item = (char *) PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0); - return PyArray_DESCR(ap)->f->setitem(v, item, ap); +PANDAS_INLINE int assign_value_1d(PyArrayObject* ap, Py_ssize_t _i, + PyObject* v) { + npy_intp i = (npy_intp)_i; + char* item = (char*)PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0); + return PyArray_DESCR(ap)->f->setitem(v, item, ap); } -PANDAS_INLINE PyObject* -get_value_1d(PyArrayObject* ap, Py_ssize_t i) { - char *item = (char *) PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0); - return PyArray_Scalar(item, PyArray_DESCR(ap), (PyObject*) ap); +PANDAS_INLINE PyObject* get_value_1d(PyArrayObject* ap, Py_ssize_t i) { + char* item = (char*)PyArray_DATA(ap) + i * PyArray_STRIDE(ap, 0); + return PyArray_Scalar(item, PyArray_DESCR(ap), (PyObject*)ap); } - -PANDAS_INLINE char* -get_c_string(PyObject* obj) { +PANDAS_INLINE char* get_c_string(PyObject* obj) { #if PY_VERSION_HEX >= 0x03000000 - PyObject* enc_str = PyUnicode_AsEncodedString(obj, "utf-8", "error"); + PyObject* enc_str = PyUnicode_AsEncodedString(obj, "utf-8", "error"); - char *ret; - ret = PyBytes_AS_STRING(enc_str); + char* ret; + ret = PyBytes_AS_STRING(enc_str); - // TODO: memory leak here + // TODO(general): memory leak here - // Py_XDECREF(enc_str); - return ret; + return ret; #else - return PyString_AsString(obj); + return PyString_AsString(obj); #endif } -PANDAS_INLINE PyObject* -char_to_string(char* data) { +PANDAS_INLINE PyObject* char_to_string(char* data) { #if PY_VERSION_HEX >= 0x03000000 return PyUnicode_FromString(data); #else @@ -122,61 +110,47 @@ char_to_string(char* data) { #endif } -// PANDAS_INLINE int -// is_string(PyObject* obj) { -// #if PY_VERSION_HEX >= 0x03000000 -// return PyUnicode_Check(obj); -// #else -// return PyString_Check(obj); -// #endif - -PyObject* sarr_from_data(PyArray_Descr *descr, int length, void* data) { - PyArrayObject *result; +PyObject* sarr_from_data(PyArray_Descr* descr, int length, void* data) { + PyArrayObject* result; npy_intp dims[1] = {length}; - Py_INCREF(descr); // newfromdescr steals a reference to descr - result = (PyArrayObject*) PyArray_NewFromDescr(&PyArray_Type, descr, 1, dims, - NULL, data, 0, NULL); + Py_INCREF(descr); // newfromdescr steals a reference to descr + result = (PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, descr, 1, dims, + NULL, data, 0, NULL); // Returned array doesn't own data by default result->flags |= NPY_OWNDATA; - return (PyObject*) result; + return (PyObject*)result; } - -void transfer_object_column(char *dst, char *src, size_t stride, +void transfer_object_column(char* dst, char* src, size_t stride, size_t length) { int i; size_t sz = sizeof(PyObject*); - for (i = 0; i < length; ++i) - { + for (i = 0; i < length; ++i) { // uninitialized data // Py_XDECREF(*((PyObject**) dst)); memcpy(dst, src, sz); - Py_INCREF(*((PyObject**) dst)); + Py_INCREF(*((PyObject**)dst)); src += sz; dst += stride; } } -void set_array_owndata(PyArrayObject *ao) { - ao->flags |= NPY_OWNDATA; -} +void set_array_owndata(PyArrayObject* ao) { ao->flags |= NPY_OWNDATA; } -void set_array_not_contiguous(PyArrayObject *ao) { +void set_array_not_contiguous(PyArrayObject* ao) { ao->flags &= ~(NPY_C_CONTIGUOUS | NPY_F_CONTIGUOUS); } - // If arr is zerodim array, return a proper array scalar (e.g. np.int64). // Otherwise, return arr as is. -PANDAS_INLINE PyObject* -unbox_if_zerodim(PyObject* arr) { +PANDAS_INLINE PyObject* unbox_if_zerodim(PyObject* arr) { if (PyArray_IsZeroDim(arr)) { - PyObject *ret; + PyObject* ret; ret = PyArray_ToScalar(PyArray_DATA(arr), arr); return ret; } else { @@ -185,20 +159,4 @@ unbox_if_zerodim(PyObject* arr) { } } - -// PANDAS_INLINE PyObject* -// get_base_ndarray(PyObject* ap) { -// // if (!ap || (NULL == ap)) { -// // Py_RETURN_NONE; -// // } - -// while (!PyArray_CheckExact(ap)) { -// ap = PyArray_BASE((PyArrayObject*) ap); -// if (ap == Py_None) Py_RETURN_NONE; -// } -// // PyArray_BASE is a borrowed reference -// if(ap) { -// Py_INCREF(ap); -// } -// return ap; -// } +#endif // PANDAS_SRC_NUMPY_HELPER_H_ diff --git a/pandas/src/parse_helper.h b/pandas/src/parse_helper.h index e565f02f27c88..5d2a0dad3da17 100644 --- a/pandas/src/parse_helper.h +++ b/pandas/src/parse_helper.h @@ -1,3 +1,15 @@ +/* +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. +*/ + +#ifndef PANDAS_SRC_PARSE_HELPER_H_ +#define PANDAS_SRC_PARSE_HELPER_H_ + #include #include #include "headers/portable.h" @@ -5,8 +17,8 @@ static double xstrtod(const char *p, char **q, char decimal, char sci, int skip_trailing, int *maybe_int); -int to_double(char *item, double *p_value, char sci, char decimal, int *maybe_int) -{ +int to_double(char *item, double *p_value, char sci, char decimal, + int *maybe_int) { char *p_end = NULL; *p_value = xstrtod(item, &p_end, decimal, sci, 1, maybe_int); @@ -15,14 +27,14 @@ int to_double(char *item, double *p_value, char sci, char decimal, int *maybe_in } #if PY_VERSION_HEX < 0x02060000 - #define PyBytes_Check PyString_Check - #define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_Check PyString_Check +#define PyBytes_AS_STRING PyString_AS_STRING #endif -int floatify(PyObject* str, double *result, int *maybe_int) { +int floatify(PyObject *str, double *result, int *maybe_int) { int status; char *data; - PyObject* tmp = NULL; + PyObject *tmp = NULL; const char sci = 'E'; const char dec = '.'; @@ -70,17 +82,15 @@ int floatify(PyObject* str, double *result, int *maybe_int) { Py_XDECREF(tmp); return -1; -/* -#if PY_VERSION_HEX >= 0x03000000 - return PyFloat_FromString(str); -#else - return PyFloat_FromString(str, NULL); -#endif -*/ - + /* + #if PY_VERSION_HEX >= 0x03000000 + return PyFloat_FromString(str); + #else + return PyFloat_FromString(str, NULL); + #endif + */ } - // --------------------------------------------------------------------------- // Implementation of xstrtod @@ -104,10 +114,12 @@ int floatify(PyObject* str, double *result, int *maybe_int) { // may be used to endorse or promote products derived from this software // without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -125,149 +137,137 @@ int floatify(PyObject* str, double *result, int *maybe_int) { // PANDAS_INLINE void lowercase(char *p) { - for ( ; *p; ++p) *p = tolower(*p); + for (; *p; ++p) *p = tolower(*p); } PANDAS_INLINE void uppercase(char *p) { - for ( ; *p; ++p) *p = toupper(*p); + for (; *p; ++p) *p = toupper(*p); } +static double xstrtod(const char *str, char **endptr, char decimal, char sci, + int skip_trailing, int *maybe_int) { + double number; + int exponent; + int negative; + char *p = (char *)str; + double p10; + int n; + int num_digits; + int num_decimals; + + errno = 0; + *maybe_int = 1; -static double xstrtod(const char *str, char **endptr, char decimal, - char sci, int skip_trailing, int *maybe_int) -{ - double number; - int exponent; - int negative; - char *p = (char *) str; - double p10; - int n; - int num_digits; - int num_decimals; - - errno = 0; - *maybe_int = 1; - - // Skip leading whitespace - while (isspace(*p)) p++; - - // Handle optional sign - negative = 0; - switch (*p) - { - case '-': negative = 1; // Fall through to increment position - case '+': p++; - } - - number = 0.; - exponent = 0; - num_digits = 0; - num_decimals = 0; - - // Process string of digits - while (isdigit(*p)) - { - number = number * 10. + (*p - '0'); - p++; - num_digits++; - } - - // Process decimal part - if (*p == decimal) - { - *maybe_int = 0; - p++; - - while (isdigit(*p)) - { - number = number * 10. + (*p - '0'); - p++; - num_digits++; - num_decimals++; + // Skip leading whitespace + while (isspace(*p)) p++; + + // Handle optional sign + negative = 0; + switch (*p) { + case '-': + negative = 1; // Fall through to increment position + case '+': + p++; } - exponent -= num_decimals; - } + number = 0.; + exponent = 0; + num_digits = 0; + num_decimals = 0; - if (num_digits == 0) - { - errno = ERANGE; - return 0.0; - } + // Process string of digits + while (isdigit(*p)) { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + } - // Correct for sign - if (negative) number = -number; + // Process decimal part + if (*p == decimal) { + *maybe_int = 0; + p++; - // Process an exponent string - if (toupper(*p) == toupper(sci)) - { - *maybe_int = 0; + while (isdigit(*p)) { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + num_decimals++; + } - // Handle optional sign - negative = 0; - switch (*++p) - { - case '-': negative = 1; // Fall through to increment pos - case '+': p++; + exponent -= num_decimals; } - // Process string of digits - num_digits = 0; - n = 0; - while (isdigit(*p)) - { - n = n * 10 + (*p - '0'); - num_digits++; - p++; + if (num_digits == 0) { + errno = ERANGE; + return 0.0; } - if (negative) - exponent -= n; - else - exponent += n; - - // If no digits, after the 'e'/'E', un-consume it - if (num_digits == 0) - p--; - } - - - if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) - { - - errno = ERANGE; - return HUGE_VAL; - } - - // Scale the result - p10 = 10.; - n = exponent; - if (n < 0) n = -n; - while (n) - { - if (n & 1) - { - if (exponent < 0) - number /= p10; - else - number *= p10; + // Correct for sign + if (negative) number = -number; + + // Process an exponent string + if (toupper(*p) == toupper(sci)) { + *maybe_int = 0; + + // Handle optional sign + negative = 0; + switch (*++p) { + case '-': + negative = 1; // Fall through to increment pos + case '+': + p++; + } + + // Process string of digits + num_digits = 0; + n = 0; + while (isdigit(*p)) { + n = n * 10 + (*p - '0'); + num_digits++; + p++; + } + + if (negative) + exponent -= n; + else + exponent += n; + + // If no digits, after the 'e'/'E', un-consume it + if (num_digits == 0) p--; } - n >>= 1; - p10 *= p10; - } + if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) { + errno = ERANGE; + return HUGE_VAL; + } - if (number == HUGE_VAL) { - errno = ERANGE; - } + // Scale the result + p10 = 10.; + n = exponent; + if (n < 0) n = -n; + while (n) { + if (n & 1) { + if (exponent < 0) + number /= p10; + else + number *= p10; + } + n >>= 1; + p10 *= p10; + } - if (skip_trailing) { - // Skip trailing whitespace - while (isspace(*p)) p++; - } + if (number == HUGE_VAL) { + errno = ERANGE; + } - if (endptr) *endptr = p; + if (skip_trailing) { + // Skip trailing whitespace + while (isspace(*p)) p++; + } + if (endptr) *endptr = p; - return number; + return number; } + +#endif // PANDAS_SRC_PARSE_HELPER_H_ diff --git a/pandas/src/period_helper.c b/pandas/src/period_helper.c index 6078be6fc3d19..19f810eb54ea7 100644 --- a/pandas/src/period_helper.c +++ b/pandas/src/period_helper.c @@ -1,30 +1,37 @@ -#include "period_helper.h" +/* +Copyright (c) 2016, PyData Development Team +All rights reserved. +Distributed under the terms of the BSD Simplified License. -/* - * Borrowed and derived code from scikits.timeseries that we will expose via - * Cython to pandas. This primarily concerns period representation and - * frequency conversion routines. - */ +The full license is in the LICENSE file, distributed with this software. -/* see end of file for stuff pandas uses (search for 'pandas') */ +Borrowed and derived code from scikits.timeseries that we will expose via +Cython to pandas. This primarily concerns interval representation and +frequency conversion routines. + +See end of file for stuff pandas uses (search for 'pandas'). +*/ + +#include "period_helper.h" /* ------------------------------------------------------------------ * Code derived from scikits.timeseries * ------------------------------------------------------------------*/ static int mod_compat(int x, int m) { - int result = x % m; - if (result < 0) return result + m; - return result; + int result = x % m; + if (result < 0) return result + m; + return result; } static int floordiv(int x, int divisor) { if (x < 0) { if (mod_compat(x, divisor)) { return x / divisor - 1; + } else { + return x / divisor; } - else return x / divisor; } else { return x / divisor; } @@ -32,19 +39,16 @@ static int floordiv(int x, int divisor) { /* Table with day offsets for each month (0-based, without and with leap) */ static int month_offset[2][13] = { - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } -}; + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}}; /* Table of number of days in a month (0-based, without and with leap) */ static int days_in_month[2][12] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; /* Return 1/0 iff year points to a leap year in calendar. */ -static int dInfoCalc_Leapyear(npy_int64 year, int calendar) -{ +static int dInfoCalc_Leapyear(npy_int64 year, int calendar) { if (calendar == GREGORIAN_CALENDAR) { return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); } else { @@ -53,8 +57,7 @@ static int dInfoCalc_Leapyear(npy_int64 year, int calendar) } /* Return the day of the week for the given absolute date. */ -static int dInfoCalc_DayOfWeek(npy_int64 absdate) -{ +static int dInfoCalc_DayOfWeek(npy_int64 absdate) { int day_of_week; if (absdate >= 1) { @@ -65,7 +68,7 @@ static int dInfoCalc_DayOfWeek(npy_int64 absdate) return day_of_week; } -static int monthToQuarter(int month) { return ((month-1)/3)+1; } +static int monthToQuarter(int month) { return ((month - 1) / 3) + 1; } /* Return the year offset, that is the absolute date of the day 31.12.(year-1) in the given calendar. @@ -75,23 +78,22 @@ static int monthToQuarter(int month) { return ((month-1)/3)+1; } using the Gregorian Epoch) value by two days because the Epoch (0001-01-01) in the Julian calendar lies 2 days before the Epoch in the Gregorian calendar. */ -static int dInfoCalc_YearOffset(npy_int64 year, int calendar) -{ +static int dInfoCalc_YearOffset(npy_int64 year, int calendar) { year--; if (calendar == GREGORIAN_CALENDAR) { - if (year >= 0 || -1/4 == -1) - return year*365 + year/4 - year/100 + year/400; - else - return year*365 + (year-3)/4 - (year-99)/100 + (year-399)/400; - } - else if (calendar == JULIAN_CALENDAR) { - if (year >= 0 || -1/4 == -1) - return year*365 + year/4 - 2; - else - return year*365 + (year-3)/4 - 2; + if (year >= 0 || -1 / 4 == -1) + return year * 365 + year / 4 - year / 100 + year / 400; + else + return year * 365 + (year - 3) / 4 - (year - 99) / 100 + + (year - 399) / 400; + } else if (calendar == JULIAN_CALENDAR) { + if (year >= 0 || -1 / 4 == -1) + return year * 365 + year / 4 - 2; + else + return year * 365 + (year - 3) / 4 - 2; } Py_Error(PyExc_ValueError, "unknown calendar"); - onError: +onError: return INT_ERR_CODE; } @@ -99,39 +101,32 @@ static int dInfoCalc_YearOffset(npy_int64 year, int calendar) * to the flags: GREGORIAN_CALENDAR, JULIAN_CALENDAR to indicate the calendar * to be used. */ -static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, - int year, int month, int day, int hour, int minute, double second, - int calendar) -{ - +static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, int year, + int month, int day, int hour, + int minute, double second, + int calendar) { /* Calculate the absolute date */ { int leap; - npy_int64 absdate; + npy_int64 absdate; int yearoffset; /* Range check */ - Py_AssertWithArg(year > -(INT_MAX / 366) && year < (INT_MAX / 366), - PyExc_ValueError, - "year out of range: %i", - year); + Py_AssertWithArg(year > -(INT_MAX / 366) && year < (INT_MAX / 366), + PyExc_ValueError, "year out of range: %i", year); /* Is it a leap year ? */ leap = dInfoCalc_Leapyear(year, calendar); /* Negative month values indicate months relative to the years end */ if (month < 0) month += 13; - Py_AssertWithArg(month >= 1 && month <= 12, - PyExc_ValueError, - "month out of range (1-12): %i", - month); + Py_AssertWithArg(month >= 1 && month <= 12, PyExc_ValueError, + "month out of range (1-12): %i", month); /* Negative values indicate days relative to the months end */ if (day < 0) day += days_in_month[leap][month - 1] + 1; Py_AssertWithArg(day >= 1 && day <= days_in_month[leap][month - 1], - PyExc_ValueError, - "day out of range: %i", - day); + PyExc_ValueError, "day out of range: %i", day); yearoffset = dInfoCalc_YearOffset(year, calendar); if (yearoffset == INT_ERR_CODE) goto onError; @@ -142,7 +137,7 @@ static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, dinfo->year = year; dinfo->month = month; - dinfo->quarter = ((month-1)/3)+1; + dinfo->quarter = ((month - 1) / 3) + 1; dinfo->day = day; dinfo->day_of_week = dInfoCalc_DayOfWeek(absdate); @@ -153,23 +148,18 @@ static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, /* Calculate the absolute time */ { - Py_AssertWithArg(hour >= 0 && hour <= 23, - PyExc_ValueError, - "hour out of range (0-23): %i", - hour); - Py_AssertWithArg(minute >= 0 && minute <= 59, - PyExc_ValueError, - "minute out of range (0-59): %i", - minute); - Py_AssertWithArg(second >= (double)0.0 && + Py_AssertWithArg(hour >= 0 && hour <= 23, PyExc_ValueError, + "hour out of range (0-23): %i", hour); + Py_AssertWithArg(minute >= 0 && minute <= 59, PyExc_ValueError, + "minute out of range (0-59): %i", minute); + Py_AssertWithArg( + second >= (double)0.0 && (second < (double)60.0 || - (hour == 23 && minute == 59 && - second < (double)61.0)), - PyExc_ValueError, - "second out of range (0.0 - <60.0; <61.0 for 23:59): %f", - second); + (hour == 23 && minute == 59 && second < (double)61.0)), + PyExc_ValueError, + "second out of range (0.0 - <60.0; <61.0 for 23:59): %f", second); - dinfo->abstime = (double)(hour*3600 + minute*60) + second; + dinfo->abstime = (double)(hour * 3600 + minute * 60) + second; dinfo->hour = hour; dinfo->minute = minute; @@ -177,7 +167,7 @@ static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, } return 0; - onError: +onError: return INT_ERR_CODE; } @@ -186,13 +176,11 @@ static int dInfoCalc_SetFromDateAndTime(struct date_info *dinfo, XXX This could also be done using some integer arithmetics rather than with this iterative approach... */ -static -int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo, - npy_int64 absdate, int calendar) -{ +static int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo, + npy_int64 absdate, int calendar) { register npy_int64 year; npy_int64 yearoffset; - int leap,dayoffset; + int leap, dayoffset; int *monthoffset; /* Approximate year */ @@ -220,7 +208,7 @@ int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo, } dayoffset = absdate - yearoffset; - leap = dInfoCalc_Leapyear(year,calendar); + leap = dInfoCalc_Leapyear(year, calendar); /* Forward correction: non leap years only have 365 days */ if (dayoffset > 365 && !leap) { @@ -239,23 +227,21 @@ int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo, register int month; for (month = 1; month < 13; month++) { - if (monthoffset[month] >= dayoffset) - break; + if (monthoffset[month] >= dayoffset) break; } dinfo->month = month; dinfo->quarter = monthToQuarter(month); - dinfo->day = dayoffset - month_offset[leap][month-1]; + dinfo->day = dayoffset - month_offset[leap][month - 1]; } - dinfo->day_of_week = dInfoCalc_DayOfWeek(absdate); dinfo->day_of_year = dayoffset; dinfo->absdate = absdate; return 0; - onError: +onError: return INT_ERR_CODE; } @@ -269,39 +255,25 @@ int dInfoCalc_SetFromAbsDate(register struct date_info *dinfo, // helpers for frequency conversion routines // static int daytime_conversion_factors[][2] = { - { FR_DAY, 1 }, - { FR_HR, 24 }, - { FR_MIN, 60 }, - { FR_SEC, 60 }, - { FR_MS, 1000 }, - { FR_US, 1000 }, - { FR_NS, 1000 }, - { 0, 0 } -}; + {FR_DAY, 1}, {FR_HR, 24}, {FR_MIN, 60}, {FR_SEC, 60}, + {FR_MS, 1000}, {FR_US, 1000}, {FR_NS, 1000}, {0, 0}}; -static npy_int64** daytime_conversion_factor_matrix = NULL; +static npy_int64 **daytime_conversion_factor_matrix = NULL; -PANDAS_INLINE int max_value(int a, int b) { - return a > b ? a : b; -} +PANDAS_INLINE int max_value(int a, int b) { return a > b ? a : b; } -PANDAS_INLINE int min_value(int a, int b) { - return a < b ? a : b; -} +PANDAS_INLINE int min_value(int a, int b) { return a < b ? a : b; } -PANDAS_INLINE int get_freq_group(int freq) { - return (freq/1000)*1000; -} +PANDAS_INLINE int get_freq_group(int freq) { return (freq / 1000) * 1000; } -PANDAS_INLINE int get_freq_group_index(int freq) { - return freq/1000; -} +PANDAS_INLINE int get_freq_group_index(int freq) { return freq / 1000; } static int calc_conversion_factors_matrix_size(void) { int matrix_size = 0; int index; - for (index=0;; index++) { - int period_value = get_freq_group_index(daytime_conversion_factors[index][0]); + for (index = 0;; index++) { + int period_value = + get_freq_group_index(daytime_conversion_factors[index][0]); if (period_value == 0) { break; } @@ -313,9 +285,11 @@ static int calc_conversion_factors_matrix_size(void) { static void alloc_conversion_factors_matrix(int matrix_size) { int row_index; int column_index; - daytime_conversion_factor_matrix = malloc(matrix_size * sizeof(**daytime_conversion_factor_matrix)); + daytime_conversion_factor_matrix = + malloc(matrix_size * sizeof(**daytime_conversion_factor_matrix)); for (row_index = 0; row_index < matrix_size; row_index++) { - daytime_conversion_factor_matrix[row_index] = malloc(matrix_size * sizeof(**daytime_conversion_factor_matrix)); + daytime_conversion_factor_matrix[row_index] = + malloc(matrix_size * sizeof(**daytime_conversion_factor_matrix)); for (column_index = 0; column_index < matrix_size; column_index++) { daytime_conversion_factor_matrix[row_index][column_index] = 0; } @@ -325,7 +299,7 @@ static void alloc_conversion_factors_matrix(int matrix_size) { static npy_int64 calculate_conversion_factor(int start_value, int end_value) { npy_int64 conversion_factor = 0; int index; - for (index=0;; index++) { + for (index = 0;; index++) { int freq_group = daytime_conversion_factors[index][0]; if (freq_group == 0) { @@ -348,11 +322,11 @@ static npy_int64 calculate_conversion_factor(int start_value, int end_value) { static void populate_conversion_factors_matrix(void) { int row_index_index; - int row_value, row_index; + int row_value, row_index; int column_index_index; - int column_value, column_index; + int column_value, column_index; - for (row_index_index = 0;; row_index_index++) { + for (row_index_index = 0;; row_index_index++) { row_value = daytime_conversion_factors[row_index_index][0]; if (row_value == 0) { break; @@ -365,7 +339,8 @@ static void populate_conversion_factors_matrix(void) { } column_index = get_freq_group_index(column_value); - daytime_conversion_factor_matrix[row_index][column_index] = calculate_conversion_factor(row_value, column_value); + daytime_conversion_factor_matrix[row_index][column_index] = + calculate_conversion_factor(row_value, column_value); } } } @@ -378,13 +353,14 @@ void initialize_daytime_conversion_factor_matrix() { } } -PANDAS_INLINE npy_int64 get_daytime_conversion_factor(int from_index, int to_index) -{ - return daytime_conversion_factor_matrix[min_value(from_index, to_index)][max_value(from_index, to_index)]; +PANDAS_INLINE npy_int64 get_daytime_conversion_factor(int from_index, + int to_index) { + return daytime_conversion_factor_matrix[min_value(from_index, to_index)] + [max_value(from_index, to_index)]; } -PANDAS_INLINE npy_int64 upsample_daytime(npy_int64 ordinal, asfreq_info *af_info, int atEnd) -{ +PANDAS_INLINE npy_int64 upsample_daytime(npy_int64 ordinal, + asfreq_info *af_info, int atEnd) { if (atEnd) { return (ordinal + 1) * af_info->intraday_conversion_factor - 1; } else { @@ -392,14 +368,19 @@ PANDAS_INLINE npy_int64 upsample_daytime(npy_int64 ordinal, asfreq_info *af_info } } -PANDAS_INLINE npy_int64 downsample_daytime(npy_int64 ordinal, asfreq_info *af_info, int atEnd) -{ +PANDAS_INLINE npy_int64 downsample_daytime(npy_int64 ordinal, + asfreq_info *af_info, int atEnd) { return ordinal / (af_info->intraday_conversion_factor); } -PANDAS_INLINE npy_int64 transform_via_day(npy_int64 ordinal, char relation, asfreq_info *af_info, freq_conv_func first_func, freq_conv_func second_func) { - //printf("transform_via_day(%ld, %ld, %d)\n", ordinal, af_info->intraday_conversion_factor, af_info->intraday_conversion_upsample); - npy_int64 result; +PANDAS_INLINE npy_int64 transform_via_day(npy_int64 ordinal, char relation, + asfreq_info *af_info, + freq_conv_func first_func, + freq_conv_func second_func) { + // printf("transform_via_day(%ld, %ld, %d)\n", ordinal, + // af_info->intraday_conversion_factor, + // af_info->intraday_conversion_upsample); + npy_int64 result; result = (*first_func)(ordinal, relation, af_info); result = (*second_func)(result, relation, af_info); @@ -413,7 +394,7 @@ static npy_int64 DtoB_weekday(npy_int64 absdate) { static npy_int64 DtoB_WeekendToMonday(npy_int64 absdate, int day_of_week) { if (day_of_week > 4) { - //change to Monday after weekend + // change to Monday after weekend absdate += (7 - day_of_week); } return DtoB_weekday(absdate); @@ -421,7 +402,7 @@ static npy_int64 DtoB_WeekendToMonday(npy_int64 absdate, int day_of_week) { static npy_int64 DtoB_WeekendToFriday(npy_int64 absdate, int day_of_week) { if (day_of_week > 4) { - //change to friday before weekend + // change to friday before weekend absdate -= (day_of_week - 4); } return DtoB_weekday(absdate); @@ -429,7 +410,8 @@ static npy_int64 DtoB_WeekendToFriday(npy_int64 absdate, int day_of_week) { static npy_int64 absdate_from_ymd(int y, int m, int d) { struct date_info tempDate; - if (dInfoCalc_SetFromDateAndTime(&tempDate, y, m, d, 0, 0, 0, GREGORIAN_CALENDAR)) { + if (dInfoCalc_SetFromDateAndTime(&tempDate, y, m, d, 0, 0, 0, + GREGORIAN_CALENDAR)) { return INT_ERR_CODE; } return tempDate.absdate; @@ -437,27 +419,33 @@ static npy_int64 absdate_from_ymd(int y, int m, int d) { //************ FROM DAILY *************** -static npy_int64 asfreq_DTtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DTtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; ordinal = downsample_daytime(ordinal, af_info, 0); - if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, GREGORIAN_CALENDAR)) + if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, + GREGORIAN_CALENDAR)) return INT_ERR_CODE; if (dinfo.month > af_info->to_a_year_end) { return (npy_int64)(dinfo.year + 1 - BASE_YEAR); - } - else { + } else { return (npy_int64)(dinfo.year - BASE_YEAR); } } -static npy_int64 DtoQ_yq(npy_int64 ordinal, asfreq_info *af_info, int *year, int *quarter) { +static npy_int64 DtoQ_yq(npy_int64 ordinal, asfreq_info *af_info, int *year, + int *quarter) { struct date_info dinfo; - if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, GREGORIAN_CALENDAR)) + if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, + GREGORIAN_CALENDAR)) return INT_ERR_CODE; if (af_info->to_q_year_end != 12) { dinfo.month -= af_info->to_q_year_end; - if (dinfo.month <= 0) { dinfo.month += 12; } - else { dinfo.year += 1; } + if (dinfo.month <= 0) { + dinfo.month += 12; + } else { + dinfo.year += 1; + } dinfo.quarter = monthToQuarter(dinfo.month); } @@ -467,7 +455,8 @@ static npy_int64 DtoQ_yq(npy_int64 ordinal, asfreq_info *af_info, int *year, int return 0; } -static npy_int64 asfreq_DTtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DTtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { int year, quarter; ordinal = downsample_daytime(ordinal, af_info, 0); @@ -479,27 +468,33 @@ static npy_int64 asfreq_DTtoQ(npy_int64 ordinal, char relation, asfreq_info *af_ return (npy_int64)((year - BASE_YEAR) * 4 + quarter - 1); } -static npy_int64 asfreq_DTtoM(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DTtoM(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; ordinal = downsample_daytime(ordinal, af_info, 0); - if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, GREGORIAN_CALENDAR)) + if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, + GREGORIAN_CALENDAR)) return INT_ERR_CODE; return (npy_int64)((dinfo.year - BASE_YEAR) * 12 + dinfo.month - 1); } -static npy_int64 asfreq_DTtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DTtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { ordinal = downsample_daytime(ordinal, af_info, 0); - return (ordinal + ORD_OFFSET - (1 + af_info->to_week_end))/7 + 1 - WEEK_OFFSET; + return (ordinal + ORD_OFFSET - (1 + af_info->to_week_end)) / 7 + 1 - + WEEK_OFFSET; } -static npy_int64 asfreq_DTtoB(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DTtoB(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; - ordinal = downsample_daytime(ordinal, af_info, 0); + ordinal = downsample_daytime(ordinal, af_info, 0); - if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, GREGORIAN_CALENDAR)) + if (dInfoCalc_SetFromAbsDate(&dinfo, ordinal + ORD_OFFSET, + GREGORIAN_CALENDAR)) return INT_ERR_CODE; if (relation == 'S') { @@ -510,43 +505,54 @@ static npy_int64 asfreq_DTtoB(npy_int64 ordinal, char relation, asfreq_info *af_ } // all intra day calculations are now done within one function -static npy_int64 asfreq_DownsampleWithinDay(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_DownsampleWithinDay(npy_int64 ordinal, char relation, + asfreq_info *af_info) { return downsample_daytime(ordinal, af_info, relation == 'E'); } -static npy_int64 asfreq_UpsampleWithinDay(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_UpsampleWithinDay(npy_int64 ordinal, char relation, + asfreq_info *af_info) { return upsample_daytime(ordinal, af_info, relation == 'E'); } //************ FROM BUSINESS *************** -static npy_int64 asfreq_BtoDT(npy_int64 ordinal, char relation, asfreq_info *af_info) -{ +static npy_int64 asfreq_BtoDT(npy_int64 ordinal, char relation, + asfreq_info *af_info) { ordinal += BDAY_OFFSET; - ordinal = (((ordinal - 1) / 5) * 7 + - mod_compat(ordinal - 1, 5) + 1 - ORD_OFFSET); + ordinal = + (((ordinal - 1) / 5) * 7 + mod_compat(ordinal - 1, 5) + 1 - ORD_OFFSET); return upsample_daytime(ordinal, af_info, relation != 'S'); } -static npy_int64 asfreq_BtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, asfreq_DTtoA); +static npy_int64 asfreq_BtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, + asfreq_DTtoA); } -static npy_int64 asfreq_BtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, asfreq_DTtoQ); +static npy_int64 asfreq_BtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, + asfreq_DTtoQ); } -static npy_int64 asfreq_BtoM(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, asfreq_DTtoM); +static npy_int64 asfreq_BtoM(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, + asfreq_DTtoM); } -static npy_int64 asfreq_BtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, asfreq_DTtoW); +static npy_int64 asfreq_BtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_BtoDT, + asfreq_DTtoW); } //************ FROM WEEKLY *************** -static npy_int64 asfreq_WtoDT(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_WtoDT(npy_int64 ordinal, char relation, + asfreq_info *af_info) { ordinal += WEEK_OFFSET; if (relation != 'S') { ordinal += 1; @@ -561,33 +567,41 @@ static npy_int64 asfreq_WtoDT(npy_int64 ordinal, char relation, asfreq_info *af_ return upsample_daytime(ordinal, af_info, relation != 'S'); } -static npy_int64 asfreq_WtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, asfreq_DTtoA); +static npy_int64 asfreq_WtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, + asfreq_DTtoA); } -static npy_int64 asfreq_WtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, asfreq_DTtoQ); +static npy_int64 asfreq_WtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, + asfreq_DTtoQ); } -static npy_int64 asfreq_WtoM(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, asfreq_DTtoM); +static npy_int64 asfreq_WtoM(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, + asfreq_DTtoM); } -static npy_int64 asfreq_WtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, asfreq_DTtoW); +static npy_int64 asfreq_WtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_WtoDT, + asfreq_DTtoW); } -static npy_int64 asfreq_WtoB(npy_int64 ordinal, char relation, asfreq_info *af_info) { - +static npy_int64 asfreq_WtoB(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; - if (dInfoCalc_SetFromAbsDate(&dinfo, - asfreq_WtoDT(ordinal, relation, af_info) + ORD_OFFSET, - GREGORIAN_CALENDAR)) return INT_ERR_CODE; + if (dInfoCalc_SetFromAbsDate( + &dinfo, asfreq_WtoDT(ordinal, relation, af_info) + ORD_OFFSET, + GREGORIAN_CALENDAR)) + return INT_ERR_CODE; if (relation == 'S') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); - } - else { + } else { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); } } @@ -598,46 +612,58 @@ static void MtoD_ym(npy_int64 ordinal, int *y, int *m) { *m = mod_compat(ordinal, 12) + 1; } - -static npy_int64 asfreq_MtoDT(npy_int64 ordinal, char relation, asfreq_info* af_info) { +static npy_int64 asfreq_MtoDT(npy_int64 ordinal, char relation, + asfreq_info *af_info) { npy_int64 absdate; int y, m; if (relation == 'E') { - ordinal += 1; + ordinal += 1; } MtoD_ym(ordinal, &y, &m); - if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE; + if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) + return INT_ERR_CODE; ordinal = absdate - ORD_OFFSET; if (relation == 'E') { - ordinal -= 1; + ordinal -= 1; } return upsample_daytime(ordinal, af_info, relation != 'S'); } -static npy_int64 asfreq_MtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, asfreq_DTtoA); +static npy_int64 asfreq_MtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, + asfreq_DTtoA); } -static npy_int64 asfreq_MtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, asfreq_DTtoQ); +static npy_int64 asfreq_MtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, + asfreq_DTtoQ); } -static npy_int64 asfreq_MtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, asfreq_DTtoW); +static npy_int64 asfreq_MtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_MtoDT, + asfreq_DTtoW); } -static npy_int64 asfreq_MtoB(npy_int64 ordinal, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_MtoB(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; - - if (dInfoCalc_SetFromAbsDate(&dinfo, - asfreq_MtoDT(ordinal, relation, af_info) + ORD_OFFSET, - GREGORIAN_CALENDAR)) return INT_ERR_CODE; - if (relation == 'S') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); } - else { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); } + if (dInfoCalc_SetFromAbsDate( + &dinfo, asfreq_MtoDT(ordinal, relation, af_info) + ORD_OFFSET, + GREGORIAN_CALENDAR)) + return INT_ERR_CODE; + + if (relation == 'S') { + return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); + } else { + return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); + } } //************ FROM QUARTERLY *************** @@ -648,62 +674,78 @@ static void QtoD_ym(npy_int64 ordinal, int *y, int *m, asfreq_info *af_info) { if (af_info->from_q_year_end != 12) { *m += af_info->from_q_year_end; - if (*m > 12) { *m -= 12; } - else { *y -= 1; } + if (*m > 12) { + *m -= 12; + } else { + *y -= 1; + } } } -static npy_int64 asfreq_QtoDT(npy_int64 ordinal, char relation, asfreq_info *af_info) { - +static npy_int64 asfreq_QtoDT(npy_int64 ordinal, char relation, + asfreq_info *af_info) { npy_int64 absdate; int y, m; if (relation == 'E') { - ordinal += 1; + ordinal += 1; } QtoD_ym(ordinal, &y, &m, af_info); - if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) return INT_ERR_CODE; + if ((absdate = absdate_from_ymd(y, m, 1)) == INT_ERR_CODE) + return INT_ERR_CODE; if (relation == 'E') { - absdate -= 1; + absdate -= 1; } return upsample_daytime(absdate - ORD_OFFSET, af_info, relation != 'S'); } -static npy_int64 asfreq_QtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, asfreq_DTtoQ); +static npy_int64 asfreq_QtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, + asfreq_DTtoQ); } -static npy_int64 asfreq_QtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, asfreq_DTtoA); +static npy_int64 asfreq_QtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, + asfreq_DTtoA); } -static npy_int64 asfreq_QtoM(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, asfreq_DTtoM); +static npy_int64 asfreq_QtoM(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, + asfreq_DTtoM); } -static npy_int64 asfreq_QtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, asfreq_DTtoW); +static npy_int64 asfreq_QtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_QtoDT, + asfreq_DTtoW); } -static npy_int64 asfreq_QtoB(npy_int64 ordinal, char relation, asfreq_info *af_info) { - +static npy_int64 asfreq_QtoB(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; - if (dInfoCalc_SetFromAbsDate(&dinfo, - asfreq_QtoDT(ordinal, relation, af_info) + ORD_OFFSET, - GREGORIAN_CALENDAR)) return INT_ERR_CODE; + if (dInfoCalc_SetFromAbsDate( + &dinfo, asfreq_QtoDT(ordinal, relation, af_info) + ORD_OFFSET, + GREGORIAN_CALENDAR)) + return INT_ERR_CODE; - if (relation == 'S') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); } - else { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); } + if (relation == 'S') { + return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); + } else { + return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); + } } - //************ FROM ANNUAL *************** -static npy_int64 asfreq_AtoDT(npy_int64 year, char relation, asfreq_info *af_info) { +static npy_int64 asfreq_AtoDT(npy_int64 year, char relation, + asfreq_info *af_info) { npy_int64 absdate; int month = (af_info->from_a_year_end) % 12; @@ -713,164 +755,193 @@ static npy_int64 asfreq_AtoDT(npy_int64 year, char relation, asfreq_info *af_inf month += 1; if (af_info->from_a_year_end != 12) { - year -= 1; + year -= 1; } if (relation == 'E') { - year += 1; + year += 1; } absdate = absdate_from_ymd(year, month, 1); - if (absdate == INT_ERR_CODE) { + if (absdate == INT_ERR_CODE) { return INT_ERR_CODE; } if (relation == 'E') { - absdate -= 1; + absdate -= 1; } return upsample_daytime(absdate - ORD_OFFSET, af_info, relation != 'S'); } -static npy_int64 asfreq_AtoA(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, asfreq_DTtoA); +static npy_int64 asfreq_AtoA(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, + asfreq_DTtoA); } -static npy_int64 asfreq_AtoQ(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, asfreq_DTtoQ); +static npy_int64 asfreq_AtoQ(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, + asfreq_DTtoQ); } -static npy_int64 asfreq_AtoM(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, asfreq_DTtoM); +static npy_int64 asfreq_AtoM(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, + asfreq_DTtoM); } -static npy_int64 asfreq_AtoW(npy_int64 ordinal, char relation, asfreq_info *af_info) { - return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, asfreq_DTtoW); +static npy_int64 asfreq_AtoW(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return transform_via_day(ordinal, relation, af_info, asfreq_AtoDT, + asfreq_DTtoW); } -static npy_int64 asfreq_AtoB(npy_int64 ordinal, char relation, asfreq_info *af_info) { - +static npy_int64 asfreq_AtoB(npy_int64 ordinal, char relation, + asfreq_info *af_info) { struct date_info dinfo; - if (dInfoCalc_SetFromAbsDate(&dinfo, - asfreq_AtoDT(ordinal, relation, af_info) + ORD_OFFSET, - GREGORIAN_CALENDAR)) return INT_ERR_CODE; + if (dInfoCalc_SetFromAbsDate( + &dinfo, asfreq_AtoDT(ordinal, relation, af_info) + ORD_OFFSET, + GREGORIAN_CALENDAR)) + return INT_ERR_CODE; - if (relation == 'S') { return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); } - else { return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); } + if (relation == 'S') { + return DtoB_WeekendToMonday(dinfo.absdate, dinfo.day_of_week); + } else { + return DtoB_WeekendToFriday(dinfo.absdate, dinfo.day_of_week); + } } -static npy_int64 nofunc(npy_int64 ordinal, char relation, asfreq_info *af_info) { return INT_ERR_CODE; } -static npy_int64 no_op(npy_int64 ordinal, char relation, asfreq_info *af_info) { return ordinal; } +static npy_int64 nofunc(npy_int64 ordinal, char relation, + asfreq_info *af_info) { + return INT_ERR_CODE; +} +static npy_int64 no_op(npy_int64 ordinal, char relation, asfreq_info *af_info) { + return ordinal; +} // end of frequency specific conversion routines static int calc_a_year_end(int freq, int group) { int result = (freq - group) % 12; - if (result == 0) {return 12;} - else {return result;} + if (result == 0) { + return 12; + } else { + return result; + } } -static int calc_week_end(int freq, int group) { - return freq - group; -} +static int calc_week_end(int freq, int group) { return freq - group; } void get_asfreq_info(int fromFreq, int toFreq, asfreq_info *af_info) { int fromGroup = get_freq_group(fromFreq); int toGroup = get_freq_group(toFreq); - af_info->intraday_conversion_factor = - get_daytime_conversion_factor( - get_freq_group_index(max_value(fromGroup, FR_DAY)), - get_freq_group_index(max_value(toGroup, FR_DAY)) - ); + af_info->intraday_conversion_factor = get_daytime_conversion_factor( + get_freq_group_index(max_value(fromGroup, FR_DAY)), + get_freq_group_index(max_value(toGroup, FR_DAY))); - //printf("get_asfreq_info(%d, %d) %ld, %d\n", fromFreq, toFreq, af_info->intraday_conversion_factor, af_info->intraday_conversion_upsample); + // printf("get_asfreq_info(%d, %d) %ld, %d\n", fromFreq, toFreq, + // af_info->intraday_conversion_factor, + // af_info->intraday_conversion_upsample); - switch(fromGroup) - { - case FR_WK: + switch (fromGroup) { + case FR_WK: af_info->from_week_end = calc_week_end(fromFreq, fromGroup); break; - case FR_ANN: + case FR_ANN: af_info->from_a_year_end = calc_a_year_end(fromFreq, fromGroup); break; - case FR_QTR: + case FR_QTR: af_info->from_q_year_end = calc_a_year_end(fromFreq, fromGroup); break; } - switch(toGroup) - { - case FR_WK: + switch (toGroup) { + case FR_WK: af_info->to_week_end = calc_week_end(toFreq, toGroup); break; - case FR_ANN: + case FR_ANN: af_info->to_a_year_end = calc_a_year_end(toFreq, toGroup); break; - case FR_QTR: + case FR_QTR: af_info->to_q_year_end = calc_a_year_end(toFreq, toGroup); break; } } - -freq_conv_func get_asfreq_func(int fromFreq, int toFreq) -{ +freq_conv_func get_asfreq_func(int fromFreq, int toFreq) { int fromGroup = get_freq_group(fromFreq); int toGroup = get_freq_group(toFreq); - if (fromGroup == FR_UND) { fromGroup = FR_DAY; } + if (fromGroup == FR_UND) { + fromGroup = FR_DAY; + } - switch(fromGroup) - { + switch (fromGroup) { case FR_ANN: - switch(toGroup) - { - case FR_ANN: return &asfreq_AtoA; - case FR_QTR: return &asfreq_AtoQ; - case FR_MTH: return &asfreq_AtoM; - case FR_WK: return &asfreq_AtoW; - case FR_BUS: return &asfreq_AtoB; - case FR_DAY: - case FR_HR: - case FR_MIN: + switch (toGroup) { + case FR_ANN: + return &asfreq_AtoA; + case FR_QTR: + return &asfreq_AtoQ; + case FR_MTH: + return &asfreq_AtoM; + case FR_WK: + return &asfreq_AtoW; + case FR_BUS: + return &asfreq_AtoB; + case FR_DAY: + case FR_HR: + case FR_MIN: case FR_SEC: case FR_MS: case FR_US: case FR_NS: - return &asfreq_AtoDT; + return &asfreq_AtoDT; - default: return &nofunc; + default: + return &nofunc; } case FR_QTR: - switch(toGroup) - { - case FR_ANN: return &asfreq_QtoA; - case FR_QTR: return &asfreq_QtoQ; - case FR_MTH: return &asfreq_QtoM; - case FR_WK: return &asfreq_QtoW; - case FR_BUS: return &asfreq_QtoB; - case FR_DAY: + switch (toGroup) { + case FR_ANN: + return &asfreq_QtoA; + case FR_QTR: + return &asfreq_QtoQ; + case FR_MTH: + return &asfreq_QtoM; + case FR_WK: + return &asfreq_QtoW; + case FR_BUS: + return &asfreq_QtoB; + case FR_DAY: case FR_HR: case FR_MIN: case FR_SEC: case FR_MS: case FR_US: case FR_NS: - return &asfreq_QtoDT; - default: return &nofunc; + return &asfreq_QtoDT; + default: + return &nofunc; } case FR_MTH: - switch(toGroup) - { - case FR_ANN: return &asfreq_MtoA; - case FR_QTR: return &asfreq_MtoQ; - case FR_MTH: return &no_op; - case FR_WK: return &asfreq_MtoW; - case FR_BUS: return &asfreq_MtoB; + switch (toGroup) { + case FR_ANN: + return &asfreq_MtoA; + case FR_QTR: + return &asfreq_MtoQ; + case FR_MTH: + return &no_op; + case FR_WK: + return &asfreq_MtoW; + case FR_BUS: + return &asfreq_MtoB; case FR_DAY: case FR_HR: case FR_MIN: @@ -878,46 +949,57 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) case FR_MS: case FR_US: case FR_NS: - return &asfreq_MtoDT; - default: return &nofunc; + return &asfreq_MtoDT; + default: + return &nofunc; } case FR_WK: - switch(toGroup) - { - case FR_ANN: return &asfreq_WtoA; - case FR_QTR: return &asfreq_WtoQ; - case FR_MTH: return &asfreq_WtoM; - case FR_WK: return &asfreq_WtoW; - case FR_BUS: return &asfreq_WtoB; - case FR_DAY: - case FR_HR: - case FR_MIN: - case FR_SEC: + switch (toGroup) { + case FR_ANN: + return &asfreq_WtoA; + case FR_QTR: + return &asfreq_WtoQ; + case FR_MTH: + return &asfreq_WtoM; + case FR_WK: + return &asfreq_WtoW; + case FR_BUS: + return &asfreq_WtoB; + case FR_DAY: + case FR_HR: + case FR_MIN: + case FR_SEC: case FR_MS: case FR_US: case FR_NS: - return &asfreq_WtoDT; - default: return &nofunc; + return &asfreq_WtoDT; + default: + return &nofunc; } case FR_BUS: - switch(toGroup) - { - case FR_ANN: return &asfreq_BtoA; - case FR_QTR: return &asfreq_BtoQ; - case FR_MTH: return &asfreq_BtoM; - case FR_WK: return &asfreq_BtoW; - case FR_BUS: return &no_op; - case FR_DAY: - case FR_HR: - case FR_MIN: + switch (toGroup) { + case FR_ANN: + return &asfreq_BtoA; + case FR_QTR: + return &asfreq_BtoQ; + case FR_MTH: + return &asfreq_BtoM; + case FR_WK: + return &asfreq_BtoW; + case FR_BUS: + return &no_op; + case FR_DAY: + case FR_HR: + case FR_MIN: case FR_SEC: case FR_MS: case FR_US: case FR_NS: - return &asfreq_BtoDT; - default: return &nofunc; + return &asfreq_BtoDT; + default: + return &nofunc; } case FR_DAY: @@ -927,14 +1009,18 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) case FR_MS: case FR_US: case FR_NS: - switch(toGroup) - { - case FR_ANN: return &asfreq_DTtoA; - case FR_QTR: return &asfreq_DTtoQ; - case FR_MTH: return &asfreq_DTtoM; - case FR_WK: return &asfreq_DTtoW; - case FR_BUS: return &asfreq_DTtoB; - case FR_DAY: + switch (toGroup) { + case FR_ANN: + return &asfreq_DTtoA; + case FR_QTR: + return &asfreq_DTtoQ; + case FR_MTH: + return &asfreq_DTtoM; + case FR_WK: + return &asfreq_DTtoW; + case FR_BUS: + return &asfreq_DTtoB; + case FR_DAY: case FR_HR: case FR_MIN: case FR_SEC: @@ -946,59 +1032,60 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) } else { return &asfreq_UpsampleWithinDay; } - default: return &nofunc; + default: + return &nofunc; } - default: return &nofunc; + default: + return &nofunc; } } double get_abs_time(int freq, npy_int64 date_ordinal, npy_int64 ordinal) { - //printf("get_abs_time %d %lld %lld\n", freq, date_ordinal, ordinal); + // printf("get_abs_time %d %lld %lld\n", freq, date_ordinal, ordinal); - int freq_index, day_index, base_index; - npy_int64 per_day, start_ord; - double unit, result; + int freq_index, day_index, base_index; + npy_int64 per_day, start_ord; + double unit, result; if (freq <= FR_DAY) { - return 0; + return 0; } freq_index = get_freq_group_index(freq); day_index = get_freq_group_index(FR_DAY); base_index = get_freq_group_index(FR_SEC); - //printf(" indices: day %d, freq %d, base %d\n", day_index, freq_index, base_index); + // printf(" indices: day %d, freq %d, base %d\n", day_index, freq_index, + // base_index); per_day = get_daytime_conversion_factor(day_index, freq_index); unit = get_daytime_conversion_factor(freq_index, base_index); - //printf(" per_day: %lld, unit: %f\n", per_day, unit); + // printf(" per_day: %lld, unit: %f\n", per_day, unit); if (base_index < freq_index) { - unit = 1 / unit; - //printf(" corrected unit: %f\n", unit); + unit = 1 / unit; + // printf(" corrected unit: %f\n", unit); } start_ord = date_ordinal * per_day; - //printf("start_ord: %lld\n", start_ord); - result = (double) ( unit * (ordinal - start_ord)); - //printf(" result: %f\n", result); + // printf("start_ord: %lld\n", start_ord); + result = (double)(unit * (ordinal - start_ord)); + // printf(" result: %f\n", result); return result; } /* Sets the time part of the DateTime object. */ -static int dInfoCalc_SetFromAbsTime(struct date_info *dinfo, - double abstime) -{ +static int dInfoCalc_SetFromAbsTime(struct date_info *dinfo, double abstime) { int inttime; - int hour,minute; + int hour, minute; double second; inttime = (int)abstime; hour = inttime / 3600; minute = (inttime % 3600) / 60; - second = abstime - (double)(hour*3600 + minute*60); + second = abstime - (double)(hour * 3600 + minute * 60); dinfo->hour = hour; dinfo->minute = minute; @@ -1013,15 +1100,12 @@ static int dInfoCalc_SetFromAbsTime(struct date_info *dinfo, may be set to the flags: GREGORIAN_CALENDAR, JULIAN_CALENDAR to indicate the calendar to be used. */ static int dInfoCalc_SetFromAbsDateTime(struct date_info *dinfo, - npy_int64 absdate, - double abstime, - int calendar) -{ + npy_int64 absdate, double abstime, + int calendar) { /* Bounds check */ Py_AssertWithArg(abstime >= 0.0 && abstime <= SECONDS_PER_DAY, - PyExc_ValueError, - "abstime out of range (0.0 - 86400.0): %f", - abstime); + PyExc_ValueError, + "abstime out of range (0.0 - 86400.0): %f", abstime); /* Calculate the date */ if (dInfoCalc_SetFromAbsDate(dinfo, absdate, calendar)) goto onError; @@ -1038,8 +1122,8 @@ static int dInfoCalc_SetFromAbsDateTime(struct date_info *dinfo, * New pandas API-helper code, to expose to cython * ------------------------------------------------------------------*/ -npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation) -{ +npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, + char relation) { npy_int64 val; freq_conv_func func; asfreq_info finfo; @@ -1048,12 +1132,14 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation) get_asfreq_info(freq1, freq2, &finfo); - //printf("\n%x %d %d %ld %ld\n", func, freq1, freq2, finfo.intraday_conversion_factor, -finfo.intraday_conversion_factor); + // printf("\n%x %d %d %ld %ld\n", func, freq1, freq2, + // finfo.intraday_conversion_factor, -finfo.intraday_conversion_factor); val = (*func)(period_ordinal, relation, &finfo); if (val == INT_ERR_CODE) { - //Py_Error(PyExc_ValueError, "Unable to convert to desired frequency."); + // Py_Error(PyExc_ValueError, "Unable to convert to desired + // frequency."); goto onError; } return val; @@ -1061,12 +1147,10 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation) return INT_ERR_CODE; } - /* generate an ordinal in period space */ -npy_int64 get_period_ordinal(int year, int month, int day, - int hour, int minute, int second, int microseconds, int picoseconds, - int freq) -{ +npy_int64 get_period_ordinal(int year, int month, int day, int hour, int minute, + int second, int microseconds, int picoseconds, + int freq) { npy_int64 absdays, delta, seconds; npy_int64 weeks, days; npy_int64 ordinal, day_adj; @@ -1074,20 +1158,21 @@ npy_int64 get_period_ordinal(int year, int month, int day, freq_group = get_freq_group(freq); if (freq == FR_SEC || freq == FR_MS || freq == FR_US || freq == FR_NS) { - absdays = absdate_from_ymd(year, month, day); delta = (absdays - ORD_OFFSET); - seconds = (npy_int64)(delta * 86400 + hour * 3600 + minute * 60 + second); + seconds = + (npy_int64)(delta * 86400 + hour * 3600 + minute * 60 + second); - switch(freq) { - case FR_MS: - return seconds * 1000 + microseconds / 1000; + switch (freq) { + case FR_MS: + return seconds * 1000 + microseconds / 1000; - case FR_US: - return seconds * 1000000 + microseconds; + case FR_US: + return seconds * 1000000 + microseconds; - case FR_NS: - return seconds * 1000000000 + microseconds * 1000 + picoseconds / 1000; + case FR_NS: + return seconds * 1000000000 + microseconds * 1000 + + picoseconds / 1000; } return seconds; @@ -1096,63 +1181,55 @@ npy_int64 get_period_ordinal(int year, int month, int day, if (freq == FR_MIN) { absdays = absdate_from_ymd(year, month, day); delta = (absdays - ORD_OFFSET); - return (npy_int64)(delta*1440 + hour*60 + minute); + return (npy_int64)(delta * 1440 + hour * 60 + minute); } if (freq == FR_HR) { - if ((absdays = absdate_from_ymd(year, month, day)) == INT_ERR_CODE) - { + if ((absdays = absdate_from_ymd(year, month, day)) == INT_ERR_CODE) { goto onError; } delta = (absdays - ORD_OFFSET); - return (npy_int64)(delta*24 + hour); + return (npy_int64)(delta * 24 + hour); } - if (freq == FR_DAY) - { - return (npy_int64) (absdate_from_ymd(year, month, day) - ORD_OFFSET); + if (freq == FR_DAY) { + return (npy_int64)(absdate_from_ymd(year, month, day) - ORD_OFFSET); } - if (freq == FR_UND) - { - return (npy_int64) (absdate_from_ymd(year, month, day) - ORD_OFFSET); + if (freq == FR_UND) { + return (npy_int64)(absdate_from_ymd(year, month, day) - ORD_OFFSET); } - if (freq == FR_BUS) - { - if((days = absdate_from_ymd(year, month, day)) == INT_ERR_CODE) - { + if (freq == FR_BUS) { + if ((days = absdate_from_ymd(year, month, day)) == INT_ERR_CODE) { goto onError; } // calculate the current week assuming sunday as last day of a week weeks = (days - BASE_WEEK_TO_DAY_OFFSET) / DAYS_PER_WEEK; // calculate the current weekday (in range 1 .. 7) delta = (days - BASE_WEEK_TO_DAY_OFFSET) % DAYS_PER_WEEK + 1; - // return the number of business days in full weeks plus the business days in the last - possible partial - week - return (npy_int64)(weeks * BUSINESS_DAYS_PER_WEEK) - + (delta <= BUSINESS_DAYS_PER_WEEK - ? delta - : BUSINESS_DAYS_PER_WEEK + 1) - - BDAY_OFFSET; + // return the number of business days in full weeks plus the business + // days in the last - possible partial - week + return (npy_int64)(weeks * BUSINESS_DAYS_PER_WEEK) + + (delta <= BUSINESS_DAYS_PER_WEEK ? delta + : BUSINESS_DAYS_PER_WEEK + 1) - + BDAY_OFFSET; } - if (freq_group == FR_WK) - { - if((ordinal = (npy_int64)absdate_from_ymd(year, month, day)) == INT_ERR_CODE) - { + if (freq_group == FR_WK) { + if ((ordinal = (npy_int64)absdate_from_ymd(year, month, day)) == + INT_ERR_CODE) { goto onError; } day_adj = freq - FR_WK; return (ordinal - (1 + day_adj)) / 7 + 1 - WEEK_OFFSET; } - if (freq == FR_MTH) - { + if (freq == FR_MTH) { return (year - BASE_YEAR) * 12 + month - 1; } - if (freq_group == FR_QTR) - { + if (freq_group == FR_QTR) { fmonth = freq - FR_QTR; if (fmonth == 0) fmonth = 12; @@ -1163,14 +1240,12 @@ npy_int64 get_period_ordinal(int year, int month, int day, return (year - BASE_YEAR) * 4 + (mdiff - 1) / 3; } - if (freq_group == FR_ANN) - { + if (freq_group == FR_ANN) { fmonth = freq - FR_ANN; if (fmonth == 0) fmonth = 12; if (month <= fmonth) { return year - BASE_YEAR; - } - else { + } else { return year - BASE_YEAR + 1; } } @@ -1188,13 +1263,11 @@ npy_int64 get_period_ordinal(int year, int month, int day, is calculated for the last day of the period. */ -npy_int64 get_python_ordinal(npy_int64 period_ordinal, int freq) -{ +npy_int64 get_python_ordinal(npy_int64 period_ordinal, int freq) { asfreq_info af_info; - freq_conv_func toDaily = NULL; + freq_conv_func toDaily = NULL; - if (freq == FR_DAY) - return period_ordinal + ORD_OFFSET; + if (freq == FR_DAY) return period_ordinal + ORD_OFFSET; toDaily = get_asfreq_func(freq, FR_DAY); get_asfreq_info(freq, FR_DAY, &af_info); @@ -1216,12 +1289,14 @@ char *str_replace(const char *s, const char *old, const char *new) { } ret = PyArray_malloc(i + 1 + count * (newlen - oldlen)); - if (ret == NULL) {return (char *)PyErr_NoMemory();} + if (ret == NULL) { + return (char *)PyErr_NoMemory(); + } i = 0; while (*s) { if (strstr(s, old) == s) { - strcpy(&ret[i], new); + strncpy(&ret[i], new, sizeof(char) * newlen); i += newlen; s += oldlen; } else { @@ -1236,9 +1311,9 @@ char *str_replace(const char *s, const char *old, const char *new) { // function to generate a nice string representation of the period // object, originally from DateObject_strftime -char* c_strftime(struct date_info *tmp, char *fmt) { +char *c_strftime(struct date_info *tmp, char *fmt) { struct tm c_date; - char* result; + char *result; struct date_info dinfo = *tmp; int result_len = strlen(fmt) + 50; @@ -1263,7 +1338,7 @@ int get_yq(npy_int64 ordinal, int freq, int *quarter, int *year) { asfreq_info af_info; int qtr_freq; npy_int64 daily_ord; - npy_int64 (*toDaily)(npy_int64, char, asfreq_info*) = NULL; + npy_int64 (*toDaily)(npy_int64, char, asfreq_info *) = NULL; toDaily = get_asfreq_func(freq, FR_DAY); get_asfreq_info(freq, FR_DAY, &af_info); @@ -1272,19 +1347,16 @@ int get_yq(npy_int64 ordinal, int freq, int *quarter, int *year) { if (get_freq_group(freq) == FR_QTR) { qtr_freq = freq; - } else { qtr_freq = FR_QTR; } + } else { + qtr_freq = FR_QTR; + } get_asfreq_info(FR_DAY, qtr_freq, &af_info); - if(DtoQ_yq(daily_ord, &af_info, year, quarter) == INT_ERR_CODE) - return -1; + if (DtoQ_yq(daily_ord, &af_info, year, quarter) == INT_ERR_CODE) return -1; return 0; } - - - - static int _quarter_year(npy_int64 ordinal, int freq, int *year, int *quarter) { asfreq_info af_info; int qtr_freq; @@ -1301,31 +1373,29 @@ static int _quarter_year(npy_int64 ordinal, int freq, int *year, int *quarter) { if (DtoQ_yq(ordinal, &af_info, year, quarter) == INT_ERR_CODE) return INT_ERR_CODE; - if ((qtr_freq % 1000) > 12) - *year -= 1; + if ((qtr_freq % 1000) > 12) *year -= 1; return 0; } -static int _ISOWeek(struct date_info *dinfo) -{ +static int _ISOWeek(struct date_info *dinfo) { int week; /* Estimate */ - week = (dinfo->day_of_year-1) - dinfo->day_of_week + 3; + week = (dinfo->day_of_year - 1) - dinfo->day_of_week + 3; if (week >= 0) week = week / 7 + 1; /* Verify */ if (week < 0) { /* The day lies in last week of the previous year */ - if ((week > -2) || - (week == -2 && dInfoCalc_Leapyear(dinfo->year-1, dinfo->calendar))) + if ((week > -2) || (week == -2 && dInfoCalc_Leapyear(dinfo->year - 1, + dinfo->calendar))) week = 53; else week = 52; } else if (week == 53) { /* Check if the week belongs to year or year+1 */ - if (31-dinfo->day + dinfo->day_of_week < 3) { + if (31 - dinfo->day + dinfo->day_of_week < 3) { week = 1; } } @@ -1333,8 +1403,7 @@ static int _ISOWeek(struct date_info *dinfo) return week; } -int get_date_info(npy_int64 ordinal, int freq, struct date_info *dinfo) -{ +int get_date_info(npy_int64 ordinal, int freq, struct date_info *dinfo) { npy_int64 absdate = get_python_ordinal(ordinal, freq); double abstime = get_abs_time(freq, absdate - ORD_OFFSET, ordinal); @@ -1344,11 +1413,11 @@ int get_date_info(npy_int64 ordinal, int freq, struct date_info *dinfo) } while (abstime >= 86400) { abstime -= 86400; - absdate += 1; + absdate += 1; } - if(dInfoCalc_SetFromAbsDateTime(dinfo, absdate, - abstime, GREGORIAN_CALENDAR)) + if (dInfoCalc_SetFromAbsDateTime(dinfo, absdate, abstime, + GREGORIAN_CALENDAR)) return INT_ERR_CODE; return 0; @@ -1362,77 +1431,77 @@ int pyear(npy_int64 ordinal, int freq) { int pqyear(npy_int64 ordinal, int freq) { int year, quarter; - if( _quarter_year(ordinal, freq, &year, &quarter) == INT_ERR_CODE) + if (_quarter_year(ordinal, freq, &year, &quarter) == INT_ERR_CODE) return INT_ERR_CODE; return year; } int pquarter(npy_int64 ordinal, int freq) { int year, quarter; - if(_quarter_year(ordinal, freq, &year, &quarter) == INT_ERR_CODE) + if (_quarter_year(ordinal, freq, &year, &quarter) == INT_ERR_CODE) return INT_ERR_CODE; return quarter; } int pmonth(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.month; } int pday(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.day; } int pweekday(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.day_of_week; } int pday_of_week(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.day_of_week; } int pday_of_year(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.day_of_year; } int pweek(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return _ISOWeek(&dinfo); } int phour(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.hour; } int pminute(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return dinfo.minute; } int psecond(npy_int64 ordinal, int freq) { struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; return (int)dinfo.second; } @@ -1440,9 +1509,10 @@ int psecond(npy_int64 ordinal, int freq) { int pdays_in_month(npy_int64 ordinal, int freq) { int days; struct date_info dinfo; - if(get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) + if (get_date_info(ordinal, freq, &dinfo) == INT_ERR_CODE) return INT_ERR_CODE; - - days = days_in_month[dInfoCalc_Leapyear(dinfo.year, dinfo.calendar)][dinfo.month-1]; + + days = days_in_month[dInfoCalc_Leapyear(dinfo.year, dinfo.calendar)] + [dinfo.month - 1]; return days; } diff --git a/pandas/src/period_helper.h b/pandas/src/period_helper.h index 0351321926fa2..601717692ff6d 100644 --- a/pandas/src/period_helper.h +++ b/pandas/src/period_helper.h @@ -1,17 +1,24 @@ /* - * Borrowed and derived code from scikits.timeseries that we will expose via - * Cython to pandas. This primarily concerns interval representation and - * frequency conversion routines. - */ +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. -#ifndef C_PERIOD_H -#define C_PERIOD_H +Borrowed and derived code from scikits.timeseries that we will expose via +Cython to pandas. This primarily concerns interval representation and +frequency conversion routines. +*/ + +#ifndef PANDAS_SRC_PERIOD_HELPER_H_ +#define PANDAS_SRC_PERIOD_HELPER_H_ #include -#include "helper.h" -#include "numpy/ndarraytypes.h" #include "headers/stdint.h" +#include "helper.h" #include "limits.h" +#include "numpy/ndarraytypes.h" /* * declarations from period here @@ -20,100 +27,113 @@ #define GREGORIAN_CALENDAR 0 #define JULIAN_CALENDAR 1 -#define SECONDS_PER_DAY ((double) 86400.0) - -#define Py_AssertWithArg(x,errortype,errorstr,a1) {if (!(x)) {PyErr_Format(errortype,errorstr,a1);goto onError;}} -#define Py_Error(errortype,errorstr) {PyErr_SetString(errortype,errorstr);goto onError;} +#define SECONDS_PER_DAY ((double)86400.0) + +#define Py_AssertWithArg(x, errortype, errorstr, a1) \ + { \ + if (!(x)) { \ + PyErr_Format(errortype, errorstr, a1); \ + goto onError; \ + } \ + } +#define Py_Error(errortype, errorstr) \ + { \ + PyErr_SetString(errortype, errorstr); \ + goto onError; \ + } /*** FREQUENCY CONSTANTS ***/ // HIGHFREQ_ORIG is the datetime ordinal from which to begin the second // frequency ordinal sequence -// typedef int64_t npy_int64; -// begins second ordinal at 1/1/1970 unix epoch - // #define HIGHFREQ_ORIG 62135683200LL #define BASE_YEAR 1970 -#define ORD_OFFSET 719163LL // days until 1970-01-01 -#define BDAY_OFFSET 513689LL // days until 1970-01-01 +#define ORD_OFFSET 719163LL // days until 1970-01-01 +#define BDAY_OFFSET 513689LL // days until 1970-01-01 #define WEEK_OFFSET 102737LL -#define BASE_WEEK_TO_DAY_OFFSET 1 // difference between day 0 and end of week in days +#define BASE_WEEK_TO_DAY_OFFSET \ + 1 // difference between day 0 and end of week in days #define DAYS_PER_WEEK 7 #define BUSINESS_DAYS_PER_WEEK 5 -#define HIGHFREQ_ORIG 0 // ORD_OFFSET * 86400LL // days until 1970-01-01 - -#define FR_ANN 1000 /* Annual */ -#define FR_ANNDEC FR_ANN /* Annual - December year end*/ -#define FR_ANNJAN 1001 /* Annual - January year end*/ -#define FR_ANNFEB 1002 /* Annual - February year end*/ -#define FR_ANNMAR 1003 /* Annual - March year end*/ -#define FR_ANNAPR 1004 /* Annual - April year end*/ -#define FR_ANNMAY 1005 /* Annual - May year end*/ -#define FR_ANNJUN 1006 /* Annual - June year end*/ -#define FR_ANNJUL 1007 /* Annual - July year end*/ -#define FR_ANNAUG 1008 /* Annual - August year end*/ -#define FR_ANNSEP 1009 /* Annual - September year end*/ -#define FR_ANNOCT 1010 /* Annual - October year end*/ -#define FR_ANNNOV 1011 /* Annual - November year end*/ +#define HIGHFREQ_ORIG 0 // ORD_OFFSET * 86400LL // days until 1970-01-01 + +#define FR_ANN 1000 /* Annual */ +#define FR_ANNDEC FR_ANN /* Annual - December year end*/ +#define FR_ANNJAN 1001 /* Annual - January year end*/ +#define FR_ANNFEB 1002 /* Annual - February year end*/ +#define FR_ANNMAR 1003 /* Annual - March year end*/ +#define FR_ANNAPR 1004 /* Annual - April year end*/ +#define FR_ANNMAY 1005 /* Annual - May year end*/ +#define FR_ANNJUN 1006 /* Annual - June year end*/ +#define FR_ANNJUL 1007 /* Annual - July year end*/ +#define FR_ANNAUG 1008 /* Annual - August year end*/ +#define FR_ANNSEP 1009 /* Annual - September year end*/ +#define FR_ANNOCT 1010 /* Annual - October year end*/ +#define FR_ANNNOV 1011 /* Annual - November year end*/ /* The standard quarterly frequencies with various fiscal year ends eg, Q42005 for Q@OCT runs Aug 1, 2005 to Oct 31, 2005 */ -#define FR_QTR 2000 /* Quarterly - December year end (default quarterly) */ -#define FR_QTRDEC FR_QTR /* Quarterly - December year end */ -#define FR_QTRJAN 2001 /* Quarterly - January year end */ -#define FR_QTRFEB 2002 /* Quarterly - February year end */ -#define FR_QTRMAR 2003 /* Quarterly - March year end */ -#define FR_QTRAPR 2004 /* Quarterly - April year end */ -#define FR_QTRMAY 2005 /* Quarterly - May year end */ -#define FR_QTRJUN 2006 /* Quarterly - June year end */ -#define FR_QTRJUL 2007 /* Quarterly - July year end */ -#define FR_QTRAUG 2008 /* Quarterly - August year end */ -#define FR_QTRSEP 2009 /* Quarterly - September year end */ -#define FR_QTROCT 2010 /* Quarterly - October year end */ -#define FR_QTRNOV 2011 /* Quarterly - November year end */ - -#define FR_MTH 3000 /* Monthly */ - -#define FR_WK 4000 /* Weekly */ +#define FR_QTR 2000 /* Quarterly - December year end (default quarterly) */ +#define FR_QTRDEC FR_QTR /* Quarterly - December year end */ +#define FR_QTRJAN 2001 /* Quarterly - January year end */ +#define FR_QTRFEB 2002 /* Quarterly - February year end */ +#define FR_QTRMAR 2003 /* Quarterly - March year end */ +#define FR_QTRAPR 2004 /* Quarterly - April year end */ +#define FR_QTRMAY 2005 /* Quarterly - May year end */ +#define FR_QTRJUN 2006 /* Quarterly - June year end */ +#define FR_QTRJUL 2007 /* Quarterly - July year end */ +#define FR_QTRAUG 2008 /* Quarterly - August year end */ +#define FR_QTRSEP 2009 /* Quarterly - September year end */ +#define FR_QTROCT 2010 /* Quarterly - October year end */ +#define FR_QTRNOV 2011 /* Quarterly - November year end */ + +#define FR_MTH 3000 /* Monthly */ + +#define FR_WK 4000 /* Weekly */ #define FR_WKSUN FR_WK /* Weekly - Sunday end of week */ -#define FR_WKMON 4001 /* Weekly - Monday end of week */ -#define FR_WKTUE 4002 /* Weekly - Tuesday end of week */ -#define FR_WKWED 4003 /* Weekly - Wednesday end of week */ -#define FR_WKTHU 4004 /* Weekly - Thursday end of week */ -#define FR_WKFRI 4005 /* Weekly - Friday end of week */ -#define FR_WKSAT 4006 /* Weekly - Saturday end of week */ - -#define FR_BUS 5000 /* Business days */ -#define FR_DAY 6000 /* Daily */ -#define FR_HR 7000 /* Hourly */ -#define FR_MIN 8000 /* Minutely */ -#define FR_SEC 9000 /* Secondly */ -#define FR_MS 10000 /* Millisecondly */ -#define FR_US 11000 /* Microsecondly */ -#define FR_NS 12000 /* Nanosecondly */ - -#define FR_UND -10000 /* Undefined */ +#define FR_WKMON 4001 /* Weekly - Monday end of week */ +#define FR_WKTUE 4002 /* Weekly - Tuesday end of week */ +#define FR_WKWED 4003 /* Weekly - Wednesday end of week */ +#define FR_WKTHU 4004 /* Weekly - Thursday end of week */ +#define FR_WKFRI 4005 /* Weekly - Friday end of week */ +#define FR_WKSAT 4006 /* Weekly - Saturday end of week */ + +#define FR_BUS 5000 /* Business days */ +#define FR_DAY 6000 /* Daily */ +#define FR_HR 7000 /* Hourly */ +#define FR_MIN 8000 /* Minutely */ +#define FR_SEC 9000 /* Secondly */ +#define FR_MS 10000 /* Millisecondly */ +#define FR_US 11000 /* Microsecondly */ +#define FR_NS 12000 /* Nanosecondly */ + +#define FR_UND -10000 /* Undefined */ #define INT_ERR_CODE INT32_MIN -#define MEM_CHECK(item) if (item == NULL) { return PyErr_NoMemory(); } -#define ERR_CHECK(item) if (item == NULL) { return NULL; } +#define MEM_CHECK(item) \ + if (item == NULL) { \ + return PyErr_NoMemory(); \ + } +#define ERR_CHECK(item) \ + if (item == NULL) { \ + return NULL; \ + } typedef struct asfreq_info { - int from_week_end; // day the week ends on in the "from" frequency - int to_week_end; // day the week ends on in the "to" frequency + int from_week_end; // day the week ends on in the "from" frequency + int to_week_end; // day the week ends on in the "to" frequency - int from_a_year_end; // month the year ends on in the "from" frequency - int to_a_year_end; // month the year ends on in the "to" frequency + int from_a_year_end; // month the year ends on in the "from" frequency + int to_a_year_end; // month the year ends on in the "to" frequency - int from_q_year_end; // month the year ends on in the "from" frequency - int to_q_year_end; // month the year ends on in the "to" frequency + int from_q_year_end; // month the year ends on in the "from" frequency + int to_q_year_end; // month the year ends on in the "to" frequency npy_int64 intraday_conversion_factor; } asfreq_info; - typedef struct date_info { npy_int64 absdate; double abstime; @@ -130,7 +150,7 @@ typedef struct date_info { int calendar; } date_info; -typedef npy_int64 (*freq_conv_func)(npy_int64, char, asfreq_info*); +typedef npy_int64 (*freq_conv_func)(npy_int64, char, asfreq_info *); /* * new pandas API helper functions here @@ -138,9 +158,9 @@ typedef npy_int64 (*freq_conv_func)(npy_int64, char, asfreq_info*); npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation); -npy_int64 get_period_ordinal(int year, int month, int day, - int hour, int minute, int second, int microseconds, int picoseconds, - int freq); +npy_int64 get_period_ordinal(int year, int month, int day, int hour, int minute, + int second, int microseconds, int picoseconds, + int freq); npy_int64 get_python_ordinal(npy_int64 period_ordinal, int freq); @@ -167,4 +187,5 @@ char *c_strftime(struct date_info *dinfo, char *fmt); int get_yq(npy_int64 ordinal, int freq, int *quarter, int *year); void initialize_daytime_conversion_factor_matrix(void); -#endif + +#endif // PANDAS_SRC_PERIOD_HELPER_H_ diff --git a/pandas/src/skiplist.h b/pandas/src/skiplist.h index 3bf63aedce9cb..013516a49fa2f 100644 --- a/pandas/src/skiplist.h +++ b/pandas/src/skiplist.h @@ -1,298 +1,290 @@ - /* - Flexibly-sized, indexable skiplist data structure for maintaining a sorted - list of values +Copyright (c) 2016, PyData Development Team +All rights reserved. + +Distributed under the terms of the BSD Simplified License. + +The full license is in the LICENSE file, distributed with this software. - Port of Wes McKinney's Cython version of Raymond Hettinger's original pure - Python recipe (http://rhettinger.wordpress.com/2010/02/06/lost-knowledge/) - */ +Flexibly-sized, index-able skiplist data structure for maintaining a sorted +list of values -// #include -// #include +Port of Wes McKinney's Cython version of Raymond Hettinger's original pure +Python recipe (http://rhettinger.wordpress.com/2010/02/06/lost-knowledge/) +*/ +#ifndef PANDAS_SRC_SKIPLIST_H_ +#define PANDAS_SRC_SKIPLIST_H_ +#include #include #include #include -#include #ifndef PANDAS_INLINE - #if defined(__GNUC__) - #define PANDAS_INLINE static __inline__ - #elif defined(_MSC_VER) - #define PANDAS_INLINE static __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define PANDAS_INLINE static inline - #else - #define PANDAS_INLINE - #endif +#if defined(__GNUC__) +#define PANDAS_INLINE static __inline__ +#elif defined(_MSC_VER) +#define PANDAS_INLINE static __inline +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define PANDAS_INLINE static inline +#else +#define PANDAS_INLINE +#endif #endif -PANDAS_INLINE float __skiplist_nanf(void) -{ - const union { int __i; float __f;} __bint = {0x7fc00000UL}; +PANDAS_INLINE float __skiplist_nanf(void) { + const union { + int __i; + float __f; + } __bint = {0x7fc00000UL}; return __bint.__f; } -#define PANDAS_NAN ((double) __skiplist_nanf()) +#define PANDAS_NAN ((double)__skiplist_nanf()) - -PANDAS_INLINE double Log2(double val) { - return log(val) / log(2.); -} +PANDAS_INLINE double Log2(double val) { return log(val) / log(2.); } typedef struct node_t node_t; struct node_t { - node_t **next; - int *width; - double value; - int is_nil; - int levels; - int ref_count; + node_t **next; + int *width; + double value; + int is_nil; + int levels; + int ref_count; }; typedef struct { - node_t *head; - node_t **tmp_chain; - int *tmp_steps; - int size; - int maxlevels; + node_t *head; + node_t **tmp_chain; + int *tmp_steps; + int size; + int maxlevels; } skiplist_t; PANDAS_INLINE double urand(void) { - return ((double) rand() + 1) / ((double) RAND_MAX + 2); + return ((double)rand() + 1) / ((double)RAND_MAX + 2); } -PANDAS_INLINE int int_min(int a, int b) { - return a < b ? a : b; -} +PANDAS_INLINE int int_min(int a, int b) { return a < b ? a : b; } PANDAS_INLINE node_t *node_init(double value, int levels) { - node_t *result; - result = (node_t*) malloc(sizeof(node_t)); - if (result) { - result->value = value; - result->levels = levels; - result->is_nil = 0; - result->ref_count = 0; - result->next = (node_t**) malloc(levels * sizeof(node_t*)); - result->width = (int*) malloc(levels * sizeof(int)); - if (!(result->next && result->width) && (levels != 0)) { - free(result->next); - free(result->width); - free(result); - return NULL; - } - } - return result; + node_t *result; + result = (node_t *)malloc(sizeof(node_t)); + if (result) { + result->value = value; + result->levels = levels; + result->is_nil = 0; + result->ref_count = 0; + result->next = (node_t **)malloc(levels * sizeof(node_t *)); + result->width = (int *)malloc(levels * sizeof(int)); + if (!(result->next && result->width) && (levels != 0)) { + free(result->next); + free(result->width); + free(result); + return NULL; + } + } + return result; } // do this ourselves -PANDAS_INLINE void node_incref(node_t *node) { - ++(node->ref_count); -} +PANDAS_INLINE void node_incref(node_t *node) { ++(node->ref_count); } -PANDAS_INLINE void node_decref(node_t *node) { - --(node->ref_count); -} +PANDAS_INLINE void node_decref(node_t *node) { --(node->ref_count); } static void node_destroy(node_t *node) { - int i; - if (node) { - if (node->ref_count <= 1) { - for (i = 0; i < node->levels; ++i) { - node_destroy(node->next[i]); - } - free(node->next); - free(node->width); - // printf("Reference count was 1, freeing\n"); - free(node); - } - else { - node_decref(node); + int i; + if (node) { + if (node->ref_count <= 1) { + for (i = 0; i < node->levels; ++i) { + node_destroy(node->next[i]); + } + free(node->next); + free(node->width); + // printf("Reference count was 1, freeing\n"); + free(node); + } else { + node_decref(node); + } + // pretty sure that freeing the struct above will be enough } - // pretty sure that freeing the struct above will be enough - } } PANDAS_INLINE void skiplist_destroy(skiplist_t *skp) { - if (skp) { - node_destroy(skp->head); - free(skp->tmp_steps); - free(skp->tmp_chain); - free(skp); - } + if (skp) { + node_destroy(skp->head); + free(skp->tmp_steps); + free(skp->tmp_chain); + free(skp); + } } PANDAS_INLINE skiplist_t *skiplist_init(int expected_size) { - skiplist_t *result; - node_t *NIL, *head; - int maxlevels, i; - - maxlevels = 1 + Log2((double) expected_size); - result = (skiplist_t*) malloc(sizeof(skiplist_t)); - if (!result) { - return NULL; - } - result->tmp_chain = (node_t**) malloc(maxlevels * sizeof(node_t*)); - result->tmp_steps = (int*) malloc(maxlevels * sizeof(int)); - result->maxlevels = maxlevels; - result->size = 0; - - head = result->head = node_init(PANDAS_NAN, maxlevels); - NIL = node_init(0.0, 0); - - if (!(result->tmp_chain && result->tmp_steps && result->head && NIL)) { - skiplist_destroy(result); - node_destroy(NIL); - return NULL; - } - - node_incref(head); - - NIL->is_nil = 1; - - for (i = 0; i < maxlevels; ++i) - { - head->next[i] = NIL; - head->width[i] = 1; - node_incref(NIL); - } - - return result; + skiplist_t *result; + node_t *NIL, *head; + int maxlevels, i; + + maxlevels = 1 + Log2((double)expected_size); + result = (skiplist_t *)malloc(sizeof(skiplist_t)); + if (!result) { + return NULL; + } + result->tmp_chain = (node_t **)malloc(maxlevels * sizeof(node_t *)); + result->tmp_steps = (int *)malloc(maxlevels * sizeof(int)); + result->maxlevels = maxlevels; + result->size = 0; + + head = result->head = node_init(PANDAS_NAN, maxlevels); + NIL = node_init(0.0, 0); + + if (!(result->tmp_chain && result->tmp_steps && result->head && NIL)) { + skiplist_destroy(result); + node_destroy(NIL); + return NULL; + } + + node_incref(head); + + NIL->is_nil = 1; + + for (i = 0; i < maxlevels; ++i) { + head->next[i] = NIL; + head->width[i] = 1; + node_incref(NIL); + } + + return result; } // 1 if left < right, 0 if left == right, -1 if left > right -PANDAS_INLINE int _node_cmp(node_t* node, double value){ - if (node->is_nil || node->value > value) { - return -1; - } - else if (node->value < value) { - return 1; - } - else { - return 0; - } +PANDAS_INLINE int _node_cmp(node_t *node, double value) { + if (node->is_nil || node->value > value) { + return -1; + } else if (node->value < value) { + return 1; + } else { + return 0; + } } PANDAS_INLINE double skiplist_get(skiplist_t *skp, int i, int *ret) { - node_t *node; - int level; - - if (i < 0 || i >= skp->size) { - *ret = 0; - return 0; - } - - node = skp->head; - ++i; - for (level = skp->maxlevels - 1; level >= 0; --level) - { - while (node->width[level] <= i) - { - i -= node->width[level]; - node = node->next[level]; + node_t *node; + int level; + + if (i < 0 || i >= skp->size) { + *ret = 0; + return 0; + } + + node = skp->head; + ++i; + for (level = skp->maxlevels - 1; level >= 0; --level) { + while (node->width[level] <= i) { + i -= node->width[level]; + node = node->next[level]; + } } - } - *ret = 1; - return node->value; + *ret = 1; + return node->value; } PANDAS_INLINE int skiplist_insert(skiplist_t *skp, double value) { - node_t *node, *prevnode, *newnode, *next_at_level; - int *steps_at_level; - int size, steps, level; - node_t **chain; - - chain = skp->tmp_chain; - - steps_at_level = skp->tmp_steps; - memset(steps_at_level, 0, skp->maxlevels * sizeof(int)); - - node = skp->head; - - for (level = skp->maxlevels - 1; level >= 0; --level) - { - next_at_level = node->next[level]; - while (_node_cmp(next_at_level, value) >= 0) { - steps_at_level[level] += node->width[level]; - node = next_at_level; - next_at_level = node->next[level]; + node_t *node, *prevnode, *newnode, *next_at_level; + int *steps_at_level; + int size, steps, level; + node_t **chain; + + chain = skp->tmp_chain; + + steps_at_level = skp->tmp_steps; + memset(steps_at_level, 0, skp->maxlevels * sizeof(int)); + + node = skp->head; + + for (level = skp->maxlevels - 1; level >= 0; --level) { + next_at_level = node->next[level]; + while (_node_cmp(next_at_level, value) >= 0) { + steps_at_level[level] += node->width[level]; + node = next_at_level; + next_at_level = node->next[level]; + } + chain[level] = node; } - chain[level] = node; - } - size = int_min(skp->maxlevels, 1 - ((int) Log2(urand()))); + size = int_min(skp->maxlevels, 1 - ((int)Log2(urand()))); - newnode = node_init(value, size); - if (!newnode) { - return -1; - } - steps = 0; + newnode = node_init(value, size); + if (!newnode) { + return -1; + } + steps = 0; - for (level = 0; level < size; ++level) { - prevnode = chain[level]; - newnode->next[level] = prevnode->next[level]; + for (level = 0; level < size; ++level) { + prevnode = chain[level]; + newnode->next[level] = prevnode->next[level]; - prevnode->next[level] = newnode; - node_incref(newnode); // increment the reference count + prevnode->next[level] = newnode; + node_incref(newnode); // increment the reference count - newnode->width[level] = prevnode->width[level] - steps; - prevnode->width[level] = steps + 1; + newnode->width[level] = prevnode->width[level] - steps; + prevnode->width[level] = steps + 1; - steps += steps_at_level[level]; - } + steps += steps_at_level[level]; + } - for (level = size; level < skp->maxlevels; ++level) { - chain[level]->width[level] += 1; - } + for (level = size; level < skp->maxlevels; ++level) { + chain[level]->width[level] += 1; + } - ++(skp->size); + ++(skp->size); - return 1; + return 1; } PANDAS_INLINE int skiplist_remove(skiplist_t *skp, double value) { - int level, size; - node_t *node, *prevnode, *tmpnode, *next_at_level; - node_t **chain; - - chain = skp->tmp_chain; - node = skp->head; - - for (level = skp->maxlevels - 1; level >= 0; --level) - { - next_at_level = node->next[level]; - while (_node_cmp(next_at_level, value) > 0) { - node = next_at_level; - next_at_level = node->next[level]; + int level, size; + node_t *node, *prevnode, *tmpnode, *next_at_level; + node_t **chain; + + chain = skp->tmp_chain; + node = skp->head; + + for (level = skp->maxlevels - 1; level >= 0; --level) { + next_at_level = node->next[level]; + while (_node_cmp(next_at_level, value) > 0) { + node = next_at_level; + next_at_level = node->next[level]; + } + chain[level] = node; } - chain[level] = node; - } - if (value != chain[0]->next[0]->value) { - return 0; - } + if (value != chain[0]->next[0]->value) { + return 0; + } - size = chain[0]->next[0]->levels; + size = chain[0]->next[0]->levels; - for (level = 0; level < size; ++level) { - prevnode = chain[level]; + for (level = 0; level < size; ++level) { + prevnode = chain[level]; - tmpnode = prevnode->next[level]; + tmpnode = prevnode->next[level]; - prevnode->width[level] += tmpnode->width[level] - 1; - prevnode->next[level] = tmpnode->next[level]; + prevnode->width[level] += tmpnode->width[level] - 1; + prevnode->next[level] = tmpnode->next[level]; - tmpnode->next[level] = NULL; - node_destroy(tmpnode); // decrement refcount or free - } + tmpnode->next[level] = NULL; + node_destroy(tmpnode); // decrement refcount or free + } - for (level = size; level < skp->maxlevels; ++level) { - --(chain[level]->width[level]); - } + for (level = size; level < skp->maxlevels; ++level) { + --(chain[level]->width[level]); + } - --(skp->size); - return 1; + --(skp->size); + return 1; } + +#endif // PANDAS_SRC_SKIPLIST_H_ diff --git a/pandas/src/ujson/lib/ultrajson.h b/pandas/src/ujson/lib/ultrajson.h index c37fe8c8e6c38..3bfb4b26c0095 100644 --- a/pandas/src/ujson/lib/ultrajson.h +++ b/pandas/src/ujson/lib/ultrajson.h @@ -49,8 +49,8 @@ tree doesn't have cyclic references. */ -#ifndef __ULTRAJSON_H__ -#define __ULTRAJSON_H__ +#ifndef PANDAS_SRC_UJSON_LIB_ULTRAJSON_H_ +#define PANDAS_SRC_UJSON_LIB_ULTRAJSON_H_ #include #include @@ -143,25 +143,23 @@ typedef int64_t JSLONG; #error "Endianess not supported" #endif -enum JSTYPES -{ - JT_NULL, // NULL - JT_TRUE, //boolean true - JT_FALSE, //boolean false - JT_INT, //(JSINT32 (signed 32-bit)) - JT_LONG, //(JSINT64 (signed 64-bit)) - JT_DOUBLE, //(double) - JT_UTF8, //(char 8-bit) - JT_ARRAY, // Array structure - JT_OBJECT, // Key/Value structure - JT_INVALID, // Internal, do not return nor expect +enum JSTYPES { + JT_NULL, // NULL + JT_TRUE, // boolean true + JT_FALSE, // boolean false + JT_INT, // (JSINT32 (signed 32-bit)) + JT_LONG, // (JSINT64 (signed 64-bit)) + JT_DOUBLE, // (double) + JT_UTF8, // (char 8-bit) + JT_ARRAY, // Array structure + JT_OBJECT, // Key/Value structure + JT_INVALID, // Internal, do not return nor expect }; typedef void * JSOBJ; typedef void * JSITER; -typedef struct __JSONTypeContext -{ +typedef struct __JSONTypeContext { int type; void *encoder; void *prv; @@ -173,16 +171,17 @@ typedef void (*JSPFN_ITERBEGIN)(JSOBJ obj, JSONTypeContext *tc); typedef int (*JSPFN_ITERNEXT)(JSOBJ obj, JSONTypeContext *tc); typedef void (*JSPFN_ITEREND)(JSOBJ obj, JSONTypeContext *tc); typedef JSOBJ (*JSPFN_ITERGETVALUE)(JSOBJ obj, JSONTypeContext *tc); -typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, size_t *outLen); +typedef char *(*JSPFN_ITERGETNAME)(JSOBJ obj, JSONTypeContext *tc, + size_t *outLen); typedef void *(*JSPFN_MALLOC)(size_t size); typedef void (*JSPFN_FREE)(void *pptr); typedef void *(*JSPFN_REALLOC)(void *base, size_t size); -typedef struct __JSONObjectEncoder -{ +typedef struct __JSONObjectEncoder { void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc); void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc); - const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen); + const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, + size_t *_outLen); JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc); JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc); double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc); @@ -256,10 +255,8 @@ typedef struct __JSONObjectEncoder char *end; int heap; int level; - } JSONObjectEncoder; - /* Encode an object structure into JSON. @@ -279,12 +276,10 @@ Life cycle of the provided buffer must still be handled by caller. If the return value doesn't equal the specified buffer caller must release the memory using JSONObjectEncoder.free or free() as specified when calling this function. */ -EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *buffer, size_t cbBuffer); - +EXPORTFUNCTION char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, + char *buffer, size_t cbBuffer); - -typedef struct __JSONObjectDecoder -{ +typedef struct __JSONObjectDecoder { JSOBJ (*newString)(void *prv, wchar_t *start, wchar_t *end); int (*objectAddKey)(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value); int (*arrayAddItem)(void *prv, JSOBJ obj, JSOBJ value); @@ -308,7 +303,8 @@ typedef struct __JSONObjectDecoder void *prv; } 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); EXPORTFUNCTION void encode(JSOBJ, JSONObjectEncoder *, const char *, size_t); -#endif +#endif // PANDAS_SRC_UJSON_LIB_ULTRAJSON_H_ diff --git a/pandas/src/ujson/lib/ultrajsondec.c b/pandas/src/ujson/lib/ultrajsondec.c index 5496068832f2e..a847b0f5d5102 100644 --- a/pandas/src/ujson/lib/ultrajsondec.c +++ b/pandas/src/ujson/lib/ultrajsondec.c @@ -16,8 +16,10 @@ derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE +LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -27,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) https://github.com/client9/stringencoders -Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. +Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights +reserved. Numeric decoder derived from from TCL library http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms @@ -35,15 +38,15 @@ Numeric decoder derived from from TCL library * Copyright (c) 1994 Sun Microsystems, Inc. */ -#include "ultrajson.h" -#include #include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include +#include "ultrajson.h" #ifndef TRUE #define TRUE 1 @@ -53,871 +56,1096 @@ Numeric decoder derived from from TCL library #define NULL 0 #endif -struct DecoderState -{ - char *start; - char *end; - wchar_t *escStart; - wchar_t *escEnd; - int escHeap; - int lastType; - JSUINT32 objDepth; - void *prv; - JSONObjectDecoder *dec; +struct DecoderState { + char *start; + char *end; + wchar_t *escStart; + wchar_t *escEnd; + int escHeap; + int lastType; + JSUINT32 objDepth; + void *prv; + JSONObjectDecoder *dec; }; -JSOBJ FASTCALL_MSVC decode_any( struct DecoderState *ds) FASTCALL_ATTR; -typedef JSOBJ (*PFN_DECODER)( struct DecoderState *ds); +JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds) FASTCALL_ATTR; +typedef JSOBJ (*PFN_DECODER)(struct DecoderState *ds); -static JSOBJ SetError( struct DecoderState *ds, int offset, const char *message) -{ - ds->dec->errorOffset = ds->start + offset; - ds->dec->errorStr = (char *) message; - return NULL; +static JSOBJ SetError(struct DecoderState *ds, int offset, + const char *message) { + ds->dec->errorOffset = ds->start + offset; + ds->dec->errorStr = (char *)message; + return NULL; } -double createDouble(double intNeg, double intValue, double frcValue, int frcDecimalCount) -{ - static const double g_pow10[] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001, 0.000000000001, 0.0000000000001, 0.00000000000001, 0.000000000000001}; - return (intValue + (frcValue * g_pow10[frcDecimalCount])) * intNeg; +double createDouble(double intNeg, double intValue, double frcValue, + int frcDecimalCount) { + static const double g_pow10[] = {1.0, + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001, + 0.00000000001, + 0.000000000001, + 0.0000000000001, + 0.00000000000001, + 0.000000000000001}; + return (intValue + (frcValue * g_pow10[frcDecimalCount])) * intNeg; } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodePreciseFloat(struct DecoderState *ds) -{ - char *end; - double value; - errno = 0; +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decodePreciseFloat(struct DecoderState *ds) { + char *end; + double value; + errno = 0; - value = strtod(ds->start, &end); + value = strtod(ds->start, &end); - if (errno == ERANGE) - { - return SetError(ds, -1, "Range error when decoding numeric as double"); - } + if (errno == ERANGE) { + return SetError(ds, -1, "Range error when decoding numeric as double"); + } - ds->start = end; - return ds->dec->newDouble(ds->prv, value); + ds->start = end; + return ds->dec->newDouble(ds->prv, value); } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_numeric (struct DecoderState *ds) -{ - int intNeg = 1; - int mantSize = 0; - JSUINT64 intValue; - int chr; - int decimalCount = 0; - double frcValue = 0.0; - double expNeg; - double expValue; - char *offset = ds->start; - - JSUINT64 overflowLimit = LLONG_MAX; - - if (*(offset) == '-') - { - offset ++; - intNeg = -1; - overflowLimit = LLONG_MIN; - } - - // Scan integer part - intValue = 0; - - while (1) - { - chr = (int) (unsigned char) *(offset); - - switch (chr) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - //FIXME: Check for arithemtic overflow here - //PERF: Don't do 64-bit arithmetic here unless we know we have to - intValue = intValue * 10ULL + (JSLONG) (chr - 48); - - if (intValue > overflowLimit) - { - return SetError(ds, -1, overflowLimit == LLONG_MAX ? "Value is too big" : "Value is too small"); - } +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_numeric(struct DecoderState *ds) { + int intNeg = 1; + int mantSize = 0; + JSUINT64 intValue; + int chr; + int decimalCount = 0; + double frcValue = 0.0; + double expNeg; + double expValue; + char *offset = ds->start; + + JSUINT64 overflowLimit = LLONG_MAX; + + if (*(offset) == '-') { + offset++; + intNeg = -1; + overflowLimit = LLONG_MIN; + } - offset ++; - mantSize ++; - break; - } - case '.': - { - offset ++; - goto DECODE_FRACTION; - break; - } - case 'e': - case 'E': - { - offset ++; - goto DECODE_EXPONENT; - break; - } - - default: - { - goto BREAK_INT_LOOP; - break; - } + // Scan integer part + intValue = 0; + + while (1) { + chr = (int)(unsigned char)*(offset); + + switch (chr) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + // FIXME: Check for arithemtic overflow here + // PERF: Don't do 64-bit arithmetic here unless we know we have + // to + intValue = intValue * 10ULL + (JSLONG)(chr - 48); + + if (intValue > overflowLimit) { + return SetError(ds, -1, overflowLimit == LLONG_MAX + ? "Value is too big" + : "Value is too small"); + } + + offset++; + mantSize++; + break; + } + case '.': { + offset++; + goto DECODE_FRACTION; + break; + } + case 'e': + case 'E': { + offset++; + goto DECODE_EXPONENT; + break; + } + + default: { + goto BREAK_INT_LOOP; + break; + } + } } - } BREAK_INT_LOOP: - ds->lastType = JT_INT; - ds->start = offset; + ds->lastType = JT_INT; + ds->start = offset; - if ((intValue >> 31)) - { - return ds->dec->newLong(ds->prv, (JSINT64) (intValue * (JSINT64) intNeg)); - } - else - { - return ds->dec->newInt(ds->prv, (JSINT32) (intValue * intNeg)); - } + if ((intValue >> 31)) { + return ds->dec->newLong(ds->prv, (JSINT64)(intValue * (JSINT64)intNeg)); + } else { + return ds->dec->newInt(ds->prv, (JSINT32)(intValue * intNeg)); + } DECODE_FRACTION: - if (ds->dec->preciseFloat) - { - return decodePreciseFloat(ds); - } - - // Scan fraction part - frcValue = 0.0; - for (;;) - { - chr = (int) (unsigned char) *(offset); - - switch (chr) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - if (decimalCount < JSON_DOUBLE_MAX_DECIMALS) - { - frcValue = frcValue * 10.0 + (double) (chr - 48); - decimalCount ++; + if (ds->dec->preciseFloat) { + return decodePreciseFloat(ds); + } + + // Scan fraction part + frcValue = 0.0; + for (;;) { + chr = (int)(unsigned char)*(offset); + + switch (chr) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + if (decimalCount < JSON_DOUBLE_MAX_DECIMALS) { + frcValue = frcValue * 10.0 + (double)(chr - 48); + decimalCount++; + } + offset++; + break; + } + case 'e': + case 'E': { + offset++; + goto DECODE_EXPONENT; + break; + } + default: { goto BREAK_FRC_LOOP; } } - offset ++; - break; - } - case 'e': - case 'E': - { - offset ++; - goto DECODE_EXPONENT; - break; - } - default: - { - goto BREAK_FRC_LOOP; - } } - } BREAK_FRC_LOOP: - //FIXME: Check for arithemtic overflow here - ds->lastType = JT_DOUBLE; - ds->start = offset; - return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue, frcValue, decimalCount)); + // FIXME: Check for arithemtic overflow here + ds->lastType = JT_DOUBLE; + ds->start = offset; + return ds->dec->newDouble( + ds->prv, + createDouble((double)intNeg, (double)intValue, frcValue, decimalCount)); DECODE_EXPONENT: - if (ds->dec->preciseFloat) - { - return decodePreciseFloat(ds); - } - - expNeg = 1.0; - - if (*(offset) == '-') - { - expNeg = -1.0; - offset ++; - } - else - if (*(offset) == '+') - { - expNeg = +1.0; - offset ++; - } - - expValue = 0.0; - - for (;;) - { - chr = (int) (unsigned char) *(offset); - - switch (chr) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - expValue = expValue * 10.0 + (double) (chr - 48); - offset ++; - break; - } - default: - { - goto BREAK_EXP_LOOP; - } + if (ds->dec->preciseFloat) { + return decodePreciseFloat(ds); + } + + expNeg = 1.0; + + if (*(offset) == '-') { + expNeg = -1.0; + offset++; + } else if (*(offset) == '+') { + expNeg = +1.0; + offset++; + } + + expValue = 0.0; + + for (;;) { + chr = (int)(unsigned char)*(offset); + + switch (chr) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + expValue = expValue * 10.0 + (double)(chr - 48); + offset++; + break; + } + default: { goto BREAK_EXP_LOOP; } + } } - } BREAK_EXP_LOOP: - //FIXME: Check for arithemtic overflow here - ds->lastType = JT_DOUBLE; - ds->start = offset; - return ds->dec->newDouble (ds->prv, createDouble( (double) intNeg, (double) intValue , frcValue, decimalCount) * pow(10.0, expValue * expNeg)); + // FIXME: Check for arithemtic overflow here + ds->lastType = JT_DOUBLE; + ds->start = offset; + return ds->dec->newDouble( + ds->prv, + createDouble((double)intNeg, (double)intValue, frcValue, decimalCount) * + pow(10.0, expValue * expNeg)); } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_true ( struct DecoderState *ds) -{ - char *offset = ds->start; - offset ++; +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_true(struct DecoderState *ds) { + char *offset = ds->start; + offset++; - if (*(offset++) != 'r') - goto SETERROR; - if (*(offset++) != 'u') - goto SETERROR; - if (*(offset++) != 'e') - goto SETERROR; + if (*(offset++) != 'r') goto SETERROR; + if (*(offset++) != 'u') goto SETERROR; + if (*(offset++) != 'e') goto SETERROR; - ds->lastType = JT_TRUE; - ds->start = offset; - return ds->dec->newTrue(ds->prv); + ds->lastType = JT_TRUE; + ds->start = offset; + return ds->dec->newTrue(ds->prv); SETERROR: - return SetError(ds, -1, "Unexpected character found when decoding 'true'"); + return SetError(ds, -1, "Unexpected character found when decoding 'true'"); } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_false ( struct DecoderState *ds) -{ - char *offset = ds->start; - offset ++; +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_false(struct DecoderState *ds) { + char *offset = ds->start; + offset++; - if (*(offset++) != 'a') - goto SETERROR; - if (*(offset++) != 'l') - goto SETERROR; - if (*(offset++) != 's') - goto SETERROR; - if (*(offset++) != 'e') - goto SETERROR; + if (*(offset++) != 'a') goto SETERROR; + if (*(offset++) != 'l') goto SETERROR; + if (*(offset++) != 's') goto SETERROR; + if (*(offset++) != 'e') goto SETERROR; - ds->lastType = JT_FALSE; - ds->start = offset; - return ds->dec->newFalse(ds->prv); + ds->lastType = JT_FALSE; + ds->start = offset; + return ds->dec->newFalse(ds->prv); SETERROR: - return SetError(ds, -1, "Unexpected character found when decoding 'false'"); + return SetError(ds, -1, "Unexpected character found when decoding 'false'"); } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_null ( struct DecoderState *ds) -{ - char *offset = ds->start; - offset ++; +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_null(struct DecoderState *ds) { + char *offset = ds->start; + offset++; - if (*(offset++) != 'u') - goto SETERROR; - if (*(offset++) != 'l') - goto SETERROR; - if (*(offset++) != 'l') - goto SETERROR; + if (*(offset++) != 'u') goto SETERROR; + if (*(offset++) != 'l') goto SETERROR; + if (*(offset++) != 'l') goto SETERROR; - ds->lastType = JT_NULL; - ds->start = offset; - return ds->dec->newNull(ds->prv); + ds->lastType = JT_NULL; + ds->start = offset; + return ds->dec->newNull(ds->prv); SETERROR: - return SetError(ds, -1, "Unexpected character found when decoding 'null'"); + return SetError(ds, -1, "Unexpected character found when decoding 'null'"); } -FASTCALL_ATTR void FASTCALL_MSVC SkipWhitespace(struct DecoderState *ds) -{ - char *offset; - - for (offset = ds->start; (ds->end - offset) > 0; offset ++) - { - switch (*offset) - { - case ' ': - case '\t': - case '\r': - case '\n': - break; - - default: - ds->start = offset; - return; +FASTCALL_ATTR void FASTCALL_MSVC SkipWhitespace(struct DecoderState *ds) { + char *offset; + + for (offset = ds->start; (ds->end - offset) > 0; offset++) { + switch (*offset) { + case ' ': + case '\t': + case '\r': + case '\n': + break; + + default: + ds->start = offset; + return; + } } - } - if (offset == ds->end) - { - ds->start = ds->end; - } + if (offset == ds->end) { + ds->start = ds->end; + } } -enum DECODESTRINGSTATE -{ - DS_ISNULL = 0x32, - DS_ISQUOTE, - DS_ISESCAPE, - DS_UTFLENERROR, - +enum DECODESTRINGSTATE { + DS_ISNULL = 0x32, + DS_ISQUOTE, + DS_ISESCAPE, + DS_UTFLENERROR, }; -static const JSUINT8 g_decoderLookup[256] = -{ - /* 0x00 */ DS_ISNULL, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x20 */ 1, 1, DS_ISQUOTE, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, DS_ISESCAPE, 1, 1, 1, - /* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0xa0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0xb0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 0xc0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - /* 0xf0 */ 4, 4, 4, 4, 4, 4, 4, 4, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, +static const JSUINT8 g_decoderLookup[256] = { + /* 0x00 */ DS_ISNULL, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x10 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x20 */ 1, + 1, + DS_ISQUOTE, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x30 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x40 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x50 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + DS_ISESCAPE, + 1, + 1, + 1, + /* 0x60 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x70 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x80 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x90 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xa0 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xb0 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xc0 */ 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + /* 0xd0 */ 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + /* 0xe0 */ 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + /* 0xf0 */ 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, + DS_UTFLENERROR, }; -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds) -{ - JSUTF16 sur[2] = { 0 }; - int iSur = 0; - int index; - wchar_t *escOffset; - wchar_t *escStart; - size_t escLen = (ds->escEnd - ds->escStart); - JSUINT8 *inputOffset; - JSUINT8 oct; - JSUTF32 ucs; - ds->lastType = JT_INVALID; - ds->start ++; - - if ( (size_t) (ds->end - ds->start) > escLen) - { - size_t newSize = (ds->end - ds->start); - - if (ds->escHeap) - { - if (newSize > (SIZE_MAX / sizeof(wchar_t))) - { - return SetError(ds, -1, "Could not reserve memory block"); - } - escStart = (wchar_t *)ds->dec->realloc(ds->escStart, newSize * sizeof(wchar_t)); - if (!escStart) - { - ds->dec->free(ds->escStart); - return SetError(ds, -1, "Could not reserve memory block"); - } - ds->escStart = escStart; - } - else - { - wchar_t *oldStart = ds->escStart; - if (newSize > (SIZE_MAX / sizeof(wchar_t))) - { - return SetError(ds, -1, "Could not reserve memory block"); - } - ds->escStart = (wchar_t *) ds->dec->malloc(newSize * sizeof(wchar_t)); - if (!ds->escStart) - { - return SetError(ds, -1, "Could not reserve memory block"); - } - ds->escHeap = 1; - memcpy(ds->escStart, oldStart, escLen * sizeof(wchar_t)); - } +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string(struct DecoderState *ds) { + JSUTF16 sur[2] = {0}; + int iSur = 0; + int index; + wchar_t *escOffset; + wchar_t *escStart; + size_t escLen = (ds->escEnd - ds->escStart); + JSUINT8 *inputOffset; + JSUINT8 oct; + JSUTF32 ucs; + ds->lastType = JT_INVALID; + ds->start++; - ds->escEnd = ds->escStart + newSize; - } - - escOffset = ds->escStart; - inputOffset = (JSUINT8 *) ds->start; - - for (;;) - { - switch (g_decoderLookup[(JSUINT8)(*inputOffset)]) - { - case DS_ISNULL: - { - return SetError(ds, -1, "Unmatched ''\"' when when decoding 'string'"); - } - case DS_ISQUOTE: - { - ds->lastType = JT_UTF8; - inputOffset ++; - ds->start += ( (char *) inputOffset - (ds->start)); - return ds->dec->newString(ds->prv, ds->escStart, escOffset); - } - case DS_UTFLENERROR: - { - return SetError (ds, -1, "Invalid UTF-8 sequence length when decoding 'string'"); - } - case DS_ISESCAPE: - inputOffset ++; - switch (*inputOffset) - { - case '\\': *(escOffset++) = L'\\'; inputOffset++; continue; - case '\"': *(escOffset++) = L'\"'; inputOffset++; continue; - case '/': *(escOffset++) = L'/'; inputOffset++; continue; - case 'b': *(escOffset++) = L'\b'; inputOffset++; continue; - case 'f': *(escOffset++) = L'\f'; inputOffset++; continue; - case 'n': *(escOffset++) = L'\n'; inputOffset++; continue; - case 'r': *(escOffset++) = L'\r'; inputOffset++; continue; - case 't': *(escOffset++) = L'\t'; inputOffset++; continue; - - case 'u': - { - int index; - inputOffset ++; - - for (index = 0; index < 4; index ++) - { - switch (*inputOffset) - { - case '\0': return SetError (ds, -1, "Unterminated unicode escape sequence when decoding 'string'"); - default: return SetError (ds, -1, "Unexpected character in unicode escape sequence when decoding 'string'"); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - sur[iSur] = (sur[iSur] << 4) + (JSUTF16) (*inputOffset - '0'); - break; - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'a'); - break; - - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'A'); - break; - } - - inputOffset ++; + if ((size_t)(ds->end - ds->start) > escLen) { + size_t newSize = (ds->end - ds->start); + + if (ds->escHeap) { + if (newSize > (SIZE_MAX / sizeof(wchar_t))) { + return SetError(ds, -1, "Could not reserve memory block"); + } + escStart = (wchar_t *)ds->dec->realloc(ds->escStart, + newSize * sizeof(wchar_t)); + if (!escStart) { + ds->dec->free(ds->escStart); + return SetError(ds, -1, "Could not reserve memory block"); } + ds->escStart = escStart; + } else { + wchar_t *oldStart = ds->escStart; + if (newSize > (SIZE_MAX / sizeof(wchar_t))) { + return SetError(ds, -1, "Could not reserve memory block"); + } + ds->escStart = + (wchar_t *)ds->dec->malloc(newSize * sizeof(wchar_t)); + if (!ds->escStart) { + return SetError(ds, -1, "Could not reserve memory block"); + } + ds->escHeap = 1; + memcpy(ds->escStart, oldStart, escLen * sizeof(wchar_t)); + } - if (iSur == 0) - { - if((sur[iSur] & 0xfc00) == 0xd800) - { - // First of a surrogate pair, continue parsing - iSur ++; - break; - } - (*escOffset++) = (wchar_t) sur[iSur]; - iSur = 0; + ds->escEnd = ds->escStart + newSize; + } + + escOffset = ds->escStart; + inputOffset = (JSUINT8 *)ds->start; + + for (;;) { + switch (g_decoderLookup[(JSUINT8)(*inputOffset)]) { + case DS_ISNULL: { + return SetError(ds, -1, + "Unmatched ''\"' when when decoding 'string'"); + } + case DS_ISQUOTE: { + ds->lastType = JT_UTF8; + inputOffset++; + ds->start += ((char *)inputOffset - (ds->start)); + return ds->dec->newString(ds->prv, ds->escStart, escOffset); } - else - { - // Decode pair - if ((sur[1] & 0xfc00) != 0xdc00) - { - return SetError (ds, -1, "Unpaired high surrogate when decoding 'string'"); - } + case DS_UTFLENERROR: { + return SetError( + ds, -1, + "Invalid UTF-8 sequence length when decoding 'string'"); + } + case DS_ISESCAPE: + inputOffset++; + switch (*inputOffset) { + case '\\': + *(escOffset++) = L'\\'; + inputOffset++; + continue; + case '\"': + *(escOffset++) = L'\"'; + inputOffset++; + continue; + case '/': + *(escOffset++) = L'/'; + inputOffset++; + continue; + case 'b': + *(escOffset++) = L'\b'; + inputOffset++; + continue; + case 'f': + *(escOffset++) = L'\f'; + inputOffset++; + continue; + case 'n': + *(escOffset++) = L'\n'; + inputOffset++; + continue; + case 'r': + *(escOffset++) = L'\r'; + inputOffset++; + continue; + case 't': + *(escOffset++) = L'\t'; + inputOffset++; + continue; + + case 'u': { + int index; + inputOffset++; + + for (index = 0; index < 4; index++) { + switch (*inputOffset) { + case '\0': + return SetError(ds, -1, + "Unterminated unicode " + "escape sequence when " + "decoding 'string'"); + default: + return SetError(ds, -1, + "Unexpected character in " + "unicode escape sequence " + "when decoding 'string'"); + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + sur[iSur] = (sur[iSur] << 4) + + (JSUTF16)(*inputOffset - '0'); + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + sur[iSur] = (sur[iSur] << 4) + 10 + + (JSUTF16)(*inputOffset - 'a'); + break; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + sur[iSur] = (sur[iSur] << 4) + 10 + + (JSUTF16)(*inputOffset - 'A'); + break; + } + + inputOffset++; + } + + if (iSur == 0) { + if ((sur[iSur] & 0xfc00) == 0xd800) { + // First of a surrogate pair, continue parsing + iSur++; + break; + } + (*escOffset++) = (wchar_t)sur[iSur]; + iSur = 0; + } else { + // Decode pair + if ((sur[1] & 0xfc00) != 0xdc00) { + return SetError(ds, -1, + "Unpaired high surrogate when " + "decoding 'string'"); + } #if WCHAR_MAX == 0xffff - (*escOffset++) = (wchar_t) sur[0]; - (*escOffset++) = (wchar_t) sur[1]; + (*escOffset++) = (wchar_t)sur[0]; + (*escOffset++) = (wchar_t)sur[1]; #else - (*escOffset++) = (wchar_t) 0x10000 + (((sur[0] - 0xd800) << 10) | (sur[1] - 0xdc00)); + (*escOffset++) = + (wchar_t)0x10000 + + (((sur[0] - 0xd800) << 10) | (sur[1] - 0xdc00)); #endif - iSur = 0; + iSur = 0; + } + break; + } + + case '\0': + return SetError(ds, -1, + "Unterminated escape sequence when " + "decoding 'string'"); + default: + return SetError(ds, -1, + "Unrecognized escape sequence when " + "decoding 'string'"); + } + break; + + case 1: { + *(escOffset++) = (wchar_t)(*inputOffset++); + break; } - break; - } - case '\0': return SetError(ds, -1, "Unterminated escape sequence when decoding 'string'"); - default: return SetError(ds, -1, "Unrecognized escape sequence when decoding 'string'"); - } - break; - - case 1: - { - *(escOffset++) = (wchar_t) (*inputOffset++); - break; - } - - case 2: - { - ucs = (*inputOffset++) & 0x1f; - ucs <<= 6; - if (((*inputOffset) & 0x80) != 0x80) - { - return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); - } - ucs |= (*inputOffset++) & 0x3f; - if (ucs < 0x80) return SetError (ds, -1, "Overlong 2 byte UTF-8 sequence detected when decoding 'string'"); - *(escOffset++) = (wchar_t) ucs; - break; - } - - case 3: - { - JSUTF32 ucs = 0; - ucs |= (*inputOffset++) & 0x0f; - - for (index = 0; index < 2; index ++) - { - ucs <<= 6; - oct = (*inputOffset++); - - if ((oct & 0x80) != 0x80) - { - return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); - } - - ucs |= oct & 0x3f; - } + case 2: { + ucs = (*inputOffset++) & 0x1f; + ucs <<= 6; + if (((*inputOffset) & 0x80) != 0x80) { + return SetError(ds, -1, + "Invalid octet in UTF-8 sequence when " + "decoding 'string'"); + } + ucs |= (*inputOffset++) & 0x3f; + if (ucs < 0x80) + return SetError(ds, -1, + "Overlong 2 byte UTF-8 sequence detected " + "when decoding 'string'"); + *(escOffset++) = (wchar_t)ucs; + break; + } - if (ucs < 0x800) return SetError (ds, -1, "Overlong 3 byte UTF-8 sequence detected when encoding string"); - *(escOffset++) = (wchar_t) ucs; - break; - } + case 3: { + JSUTF32 ucs = 0; + ucs |= (*inputOffset++) & 0x0f; - case 4: - { - JSUTF32 ucs = 0; - ucs |= (*inputOffset++) & 0x07; + for (index = 0; index < 2; index++) { + ucs <<= 6; + oct = (*inputOffset++); - for (index = 0; index < 3; index ++) - { - ucs <<= 6; - oct = (*inputOffset++); + if ((oct & 0x80) != 0x80) { + return SetError(ds, -1, + "Invalid octet in UTF-8 sequence when " + "decoding 'string'"); + } - if ((oct & 0x80) != 0x80) - { - return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'"); - } + ucs |= oct & 0x3f; + } - ucs |= oct & 0x3f; - } + if (ucs < 0x800) + return SetError(ds, -1, + "Overlong 3 byte UTF-8 sequence detected " + "when encoding string"); + *(escOffset++) = (wchar_t)ucs; + break; + } - if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4 byte UTF-8 sequence detected when decoding 'string'"); + case 4: { + JSUTF32 ucs = 0; + ucs |= (*inputOffset++) & 0x07; + + for (index = 0; index < 3; index++) { + ucs <<= 6; + oct = (*inputOffset++); + + if ((oct & 0x80) != 0x80) { + return SetError(ds, -1, + "Invalid octet in UTF-8 sequence when " + "decoding 'string'"); + } + + ucs |= oct & 0x3f; + } + + if (ucs < 0x10000) + return SetError(ds, -1, + "Overlong 4 byte UTF-8 sequence detected " + "when decoding 'string'"); #if WCHAR_MAX == 0xffff - if (ucs >= 0x10000) - { - ucs -= 0x10000; - *(escOffset++) = (wchar_t) (ucs >> 10) + 0xd800; - *(escOffset++) = (wchar_t) (ucs & 0x3ff) + 0xdc00; - } - else - { - *(escOffset++) = (wchar_t) ucs; - } + if (ucs >= 0x10000) { + ucs -= 0x10000; + *(escOffset++) = (wchar_t)(ucs >> 10) + 0xd800; + *(escOffset++) = (wchar_t)(ucs & 0x3ff) + 0xdc00; + } else { + *(escOffset++) = (wchar_t)ucs; + } #else - *(escOffset++) = (wchar_t) ucs; + *(escOffset++) = (wchar_t)ucs; #endif - break; - } + break; + } + } } - } } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_array(struct DecoderState *ds) -{ - JSOBJ itemValue; - JSOBJ newObj; - int len; - ds->objDepth++; - if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { - return SetError(ds, -1, "Reached object decoding depth limit"); - } - - newObj = ds->dec->newArray(ds->prv, ds->dec); - len = 0; - - ds->lastType = JT_INVALID; - ds->start ++; - - for (;;) - { - SkipWhitespace(ds); - - if ((*ds->start) == ']') - { - ds->objDepth--; - if (len == 0) - { - ds->start ++; - return ds->dec->endArray(ds->prv, newObj); - } - - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return SetError(ds, -1, "Unexpected character found when decoding array value (1)"); +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_array(struct DecoderState *ds) { + JSOBJ itemValue; + JSOBJ newObj; + int len; + ds->objDepth++; + if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { + return SetError(ds, -1, "Reached object decoding depth limit"); } - itemValue = decode_any(ds); + newObj = ds->dec->newArray(ds->prv, ds->dec); + len = 0; - if (itemValue == NULL) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return NULL; - } + ds->lastType = JT_INVALID; + ds->start++; - if (!ds->dec->arrayAddItem (ds->prv, newObj, itemValue)) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return NULL; - } + for (;;) { + SkipWhitespace(ds); + + if ((*ds->start) == ']') { + ds->objDepth--; + if (len == 0) { + ds->start++; + return ds->dec->endArray(ds->prv, newObj); + } + + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return SetError( + ds, -1, + "Unexpected character found when decoding array value (1)"); + } - SkipWhitespace(ds); + itemValue = decode_any(ds); + + if (itemValue == NULL) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return NULL; + } + + if (!ds->dec->arrayAddItem(ds->prv, newObj, itemValue)) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return NULL; + } + + SkipWhitespace(ds); + + switch (*(ds->start++)) { + case ']': { + ds->objDepth--; + return ds->dec->endArray(ds->prv, newObj); + } + case ',': + break; - switch (*(ds->start++)) - { - case ']': - { - ds->objDepth--; - return ds->dec->endArray(ds->prv, newObj); + default: + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return SetError( + ds, -1, + "Unexpected character found when decoding array value (2)"); + } + + len++; } - case ',': - break; +} + +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_object(struct DecoderState *ds) { + JSOBJ itemName; + JSOBJ itemValue; + JSOBJ newObj; - default: - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return SetError(ds, -1, "Unexpected character found when decoding array value (2)"); + ds->objDepth++; + if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { + return SetError(ds, -1, "Reached object decoding depth limit"); } - len ++; - } -} + newObj = ds->dec->newObject(ds->prv, ds->dec); -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_object( struct DecoderState *ds) -{ - JSOBJ itemName; - JSOBJ itemValue; - JSOBJ newObj; + ds->start++; - ds->objDepth++; - if (ds->objDepth > JSON_MAX_OBJECT_DEPTH) { - return SetError(ds, -1, "Reached object decoding depth limit"); - } + for (;;) { + SkipWhitespace(ds); - newObj = ds->dec->newObject(ds->prv, ds->dec); + if ((*ds->start) == '}') { + ds->objDepth--; + ds->start++; + return ds->dec->endObject(ds->prv, newObj); + } - ds->start ++; + ds->lastType = JT_INVALID; + itemName = decode_any(ds); - for (;;) - { - SkipWhitespace(ds); + if (itemName == NULL) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return NULL; + } - if ((*ds->start) == '}') - { - ds->objDepth--; - ds->start ++; - return ds->dec->endObject(ds->prv, newObj); - } + if (ds->lastType != JT_UTF8) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + ds->dec->releaseObject(ds->prv, itemName, ds->dec); + return SetError( + ds, -1, + "Key name of object must be 'string' when decoding 'object'"); + } - ds->lastType = JT_INVALID; - itemName = decode_any(ds); + SkipWhitespace(ds); - if (itemName == NULL) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return NULL; - } + if (*(ds->start++) != ':') { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + ds->dec->releaseObject(ds->prv, itemName, ds->dec); + return SetError(ds, -1, "No ':' found when decoding object value"); + } - if (ds->lastType != JT_UTF8) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - ds->dec->releaseObject(ds->prv, itemName, ds->dec); - return SetError(ds, -1, "Key name of object must be 'string' when decoding 'object'"); - } + SkipWhitespace(ds); - SkipWhitespace(ds); + itemValue = decode_any(ds); - if (*(ds->start++) != ':') - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - ds->dec->releaseObject(ds->prv, itemName, ds->dec); - return SetError(ds, -1, "No ':' found when decoding object value"); - } + if (itemValue == NULL) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + ds->dec->releaseObject(ds->prv, itemName, ds->dec); + return NULL; + } - SkipWhitespace(ds); + if (!ds->dec->objectAddKey(ds->prv, newObj, itemName, itemValue)) { + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + ds->dec->releaseObject(ds->prv, itemName, ds->dec); + ds->dec->releaseObject(ds->prv, itemValue, ds->dec); + return NULL; + } - itemValue = decode_any(ds); + SkipWhitespace(ds); - if (itemValue == NULL) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - ds->dec->releaseObject(ds->prv, itemName, ds->dec); - return NULL; - } + switch (*(ds->start++)) { + case '}': { + ds->objDepth--; + return ds->dec->endObject(ds->prv, newObj); + } + case ',': + break; - if (!ds->dec->objectAddKey (ds->prv, newObj, itemName, itemValue)) - { - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - ds->dec->releaseObject(ds->prv, itemName, ds->dec); - ds->dec->releaseObject(ds->prv, itemValue, ds->dec); - return NULL; - } - - SkipWhitespace(ds); - - switch (*(ds->start++)) - { - case '}': - { - ds->objDepth--; - return ds->dec->endObject(ds->prv, newObj); - } - case ',': - break; - - default: - ds->dec->releaseObject(ds->prv, newObj, ds->dec); - return SetError(ds, -1, "Unexpected character found when decoding object value"); + default: + ds->dec->releaseObject(ds->prv, newObj, ds->dec); + return SetError( + ds, -1, + "Unexpected character found when decoding object value"); + } } - } } -FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds) -{ - for (;;) - { - switch (*ds->start) - { - case '\"': - return decode_string (ds); - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - return decode_numeric (ds); - - case '[': return decode_array (ds); - case '{': return decode_object (ds); - case 't': return decode_true (ds); - case 'f': return decode_false (ds); - case 'n': return decode_null (ds); - - case ' ': - case '\t': - case '\r': - case '\n': - // White space - ds->start ++; - break; - - default: - return SetError(ds, -1, "Expected object or value"); +FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds) { + for (;;) { + switch (*ds->start) { + case '\"': + return decode_string(ds); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return decode_numeric(ds); + + case '[': + return decode_array(ds); + case '{': + return decode_object(ds); + case 't': + return decode_true(ds); + case 'f': + return decode_false(ds); + case 'n': + return decode_null(ds); + + case ' ': + case '\t': + case '\r': + case '\n': + // White space + ds->start++; + break; + + default: + return SetError(ds, -1, "Expected object or value"); + } } - } } -JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer) -{ - /* - FIXME: Base the size of escBuffer of that of cbBuffer so that the unicode escaping doesn't run into the wall each time */ - char *locale; - struct DecoderState ds; - wchar_t escBuffer[(JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t))]; - JSOBJ ret; - - ds.start = (char *) buffer; - ds.end = ds.start + cbBuffer; - - ds.escStart = escBuffer; - ds.escEnd = ds.escStart + (JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t)); - ds.escHeap = 0; - ds.prv = dec->prv; - ds.dec = dec; - ds.dec->errorStr = NULL; - ds.dec->errorOffset = NULL; - ds.objDepth = 0; - - ds.dec = dec; - - locale = setlocale(LC_NUMERIC, NULL); - if (strcmp(locale, "C")) - { - locale = strdup(locale); - if (!locale) - { - return SetError(&ds, -1, "Could not reserve memory block"); +JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, + size_t cbBuffer) { + /* + FIXME: Base the size of escBuffer of that of cbBuffer so that the unicode + escaping doesn't run into the wall each time */ + char *locale; + struct DecoderState ds; + wchar_t escBuffer[(JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t))]; + JSOBJ ret; + + ds.start = (char *)buffer; + ds.end = ds.start + cbBuffer; + + ds.escStart = escBuffer; + ds.escEnd = ds.escStart + (JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t)); + ds.escHeap = 0; + ds.prv = dec->prv; + ds.dec = dec; + ds.dec->errorStr = NULL; + ds.dec->errorOffset = NULL; + ds.objDepth = 0; + + ds.dec = dec; + + locale = setlocale(LC_NUMERIC, NULL); + if (strcmp(locale, "C")) { + locale = strdup(locale); + if (!locale) { + return SetError(&ds, -1, "Could not reserve memory block"); + } + setlocale(LC_NUMERIC, "C"); + ret = decode_any(&ds); + setlocale(LC_NUMERIC, locale); + free(locale); + } else { + ret = decode_any(&ds); + } + + if (ds.escHeap) { + dec->free(ds.escStart); } - setlocale(LC_NUMERIC, "C"); - ret = decode_any (&ds); - setlocale(LC_NUMERIC, locale); - free(locale); - } - else - { - ret = decode_any (&ds); - } - - if (ds.escHeap) - { - dec->free(ds.escStart); - } - - SkipWhitespace(&ds); - - if (ds.start != ds.end && ret) - { - dec->releaseObject(ds.prv, ret, ds.dec); - return SetError(&ds, -1, "Trailing data"); - } - - return ret; + + SkipWhitespace(&ds); + + if (ds.start != ds.end && ret) { + dec->releaseObject(ds.prv, ret, ds.dec); + return SetError(&ds, -1, "Trailing data"); + } + + return ret; } diff --git a/pandas/src/ujson/lib/ultrajsonenc.c b/pandas/src/ujson/lib/ultrajsonenc.c index 2adf3cb707bdb..5a15071938c1a 100644 --- a/pandas/src/ujson/lib/ultrajsonenc.c +++ b/pandas/src/ujson/lib/ultrajsonenc.c @@ -16,8 +16,10 @@ modification, are permitted provided that the following conditions are met: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE +LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT @@ -27,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Portions of code from MODP_ASCII - Ascii transformations (upper/lower, etc) https://github.com/client9/stringencoders -Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved. +Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights +reserved. Numeric decoder derived from from TCL library http://www.opensource.apple.com/source/tcl/tcl-14/tcl/license.terms @@ -35,15 +38,14 @@ Numeric decoder derived from from TCL library * Copyright (c) 1994 Sun Microsystems, Inc. */ -#include "ultrajson.h" -#include #include -#include -#include -#include -#include - #include +#include +#include +#include +#include +#include +#include "ultrajson.h" #ifndef TRUE #define TRUE 1 @@ -67,587 +69,821 @@ or UTF-16 surrogate pairs The extra 2 bytes are for the quotes around the string */ -#define RESERVE_STRING(_len) (2 + ((_len) * 6)) - -static const double g_pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000}; +#define RESERVE_STRING(_len) (2 + ((_len)*6)) + +static const double g_pow10[] = {1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000}; static const char g_hexChars[] = "0123456789abcdef"; static const char g_escapeChars[] = "0123456789\\b\\t\\n\\f\\r\\\"\\\\\\/"; /* -FIXME: While this is fine dandy and working it's a magic value mess which probably only the author understands. +FIXME: While this is fine dandy and working it's a magic value mess which +probably only the author understands. Needs a cleanup and more documentation */ /* Table for pure ascii output escaping all characters above 127 to \uXXXX */ -static const JSUINT8 g_asciiOutputTable[256] = -{ -/* 0x00 */ 0, 30, 30, 30, 30, 30, 30, 30, 10, 12, 14, 30, 16, 18, 30, 30, -/* 0x10 */ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, -/* 0x20 */ 1, 1, 20, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 1, 1, 24, -/* 0x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 1, 29, 1, -/* 0x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22, 1, 1, 1, -/* 0x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0xa0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0xb0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 0xc0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* 0xd0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* 0xe0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -/* 0xf0 */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 -}; - -static void SetError (JSOBJ obj, JSONObjectEncoder *enc, const char *message) -{ - enc->errorMsg = message; - enc->errorObj = obj; +static const JSUINT8 g_asciiOutputTable[256] = { + /* 0x00 */ 0, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 10, + 12, + 14, + 30, + 16, + 18, + 30, + 30, + /* 0x10 */ 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + /* 0x20 */ 1, + 1, + 20, + 1, + 1, + 1, + 29, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 24, + /* 0x30 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 29, + 1, + 29, + 1, + /* 0x40 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x50 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 22, + 1, + 1, + 1, + /* 0x60 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x70 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x80 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0x90 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xa0 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xb0 */ 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + /* 0xc0 */ 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + /* 0xd0 */ 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + /* 0xe0 */ 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + /* 0xf0 */ 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 5, + 5, + 5, + 5, + 6, + 6, + 1, + 1}; + +static void SetError(JSOBJ obj, JSONObjectEncoder *enc, const char *message) { + enc->errorMsg = message; + enc->errorObj = obj; } /* -FIXME: Keep track of how big these get across several encoder calls and try to make an estimate +FIXME: Keep track of how big these get across several encoder calls and try to +make an estimate That way we won't run our head into the wall each call */ -void Buffer_Realloc (JSONObjectEncoder *enc, size_t cbNeeded) -{ - size_t curSize = enc->end - enc->start; - size_t newSize = curSize * 2; - size_t offset = enc->offset - enc->start; - - while (newSize < curSize + cbNeeded) - { - newSize *= 2; - } - - if (enc->heap) - { - enc->start = (char *) enc->realloc (enc->start, newSize); - if (!enc->start) - { - SetError (NULL, enc, "Could not reserve memory block"); - return; +void Buffer_Realloc(JSONObjectEncoder *enc, size_t cbNeeded) { + size_t curSize = enc->end - enc->start; + size_t newSize = curSize * 2; + size_t offset = enc->offset - enc->start; + + while (newSize < curSize + cbNeeded) { + newSize *= 2; } - } - else - { - char *oldStart = enc->start; - enc->heap = 1; - enc->start = (char *) enc->malloc (newSize); - if (!enc->start) - { - SetError (NULL, enc, "Could not reserve memory block"); - return; + + if (enc->heap) { + enc->start = (char *)enc->realloc(enc->start, newSize); + if (!enc->start) { + SetError(NULL, enc, "Could not reserve memory block"); + return; + } + } else { + char *oldStart = enc->start; + enc->heap = 1; + enc->start = (char *)enc->malloc(newSize); + if (!enc->start) { + SetError(NULL, enc, "Could not reserve memory block"); + return; + } + memcpy(enc->start, oldStart, offset); } - memcpy (enc->start, oldStart, offset); - } - enc->offset = enc->start + offset; - enc->end = enc->start + newSize; + enc->offset = enc->start + offset; + enc->end = enc->start + newSize; } -FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_AppendShortHexUnchecked (char *outputOffset, unsigned short value) -{ - *(outputOffset++) = g_hexChars[(value & 0xf000) >> 12]; - *(outputOffset++) = g_hexChars[(value & 0x0f00) >> 8]; - *(outputOffset++) = g_hexChars[(value & 0x00f0) >> 4]; - *(outputOffset++) = g_hexChars[(value & 0x000f) >> 0]; +FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC +Buffer_AppendShortHexUnchecked(char *outputOffset, unsigned short value) { + *(outputOffset++) = g_hexChars[(value & 0xf000) >> 12]; + *(outputOffset++) = g_hexChars[(value & 0x0f00) >> 8]; + *(outputOffset++) = g_hexChars[(value & 0x00f0) >> 4]; + *(outputOffset++) = g_hexChars[(value & 0x000f) >> 0]; } -int Buffer_EscapeStringUnvalidated (JSONObjectEncoder *enc, const char *io, const char *end) -{ - char *of = (char *) enc->offset; - - for (;;) - { - switch (*io) - { - case 0x00: - { - if (io < end) - { - *(of++) = '\\'; - *(of++) = 'u'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = '0'; - break; - } - else - { - enc->offset += (of - enc->offset); - return TRUE; - } - } - case '\"': (*of++) = '\\'; (*of++) = '\"'; break; - case '\\': (*of++) = '\\'; (*of++) = '\\'; break; - case '/': (*of++) = '\\'; (*of++) = '/'; break; - case '\b': (*of++) = '\\'; (*of++) = 'b'; break; - case '\f': (*of++) = '\\'; (*of++) = 'f'; break; - case '\n': (*of++) = '\\'; (*of++) = 'n'; break; - case '\r': (*of++) = '\\'; (*of++) = 'r'; break; - case '\t': (*of++) = '\\'; (*of++) = 't'; break; - - case 0x26: // '/' - case 0x3c: // '<' - case 0x3e: // '>' - { - if (enc->encodeHTMLChars) - { - // Fall through to \u00XX case below. - } - else - { - // Same as default case below. - (*of++) = (*io); - break; +int Buffer_EscapeStringUnvalidated(JSONObjectEncoder *enc, const char *io, + const char *end) { + char *of = (char *)enc->offset; + + for (;;) { + switch (*io) { + case 0x00: { + if (io < end) { + *(of++) = '\\'; + *(of++) = 'u'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = '0'; + break; + } else { + enc->offset += (of - enc->offset); + return TRUE; + } + } + case '\"': + (*of++) = '\\'; + (*of++) = '\"'; + break; + case '\\': + (*of++) = '\\'; + (*of++) = '\\'; + break; + case '/': + (*of++) = '\\'; + (*of++) = '/'; + break; + case '\b': + (*of++) = '\\'; + (*of++) = 'b'; + break; + case '\f': + (*of++) = '\\'; + (*of++) = 'f'; + break; + case '\n': + (*of++) = '\\'; + (*of++) = 'n'; + break; + case '\r': + (*of++) = '\\'; + (*of++) = 'r'; + break; + case '\t': + (*of++) = '\\'; + (*of++) = 't'; + break; + + case 0x26: // '/' + case 0x3c: // '<' + case 0x3e: // '>' + { + if (enc->encodeHTMLChars) { + // Fall through to \u00XX case below. + } else { + // Same as default case below. + (*of++) = (*io); + break; + } + } + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x0b: + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: { + *(of++) = '\\'; + *(of++) = 'u'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = g_hexChars[(unsigned char)(((*io) & 0xf0) >> 4)]; + *(of++) = g_hexChars[(unsigned char)((*io) & 0x0f)]; + break; + } + default: + (*of++) = (*io); + break; } - } - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x0b: - case 0x0e: - case 0x0f: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: - { - *(of++) = '\\'; - *(of++) = 'u'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = g_hexChars[ (unsigned char) (((*io) & 0xf0) >> 4)]; - *(of++) = g_hexChars[ (unsigned char) ((*io) & 0x0f)]; - break; - } - default: (*of++) = (*io); break; - } - io++; - } + io++; + } } -int Buffer_EscapeStringValidated (JSOBJ obj, JSONObjectEncoder *enc, const char *io, const char *end) -{ - JSUTF32 ucs; - char *of = (char *) enc->offset; - - for (;;) - { - JSUINT8 utflen = g_asciiOutputTable[(unsigned char) *io]; - - switch (utflen) - { - case 0: - { - if (io < end) - { - *(of++) = '\\'; - *(of++) = 'u'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = '0'; - io ++; - continue; - } - else - { - enc->offset += (of - enc->offset); - return TRUE; - } - } - - case 1: - { - *(of++)= (*io++); - continue; - } - - case 2: - { - JSUTF32 in; - JSUTF16 in16; - - if (end - io < 1) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); - return FALSE; - } - - memcpy(&in16, io, sizeof(JSUTF16)); - in = (JSUTF32) in16; +int Buffer_EscapeStringValidated(JSOBJ obj, JSONObjectEncoder *enc, + const char *io, const char *end) { + JSUTF32 ucs; + char *of = (char *)enc->offset; + + for (;;) { + JSUINT8 utflen = g_asciiOutputTable[(unsigned char)*io]; + + switch (utflen) { + case 0: { + if (io < end) { + *(of++) = '\\'; + *(of++) = 'u'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = '0'; + io++; + continue; + } else { + enc->offset += (of - enc->offset); + return TRUE; + } + } + + case 1: { + *(of++) = (*io++); + continue; + } + + case 2: { + JSUTF32 in; + JSUTF16 in16; + + if (end - io < 1) { + enc->offset += (of - enc->offset); + SetError( + obj, enc, + "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } + + memcpy(&in16, io, sizeof(JSUTF16)); + in = (JSUTF32)in16; #ifdef __LITTLE_ENDIAN__ - ucs = ((in & 0x1f) << 6) | ((in >> 8) & 0x3f); + ucs = ((in & 0x1f) << 6) | ((in >> 8) & 0x3f); #else - ucs = ((in & 0x1f00) >> 2) | (in & 0x3f); + ucs = ((in & 0x1f00) >> 2) | (in & 0x3f); #endif - if (ucs < 0x80) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Overlong 2 byte UTF-8 sequence detected when encoding string"); - return FALSE; - } - - io += 2; - break; - } - - case 3: - { - JSUTF32 in; - JSUTF16 in16; - JSUINT8 in8; - - if (end - io < 2) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); - return FALSE; - } - - memcpy(&in16, io, sizeof(JSUTF16)); - memcpy(&in8, io + 2, sizeof(JSUINT8)); + if (ucs < 0x80) { + enc->offset += (of - enc->offset); + SetError(obj, enc, + "Overlong 2 byte UTF-8 sequence detected when " + "encoding string"); + return FALSE; + } + + io += 2; + break; + } + + case 3: { + JSUTF32 in; + JSUTF16 in16; + JSUINT8 in8; + + if (end - io < 2) { + enc->offset += (of - enc->offset); + SetError( + obj, enc, + "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } + + memcpy(&in16, io, sizeof(JSUTF16)); + memcpy(&in8, io + 2, sizeof(JSUINT8)); #ifdef __LITTLE_ENDIAN__ - in = (JSUTF32) in16; - in |= in8 << 16; - ucs = ((in & 0x0f) << 12) | ((in & 0x3f00) >> 2) | ((in & 0x3f0000) >> 16); + in = (JSUTF32)in16; + in |= in8 << 16; + ucs = ((in & 0x0f) << 12) | ((in & 0x3f00) >> 2) | + ((in & 0x3f0000) >> 16); #else - in = in16 << 8; - in |= in8; - ucs = ((in & 0x0f0000) >> 4) | ((in & 0x3f00) >> 2) | (in & 0x3f); + in = in16 << 8; + in |= in8; + ucs = + ((in & 0x0f0000) >> 4) | ((in & 0x3f00) >> 2) | (in & 0x3f); #endif - if (ucs < 0x800) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Overlong 3 byte UTF-8 sequence detected when encoding string"); - return FALSE; - } - - io += 3; - break; - } - case 4: - { - JSUTF32 in; - - if (end - io < 3) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string"); - return FALSE; - } - - memcpy(&in, io, sizeof(JSUTF32)); + if (ucs < 0x800) { + enc->offset += (of - enc->offset); + SetError(obj, enc, + "Overlong 3 byte UTF-8 sequence detected when " + "encoding string"); + return FALSE; + } + + io += 3; + break; + } + case 4: { + JSUTF32 in; + + if (end - io < 3) { + enc->offset += (of - enc->offset); + SetError( + obj, enc, + "Unterminated UTF-8 sequence when encoding string"); + return FALSE; + } + + memcpy(&in, io, sizeof(JSUTF32)); #ifdef __LITTLE_ENDIAN__ - ucs = ((in & 0x07) << 18) | ((in & 0x3f00) << 4) | ((in & 0x3f0000) >> 10) | ((in & 0x3f000000) >> 24); + ucs = ((in & 0x07) << 18) | ((in & 0x3f00) << 4) | + ((in & 0x3f0000) >> 10) | ((in & 0x3f000000) >> 24); #else - ucs = ((in & 0x07000000) >> 6) | ((in & 0x3f0000) >> 4) | ((in & 0x3f00) >> 2) | (in & 0x3f); + ucs = ((in & 0x07000000) >> 6) | ((in & 0x3f0000) >> 4) | + ((in & 0x3f00) >> 2) | (in & 0x3f); #endif - if (ucs < 0x10000) - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Overlong 4 byte UTF-8 sequence detected when encoding string"); - return FALSE; + if (ucs < 0x10000) { + enc->offset += (of - enc->offset); + SetError(obj, enc, + "Overlong 4 byte UTF-8 sequence detected when " + "encoding string"); + return FALSE; + } + + io += 4; + break; + } + + case 5: + case 6: { + enc->offset += (of - enc->offset); + SetError( + obj, enc, + "Unsupported UTF-8 sequence length when encoding string"); + return FALSE; + } + + case 29: { + if (enc->encodeHTMLChars) { + // Fall through to \u00XX case 30 below. + } else { + // Same as case 1 above. + *(of++) = (*io++); + continue; + } + } + + case 30: { + // \uXXXX encode + *(of++) = '\\'; + *(of++) = 'u'; + *(of++) = '0'; + *(of++) = '0'; + *(of++) = g_hexChars[(unsigned char)(((*io) & 0xf0) >> 4)]; + *(of++) = g_hexChars[(unsigned char)((*io) & 0x0f)]; + io++; + continue; + } + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: { + *(of++) = *((char *)(g_escapeChars + utflen + 0)); + *(of++) = *((char *)(g_escapeChars + utflen + 1)); + io++; + continue; + } + // This can never happen, it's here to make L4 VC++ happy + default: { + ucs = 0; + break; + } } - io += 4; - break; - } - - - case 5: - case 6: - { - enc->offset += (of - enc->offset); - SetError (obj, enc, "Unsupported UTF-8 sequence length when encoding string"); - return FALSE; - } - - case 29: - { - if (enc->encodeHTMLChars) - { - // Fall through to \u00XX case 30 below. - } - else - { - // Same as case 1 above. - *(of++) = (*io++); - continue; + /* + If the character is a UTF8 sequence of length > 1 we end up here */ + if (ucs >= 0x10000) { + ucs -= 0x10000; + *(of++) = '\\'; + *(of++) = 'u'; + Buffer_AppendShortHexUnchecked( + of, (unsigned short)(ucs >> 10) + 0xd800); + of += 4; + + *(of++) = '\\'; + *(of++) = 'u'; + Buffer_AppendShortHexUnchecked( + of, (unsigned short)(ucs & 0x3ff) + 0xdc00); + of += 4; + } else { + *(of++) = '\\'; + *(of++) = 'u'; + Buffer_AppendShortHexUnchecked(of, (unsigned short)ucs); + of += 4; } - } - - case 30: - { - // \uXXXX encode - *(of++) = '\\'; - *(of++) = 'u'; - *(of++) = '0'; - *(of++) = '0'; - *(of++) = g_hexChars[ (unsigned char) (((*io) & 0xf0) >> 4)]; - *(of++) = g_hexChars[ (unsigned char) ((*io) & 0x0f)]; - io ++; - continue; - } - case 10: - case 12: - case 14: - case 16: - case 18: - case 20: - case 22: - case 24: - { - *(of++) = *( (char *) (g_escapeChars + utflen + 0)); - *(of++) = *( (char *) (g_escapeChars + utflen + 1)); - io ++; - continue; - } - // This can never happen, it's here to make L4 VC++ happy - default: - { - ucs = 0; - break; - } } +} - /* - If the character is a UTF8 sequence of length > 1 we end up here */ - if (ucs >= 0x10000) - { - ucs -= 0x10000; - *(of++) = '\\'; - *(of++) = 'u'; - Buffer_AppendShortHexUnchecked(of, (unsigned short) (ucs >> 10) + 0xd800); - of += 4; - - *(of++) = '\\'; - *(of++) = 'u'; - Buffer_AppendShortHexUnchecked(of, (unsigned short) (ucs & 0x3ff) + 0xdc00); - of += 4; - } - else - { - *(of++) = '\\'; - *(of++) = 'u'; - Buffer_AppendShortHexUnchecked(of, (unsigned short) ucs); - of += 4; +#define Buffer_Reserve(__enc, __len) \ + if ((size_t)((__enc)->end - (__enc)->offset) < (size_t)(__len)) { \ + Buffer_Realloc((__enc), (__len)); \ } - } -} -#define Buffer_Reserve(__enc, __len) \ - if ( (size_t) ((__enc)->end - (__enc)->offset) < (size_t) (__len)) \ - { \ - Buffer_Realloc((__enc), (__len));\ - } \ +#define Buffer_AppendCharUnchecked(__enc, __chr) *((__enc)->offset++) = __chr; +FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC strreverse(char *begin, + char *end) { + char aux; + while (end > begin) aux = *end, *end-- = *begin, *begin++ = aux; +} -#define Buffer_AppendCharUnchecked(__enc, __chr) \ - *((__enc)->offset++) = __chr; \ +void Buffer_AppendIntUnchecked(JSONObjectEncoder *enc, JSINT32 value) { + char *wstr; + JSUINT32 uvalue = (value < 0) ? -value : value; + wstr = enc->offset; -FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC strreverse(char* begin, char* end) -{ - char aux; - while (end > begin) - aux = *end, *end-- = *begin, *begin++ = aux; + // Conversion. Number is reversed. + do { + *wstr++ = (char)(48 + (uvalue % 10)); + } while (uvalue /= 10); + if (value < 0) *wstr++ = '-'; + + // Reverse string + strreverse(enc->offset, wstr - 1); + enc->offset += (wstr - (enc->offset)); } -void Buffer_AppendIntUnchecked(JSONObjectEncoder *enc, JSINT32 value) -{ - char* wstr; - JSUINT32 uvalue = (value < 0) ? -value : value; +void Buffer_AppendLongUnchecked(JSONObjectEncoder *enc, JSINT64 value) { + char *wstr; + JSUINT64 uvalue = (value < 0) ? -value : value; - wstr = enc->offset; - // Conversion. Number is reversed. + wstr = enc->offset; + // Conversion. Number is reversed. - do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10); - if (value < 0) *wstr++ = '-'; + do { + *wstr++ = (char)(48 + (uvalue % 10ULL)); + } while (uvalue /= 10ULL); + if (value < 0) *wstr++ = '-'; - // Reverse string - strreverse(enc->offset,wstr - 1); - enc->offset += (wstr - (enc->offset)); + // Reverse string + strreverse(enc->offset, wstr - 1); + enc->offset += (wstr - (enc->offset)); } -void Buffer_AppendLongUnchecked(JSONObjectEncoder *enc, JSINT64 value) -{ - char* wstr; - JSUINT64 uvalue = (value < 0) ? -value : value; - - wstr = enc->offset; - // Conversion. Number is reversed. +int Buffer_AppendDoubleUnchecked(JSOBJ obj, JSONObjectEncoder *enc, + double value) { + /* if input is beyond the thresholds, revert to exponential */ + const double thres_max = (double)1e16 - 1; + const double thres_min = (double)1e-15; + char precision_str[20]; + int count; + double diff = 0.0; + char *str = enc->offset; + char *wstr = str; + unsigned long long whole; + double tmp; + unsigned long long frac; + int neg; + double pow10; + + if (value == HUGE_VAL || value == -HUGE_VAL) { + SetError(obj, enc, "Invalid Inf value when encoding double"); + return FALSE; + } - do *wstr++ = (char)(48 + (uvalue % 10ULL)); while(uvalue /= 10ULL); - if (value < 0) *wstr++ = '-'; + if (!(value == value)) { + SetError(obj, enc, "Invalid Nan value when encoding double"); + return FALSE; + } - // Reverse string - strreverse(enc->offset,wstr - 1); - enc->offset += (wstr - (enc->offset)); -} + /* we'll work in positive values and deal with the + negative sign issue later */ + neg = 0; + if (value < 0) { + neg = 1; + value = -value; + } -int Buffer_AppendDoubleUnchecked(JSOBJ obj, JSONObjectEncoder *enc, double value) -{ - /* if input is beyond the thresholds, revert to exponential */ - const double thres_max = (double) 1e16 - 1; - const double thres_min = (double) 1e-15; - char precision_str[20]; - int count; - double diff = 0.0; - char* str = enc->offset; - char* wstr = str; - unsigned long long whole; - double tmp; - unsigned long long frac; - int neg; - double pow10; - - if (value == HUGE_VAL || value == -HUGE_VAL) - { - SetError (obj, enc, "Invalid Inf value when encoding double"); - return FALSE; - } - - if (!(value == value)) - { - SetError (obj, enc, "Invalid Nan value when encoding double"); - return FALSE; - } - - /* we'll work in positive values and deal with the - negative sign issue later */ - neg = 0; - if (value < 0) - { - neg = 1; - value = -value; - } - - /* - for very large or small numbers switch back to native sprintf for - exponentials. anyone want to write code to replace this? */ - if (value > thres_max || (value != 0.0 && fabs(value) < thres_min)) - { - precision_str[0] = '%'; - precision_str[1] = '.'; + /* + for very large or small numbers switch back to native sprintf for + exponentials. anyone want to write code to replace this? */ + if (value > thres_max || (value != 0.0 && fabs(value) < thres_min)) { + precision_str[0] = '%'; + precision_str[1] = '.'; #if defined(_WIN32) && defined(_MSC_VER) - sprintf_s(precision_str+2, sizeof(precision_str)-2, "%ug", enc->doublePrecision); - enc->offset += sprintf_s(str, enc->end - enc->offset, precision_str, neg ? -value : value); + sprintf_s(precision_str + 2, sizeof(precision_str) - 2, "%ug", + enc->doublePrecision); + enc->offset += sprintf_s(str, enc->end - enc->offset, precision_str, + neg ? -value : value); #else - snprintf(precision_str+2, sizeof(precision_str)-2, "%ug", enc->doublePrecision); - enc->offset += snprintf(str, enc->end - enc->offset, precision_str, neg ? -value : value); + snprintf(precision_str + 2, sizeof(precision_str) - 2, "%ug", + enc->doublePrecision); + enc->offset += snprintf(str, enc->end - enc->offset, precision_str, + neg ? -value : value); #endif - return TRUE; - } - - pow10 = g_pow10[enc->doublePrecision]; - - whole = (unsigned long long) value; - tmp = (value - whole) * pow10; - frac = (unsigned long long)(tmp); - diff = tmp - frac; - - if (diff > 0.5) - { - ++frac; - /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */ - if (frac >= pow10) - { - frac = 0; - ++whole; - } - } - else - if (diff == 0.5 && ((frac == 0) || (frac & 1))) - { - /* if halfway, round up if odd, OR - if last digit is 0. That last part is strange */ - ++frac; - } - - if (enc->doublePrecision == 0) - { - diff = value - whole; - - if (diff > 0.5) - { - /* greater than 0.5, round up, e.g. 1.6 -> 2 */ - ++whole; + return TRUE; } - else - if (diff == 0.5 && (whole & 1)) - { - /* exactly 0.5 and ODD, then round up */ - /* 1.5 -> 2, but 2.5 -> 2 */ - ++whole; + + pow10 = g_pow10[enc->doublePrecision]; + + whole = (unsigned long long)value; + tmp = (value - whole) * pow10; + frac = (unsigned long long)(tmp); + diff = tmp - frac; + + if (diff > 0.5) { + ++frac; + /* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */ + if (frac >= pow10) { + frac = 0; + ++whole; + } + } else if (diff == 0.5 && ((frac == 0) || (frac & 1))) { + /* if halfway, round up if odd, OR + if last digit is 0. That last part is strange */ + ++frac; } - //vvvvvvvvvvvvvvvvvvv Diff from modp_dto2 - } - else - if (frac) - { - count = enc->doublePrecision; - // now do fractional part, as an unsigned number - // we know it is not 0 but we can have leading zeros, these - // should be removed - while (!(frac % 10)) - { - --count; - frac /= 10; - } - //^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2 - - // now do fractional part, as an unsigned number - do - { - --count; - *wstr++ = (char)(48 + (frac % 10)); - } while (frac /= 10); - // add extra 0s - while (count-- > 0) - { + if (enc->doublePrecision == 0) { + diff = value - whole; + + if (diff > 0.5) { + /* greater than 0.5, round up, e.g. 1.6 -> 2 */ + ++whole; + } else if (diff == 0.5 && (whole & 1)) { + /* exactly 0.5 and ODD, then round up */ + /* 1.5 -> 2, but 2.5 -> 2 */ + ++whole; + } + + // vvvvvvvvvvvvvvvvvvv Diff from modp_dto2 + } else if (frac) { + count = enc->doublePrecision; + // now do fractional part, as an unsigned number + // we know it is not 0 but we can have leading zeros, these + // should be removed + while (!(frac % 10)) { + --count; + frac /= 10; + } + //^^^^^^^^^^^^^^^^^^^ Diff from modp_dto2 + + // now do fractional part, as an unsigned number + do { + --count; + *wstr++ = (char)(48 + (frac % 10)); + } while (frac /= 10); + // add extra 0s + while (count-- > 0) { + *wstr++ = '0'; + } + // add decimal + *wstr++ = '.'; + } else { *wstr++ = '0'; - } - // add decimal - *wstr++ = '.'; - } - else - { - *wstr++ = '0'; - *wstr++ = '.'; + *wstr++ = '.'; } - // do whole part - // Take care of sign - // Conversion. Number is reversed. - do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10); + // Do whole part. Take care of sign + // conversion. Number is reversed. + do { + *wstr++ = (char)(48 + (whole % 10)); + } while (whole /= 10); - if (neg) - { - *wstr++ = '-'; + if (neg) { + *wstr++ = '-'; } - strreverse(str, wstr-1); + strreverse(str, wstr - 1); enc->offset += (wstr - (enc->offset)); return TRUE; @@ -661,287 +897,248 @@ Handle integration functions returning NULL here */ FIXME: Perhaps implement recursion detection */ -void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName) -{ - const char *value; - char *objName; - int count; - JSOBJ iterObj; - size_t szlen; - JSONTypeContext tc; - tc.encoder = enc; - - if (enc->level > enc->recursionMax) - { - SetError (obj, enc, "Maximum recursion level reached"); - return; - } - - /* - This reservation must hold - - length of _name as encoded worst case + - maxLength of double to string OR maxLength of JSLONG to string - */ - - Buffer_Reserve(enc, 256 + RESERVE_STRING(cbName)); - if (enc->errorMsg) - { - return; - } - - if (name) - { - Buffer_AppendCharUnchecked(enc, '\"'); - - if (enc->forceASCII) - { - if (!Buffer_EscapeStringValidated(obj, enc, name, name + cbName)) - { +void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, + size_t cbName) { + const char *value; + char *objName; + int count; + JSOBJ iterObj; + size_t szlen; + JSONTypeContext tc; + tc.encoder = enc; + + if (enc->level > enc->recursionMax) { + SetError(obj, enc, "Maximum recursion level reached"); return; - } } - else - { - if (!Buffer_EscapeStringUnvalidated(enc, name, name + cbName)) - { + + /* + This reservation must hold + + length of _name as encoded worst case + + maxLength of double to string OR maxLength of JSLONG to string + */ + + Buffer_Reserve(enc, 256 + RESERVE_STRING(cbName)); + if (enc->errorMsg) { return; - } } - Buffer_AppendCharUnchecked(enc, '\"'); + if (name) { + Buffer_AppendCharUnchecked(enc, '\"'); + + if (enc->forceASCII) { + if (!Buffer_EscapeStringValidated(obj, enc, name, name + cbName)) { + return; + } + } else { + if (!Buffer_EscapeStringUnvalidated(enc, name, name + cbName)) { + return; + } + } + + Buffer_AppendCharUnchecked(enc, '\"'); - Buffer_AppendCharUnchecked (enc, ':'); + Buffer_AppendCharUnchecked(enc, ':'); #ifndef JSON_NO_EXTRA_WHITESPACE - Buffer_AppendCharUnchecked (enc, ' '); + Buffer_AppendCharUnchecked(enc, ' '); #endif } enc->beginTypeContext(obj, &tc); - switch (tc.type) - { - case JT_INVALID: - { - return; - } + switch (tc.type) { + case JT_INVALID: { + return; + } - case JT_ARRAY: - { - count = 0; - enc->iterBegin(obj, &tc); + case JT_ARRAY: { + count = 0; + enc->iterBegin(obj, &tc); - Buffer_AppendCharUnchecked (enc, '['); + Buffer_AppendCharUnchecked(enc, '['); - while (enc->iterNext(obj, &tc)) - { - if (count > 0) - { - Buffer_AppendCharUnchecked (enc, ','); + while (enc->iterNext(obj, &tc)) { + if (count > 0) { + Buffer_AppendCharUnchecked(enc, ','); #ifndef JSON_NO_EXTRA_WHITESPACE - Buffer_AppendCharUnchecked (buffer, ' '); + Buffer_AppendCharUnchecked(buffer, ' '); #endif - } + } - iterObj = enc->iterGetValue(obj, &tc); + iterObj = enc->iterGetValue(obj, &tc); - enc->level ++; - encode (iterObj, enc, NULL, 0); - count ++; - } + enc->level++; + encode(iterObj, enc, NULL, 0); + count++; + } - enc->iterEnd(obj, &tc); - Buffer_AppendCharUnchecked (enc, ']'); - break; - } + enc->iterEnd(obj, &tc); + Buffer_AppendCharUnchecked(enc, ']'); + break; + } - case JT_OBJECT: - { - count = 0; - enc->iterBegin(obj, &tc); + case JT_OBJECT: { + count = 0; + enc->iterBegin(obj, &tc); - Buffer_AppendCharUnchecked (enc, '{'); + Buffer_AppendCharUnchecked(enc, '{'); - while (enc->iterNext(obj, &tc)) - { - if (count > 0) - { - Buffer_AppendCharUnchecked (enc, ','); + while (enc->iterNext(obj, &tc)) { + if (count > 0) { + Buffer_AppendCharUnchecked(enc, ','); #ifndef JSON_NO_EXTRA_WHITESPACE - Buffer_AppendCharUnchecked (enc, ' '); + Buffer_AppendCharUnchecked(enc, ' '); #endif - } + } - iterObj = enc->iterGetValue(obj, &tc); - objName = enc->iterGetName(obj, &tc, &szlen); + iterObj = enc->iterGetValue(obj, &tc); + objName = enc->iterGetName(obj, &tc, &szlen); - enc->level ++; - encode (iterObj, enc, objName, szlen); - count ++; - } + enc->level++; + encode(iterObj, enc, objName, szlen); + count++; + } - enc->iterEnd(obj, &tc); - Buffer_AppendCharUnchecked (enc, '}'); - break; - } - - case JT_LONG: - { - Buffer_AppendLongUnchecked (enc, enc->getLongValue(obj, &tc)); - break; - } - - case JT_INT: - { - Buffer_AppendIntUnchecked (enc, enc->getIntValue(obj, &tc)); - break; - } - - case JT_TRUE: - { - Buffer_AppendCharUnchecked (enc, 't'); - Buffer_AppendCharUnchecked (enc, 'r'); - Buffer_AppendCharUnchecked (enc, 'u'); - Buffer_AppendCharUnchecked (enc, 'e'); - break; - } - - case JT_FALSE: - { - Buffer_AppendCharUnchecked (enc, 'f'); - Buffer_AppendCharUnchecked (enc, 'a'); - Buffer_AppendCharUnchecked (enc, 'l'); - Buffer_AppendCharUnchecked (enc, 's'); - Buffer_AppendCharUnchecked (enc, 'e'); - break; - } - - - case JT_NULL: - { - Buffer_AppendCharUnchecked (enc, 'n'); - Buffer_AppendCharUnchecked (enc, 'u'); - Buffer_AppendCharUnchecked (enc, 'l'); - Buffer_AppendCharUnchecked (enc, 'l'); - break; - } - - case JT_DOUBLE: - { - if (!Buffer_AppendDoubleUnchecked (obj, enc, enc->getDoubleValue(obj, &tc))) - { - enc->endTypeContext(obj, &tc); - enc->level --; - return; - } - break; - } - - case JT_UTF8: - { - value = enc->getStringValue(obj, &tc, &szlen); - Buffer_Reserve(enc, RESERVE_STRING(szlen)); - if (enc->errorMsg) - { - enc->endTypeContext(obj, &tc); - return; - } - Buffer_AppendCharUnchecked (enc, '\"'); - - if (enc->forceASCII) - { - if (!Buffer_EscapeStringValidated(obj, enc, value, value + szlen)) - { - enc->endTypeContext(obj, &tc); - enc->level --; - return; + enc->iterEnd(obj, &tc); + Buffer_AppendCharUnchecked(enc, '}'); + break; + } + + case JT_LONG: { + Buffer_AppendLongUnchecked(enc, enc->getLongValue(obj, &tc)); + break; + } + + case JT_INT: { + Buffer_AppendIntUnchecked(enc, enc->getIntValue(obj, &tc)); + break; + } + + case JT_TRUE: { + Buffer_AppendCharUnchecked(enc, 't'); + Buffer_AppendCharUnchecked(enc, 'r'); + Buffer_AppendCharUnchecked(enc, 'u'); + Buffer_AppendCharUnchecked(enc, 'e'); + break; + } + + case JT_FALSE: { + Buffer_AppendCharUnchecked(enc, 'f'); + Buffer_AppendCharUnchecked(enc, 'a'); + Buffer_AppendCharUnchecked(enc, 'l'); + Buffer_AppendCharUnchecked(enc, 's'); + Buffer_AppendCharUnchecked(enc, 'e'); + break; + } + + case JT_NULL: { + Buffer_AppendCharUnchecked(enc, 'n'); + Buffer_AppendCharUnchecked(enc, 'u'); + Buffer_AppendCharUnchecked(enc, 'l'); + Buffer_AppendCharUnchecked(enc, 'l'); + break; } - } - else - { - if (!Buffer_EscapeStringUnvalidated(enc, value, value + szlen)) - { - enc->endTypeContext(obj, &tc); - enc->level --; - return; + + case JT_DOUBLE: { + if (!Buffer_AppendDoubleUnchecked(obj, enc, + enc->getDoubleValue(obj, &tc))) { + enc->endTypeContext(obj, &tc); + enc->level--; + return; + } + break; } - } - Buffer_AppendCharUnchecked (enc, '\"'); - break; + case JT_UTF8: { + value = enc->getStringValue(obj, &tc, &szlen); + Buffer_Reserve(enc, RESERVE_STRING(szlen)); + if (enc->errorMsg) { + enc->endTypeContext(obj, &tc); + return; + } + Buffer_AppendCharUnchecked(enc, '\"'); + + if (enc->forceASCII) { + if (!Buffer_EscapeStringValidated(obj, enc, value, + value + szlen)) { + enc->endTypeContext(obj, &tc); + enc->level--; + return; + } + } else { + if (!Buffer_EscapeStringUnvalidated(enc, value, + value + szlen)) { + enc->endTypeContext(obj, &tc); + enc->level--; + return; + } + } + + Buffer_AppendCharUnchecked(enc, '\"'); + break; + } } - } - enc->endTypeContext(obj, &tc); - enc->level --; + enc->endTypeContext(obj, &tc); + enc->level--; } -char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *_buffer, size_t _cbBuffer) -{ - char *locale; - enc->malloc = enc->malloc ? enc->malloc : malloc; - enc->free = enc->free ? enc->free : free; - enc->realloc = enc->realloc ? enc->realloc : realloc; - enc->errorMsg = NULL; - enc->errorObj = NULL; - enc->level = 0; - - if (enc->recursionMax < 1) - { - enc->recursionMax = JSON_MAX_RECURSION_DEPTH; - } - - if (enc->doublePrecision < 0 || - enc->doublePrecision > JSON_DOUBLE_MAX_DECIMALS) - { - enc->doublePrecision = JSON_DOUBLE_MAX_DECIMALS; - } - - if (_buffer == NULL) - { - _cbBuffer = 32768; - enc->start = (char *) enc->malloc (_cbBuffer); - if (!enc->start) - { - SetError(obj, enc, "Could not reserve memory block"); - return NULL; +char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *_buffer, + size_t _cbBuffer) { + char *locale; + enc->malloc = enc->malloc ? enc->malloc : malloc; + enc->free = enc->free ? enc->free : free; + enc->realloc = enc->realloc ? enc->realloc : realloc; + enc->errorMsg = NULL; + enc->errorObj = NULL; + enc->level = 0; + + if (enc->recursionMax < 1) { + enc->recursionMax = JSON_MAX_RECURSION_DEPTH; } - enc->heap = 1; - } - else - { - enc->start = _buffer; - enc->heap = 0; - } - - enc->end = enc->start + _cbBuffer; - enc->offset = enc->start; - - locale = setlocale(LC_NUMERIC, NULL); - if (strcmp(locale, "C")) - { - locale = strdup(locale); - if (!locale) - { - SetError(NULL, enc, "Could not reserve memory block"); - return NULL; + + if (enc->doublePrecision < 0 || + enc->doublePrecision > JSON_DOUBLE_MAX_DECIMALS) { + enc->doublePrecision = JSON_DOUBLE_MAX_DECIMALS; } - setlocale(LC_NUMERIC, "C"); - encode (obj, enc, NULL, 0); - setlocale(LC_NUMERIC, locale); - free(locale); - } - else - { - encode (obj, enc, NULL, 0); - } - - Buffer_Reserve(enc, 1); - if (enc->errorMsg) - { - return NULL; - } - Buffer_AppendCharUnchecked(enc, '\0'); - - return enc->start; + + if (_buffer == NULL) { + _cbBuffer = 32768; + enc->start = (char *)enc->malloc(_cbBuffer); + if (!enc->start) { + SetError(obj, enc, "Could not reserve memory block"); + return NULL; + } + enc->heap = 1; + } else { + enc->start = _buffer; + enc->heap = 0; + } + + enc->end = enc->start + _cbBuffer; + enc->offset = enc->start; + + locale = setlocale(LC_NUMERIC, NULL); + if (strcmp(locale, "C")) { + locale = strdup(locale); + if (!locale) { + SetError(NULL, enc, "Could not reserve memory block"); + return NULL; + } + setlocale(LC_NUMERIC, "C"); + encode(obj, enc, NULL, 0); + setlocale(LC_NUMERIC, locale); + free(locale); + } else { + encode(obj, enc, NULL, 0); + } + + Buffer_Reserve(enc, 1); + if (enc->errorMsg) { + return NULL; + } + Buffer_AppendCharUnchecked(enc, '\0'); + + return enc->start; } diff --git a/pandas/src/ujson/python/JSONtoObj.c b/pandas/src/ujson/python/JSONtoObj.c index e4d02db4cb60a..b0132532c16af 100644 --- a/pandas/src/ujson/python/JSONtoObj.c +++ b/pandas/src/ujson/python/JSONtoObj.c @@ -35,38 +35,37 @@ Numeric decoder derived from from TCL library * Copyright (c) 1994 Sun Microsystems, Inc. */ +// "py_defines.h" needs to be included first to +// avoid compilation errors, but it does violate +// styleguide checks with regards to include order. #include "py_defines.h" #define PY_ARRAY_UNIQUE_SYMBOL UJSON_NUMPY #define NO_IMPORT_ARRAY -#include -#include +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) - -//#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__) #define PRINTMARK() -typedef struct __PyObjectDecoder -{ - JSONObjectDecoder dec; +typedef struct __PyObjectDecoder { + JSONObjectDecoder dec; - void* npyarr; // Numpy context buffer - void* npyarr_addr; // Ref to npyarr ptr to track DECREF calls - npy_intp curdim; // Current array dimension + void *npyarr; // Numpy context buffer + void *npyarr_addr; // Ref to npyarr ptr to track DECREF calls + npy_intp curdim; // Current array dimension - PyArray_Descr* dtype; + PyArray_Descr *dtype; } PyObjectDecoder; -typedef struct __NpyArrContext -{ - PyObject* ret; - PyObject* labels[2]; - PyArray_Dims shape; +typedef struct __NpyArrContext { + PyObject *ret; + PyObject *labels[2]; + PyArray_Dims shape; - PyObjectDecoder* dec; + PyObjectDecoder *dec; - npy_intp i; - npy_intp elsize; - npy_intp elcount; + npy_intp i; + npy_intp elsize; + npy_intp elcount; } NpyArrContext; // Numpy handling based on numpy internal code, specifically the function @@ -76,661 +75,564 @@ typedef struct __NpyArrContext // to ensure the compiler catches any errors // standard numpy array handling -JSOBJ Object_npyNewArray(void *prv, void* decoder); +JSOBJ Object_npyNewArray(void *prv, void *decoder); JSOBJ Object_npyEndArray(void *prv, JSOBJ obj); int Object_npyArrayAddItem(void *prv, JSOBJ obj, JSOBJ value); // for more complex dtypes (object and string) fill a standard Python list // and convert to a numpy array when done. -JSOBJ Object_npyNewArrayList(void *prv, void* decoder); +JSOBJ Object_npyNewArrayList(void *prv, void *decoder); JSOBJ Object_npyEndArrayList(void *prv, JSOBJ obj); int Object_npyArrayListAddItem(void *prv, JSOBJ obj, JSOBJ value); // labelled support, encode keys and values of JS object into separate numpy // arrays -JSOBJ Object_npyNewObject(void *prv, void* decoder); +JSOBJ Object_npyNewObject(void *prv, void *decoder); JSOBJ Object_npyEndObject(void *prv, JSOBJ obj); int Object_npyObjectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value); // free the numpy context buffer -void Npy_releaseContext(NpyArrContext* npyarr) -{ - PRINTMARK(); - if (npyarr) - { - if (npyarr->shape.ptr) - { - PyObject_Free(npyarr->shape.ptr); - } - if (npyarr->dec) - { - npyarr->dec->npyarr = NULL; - npyarr->dec->curdim = 0; - } - Py_XDECREF(npyarr->labels[0]); - Py_XDECREF(npyarr->labels[1]); - Py_XDECREF(npyarr->ret); - PyObject_Free(npyarr); - } +void Npy_releaseContext(NpyArrContext *npyarr) { + PRINTMARK(); + if (npyarr) { + if (npyarr->shape.ptr) { + PyObject_Free(npyarr->shape.ptr); + } + if (npyarr->dec) { + npyarr->dec->npyarr = NULL; + npyarr->dec->curdim = 0; + } + Py_XDECREF(npyarr->labels[0]); + Py_XDECREF(npyarr->labels[1]); + Py_XDECREF(npyarr->ret); + PyObject_Free(npyarr); + } } -JSOBJ Object_npyNewArray(void *prv, void* _decoder) -{ - NpyArrContext* npyarr; - PyObjectDecoder* decoder = (PyObjectDecoder*) _decoder; - PRINTMARK(); - if (decoder->curdim <= 0) - { - // start of array - initialise the context buffer - npyarr = decoder->npyarr = PyObject_Malloc(sizeof(NpyArrContext)); - decoder->npyarr_addr = npyarr; - - if (!npyarr) - { - PyErr_NoMemory(); - return NULL; - } - - npyarr->dec = decoder; - npyarr->labels[0] = npyarr->labels[1] = NULL; - - npyarr->shape.ptr = PyObject_Malloc(sizeof(npy_intp)*NPY_MAXDIMS); - npyarr->shape.len = 1; - npyarr->ret = NULL; - - npyarr->elsize = 0; - npyarr->elcount = 4; - npyarr->i = 0; - } - else - { - // starting a new dimension continue the current array (and reshape after) - npyarr = (NpyArrContext*) decoder->npyarr; - if (decoder->curdim >= npyarr->shape.len) - { - npyarr->shape.len++; - } - } - - npyarr->shape.ptr[decoder->curdim] = 0; - decoder->curdim++; - return npyarr; -} +JSOBJ Object_npyNewArray(void *prv, void *_decoder) { + NpyArrContext *npyarr; + PyObjectDecoder *decoder = (PyObjectDecoder *)_decoder; + PRINTMARK(); + if (decoder->curdim <= 0) { + // start of array - initialise the context buffer + npyarr = decoder->npyarr = PyObject_Malloc(sizeof(NpyArrContext)); + decoder->npyarr_addr = npyarr; + + if (!npyarr) { + PyErr_NoMemory(); + return NULL; + } + + npyarr->dec = decoder; + npyarr->labels[0] = npyarr->labels[1] = NULL; + + npyarr->shape.ptr = PyObject_Malloc(sizeof(npy_intp) * NPY_MAXDIMS); + npyarr->shape.len = 1; + npyarr->ret = NULL; + + npyarr->elsize = 0; + npyarr->elcount = 4; + npyarr->i = 0; + } else { + // starting a new dimension continue the current array (and reshape + // after) + npyarr = (NpyArrContext *)decoder->npyarr; + if (decoder->curdim >= npyarr->shape.len) { + npyarr->shape.len++; + } + } -PyObject* Npy_returnLabelled(NpyArrContext* npyarr) -{ - PyObject* ret = npyarr->ret; - npy_intp i; - - if (npyarr->labels[0] || npyarr->labels[1]) - { - // finished decoding, build tuple with values and labels - ret = PyTuple_New(npyarr->shape.len+1); - for (i = 0; i < npyarr->shape.len; i++) - { - if (npyarr->labels[i]) - { - PyTuple_SET_ITEM(ret, i+1, npyarr->labels[i]); - npyarr->labels[i] = NULL; - } - else - { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(ret, i+1, Py_None); - } - } - PyTuple_SET_ITEM(ret, 0, npyarr->ret); - } - - return ret; + npyarr->shape.ptr[decoder->curdim] = 0; + decoder->curdim++; + return npyarr; } -JSOBJ Object_npyEndArray(void *prv, JSOBJ obj) -{ - PyObject *ret; - char* new_data; - NpyArrContext* npyarr = (NpyArrContext*) obj; - int emptyType = NPY_DEFAULT_TYPE; - npy_intp i; - PRINTMARK(); - if (!npyarr) - { - return NULL; - } - - ret = npyarr->ret; - i = npyarr->i; - - npyarr->dec->curdim--; - - if (i == 0 || !npyarr->ret) { - // empty array would not have been initialised so do it now. - if (npyarr->dec->dtype) - { - emptyType = npyarr->dec->dtype->type_num; - } - npyarr->ret = ret = PyArray_EMPTY(npyarr->shape.len, npyarr->shape.ptr, emptyType, 0); - } - else if (npyarr->dec->curdim <= 0) - { - // realloc to final size - new_data = PyDataMem_RENEW(PyArray_DATA(ret), i * npyarr->elsize); - if (new_data == NULL) { - PyErr_NoMemory(); - Npy_releaseContext(npyarr); - return NULL; - } - ((PyArrayObject*) ret)->data = (void*) new_data; - // PyArray_BYTES(ret) = new_data; - } - - if (npyarr->dec->curdim <= 0) - { - // finished decoding array, reshape if necessary - if (npyarr->shape.len > 1) - { - npyarr->ret = PyArray_Newshape((PyArrayObject*) ret, &npyarr->shape, NPY_ANYORDER); - Py_DECREF(ret); +PyObject *Npy_returnLabelled(NpyArrContext *npyarr) { + PyObject *ret = npyarr->ret; + npy_intp i; + + if (npyarr->labels[0] || npyarr->labels[1]) { + // finished decoding, build tuple with values and labels + ret = PyTuple_New(npyarr->shape.len + 1); + for (i = 0; i < npyarr->shape.len; i++) { + if (npyarr->labels[i]) { + PyTuple_SET_ITEM(ret, i + 1, npyarr->labels[i]); + npyarr->labels[i] = NULL; + } else { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(ret, i + 1, Py_None); + } + } + PyTuple_SET_ITEM(ret, 0, npyarr->ret); } - ret = Npy_returnLabelled(npyarr); - - npyarr->ret = NULL; - Npy_releaseContext(npyarr); - } - - return ret; + return ret; } -int Object_npyArrayAddItem(void *prv, JSOBJ obj, JSOBJ value) -{ - PyObject* type; - PyArray_Descr* dtype; - npy_intp i; - char *new_data, *item; - NpyArrContext* npyarr = (NpyArrContext*) obj; - PRINTMARK(); - if (!npyarr) - { - return 0; - } +JSOBJ Object_npyEndArray(void *prv, JSOBJ obj) { + PyObject *ret; + char *new_data; + NpyArrContext *npyarr = (NpyArrContext *)obj; + int emptyType = NPY_DEFAULT_TYPE; + npy_intp i; + PRINTMARK(); + if (!npyarr) { + return NULL; + } - i = npyarr->i; + ret = npyarr->ret; + i = npyarr->i; + + npyarr->dec->curdim--; + + if (i == 0 || !npyarr->ret) { + // empty array would not have been initialised so do it now. + if (npyarr->dec->dtype) { + emptyType = npyarr->dec->dtype->type_num; + } + npyarr->ret = ret = + PyArray_EMPTY(npyarr->shape.len, npyarr->shape.ptr, emptyType, 0); + } else if (npyarr->dec->curdim <= 0) { + // realloc to final size + new_data = PyDataMem_RENEW(PyArray_DATA(ret), i * npyarr->elsize); + if (new_data == NULL) { + PyErr_NoMemory(); + Npy_releaseContext(npyarr); + return NULL; + } + ((PyArrayObject *)ret)->data = (void *)new_data; + // PyArray_BYTES(ret) = new_data; + } - npyarr->shape.ptr[npyarr->dec->curdim-1]++; + if (npyarr->dec->curdim <= 0) { + // finished decoding array, reshape if necessary + if (npyarr->shape.len > 1) { + npyarr->ret = PyArray_Newshape((PyArrayObject *)ret, &npyarr->shape, + NPY_ANYORDER); + Py_DECREF(ret); + } - if (PyArray_Check((PyObject*)value)) - { - // multidimensional array, keep decoding values. - return 1; - } - - if (!npyarr->ret) - { - // Array not initialised yet. - // We do it here so we can 'sniff' the data type if none was provided - if (!npyarr->dec->dtype) - { - type = PyObject_Type(value); - if(!PyArray_DescrConverter(type, &dtype)) - { - Py_DECREF(type); - goto fail; - } - Py_INCREF(dtype); - Py_DECREF(type); - } - else - { - dtype = PyArray_DescrNew(npyarr->dec->dtype); - } - - // If it's an object or string then fill a Python list and subsequently - // convert. Otherwise we would need to somehow mess about with - // reference counts when renewing memory. - npyarr->elsize = dtype->elsize; - if (PyDataType_REFCHK(dtype) || npyarr->elsize == 0) - { - Py_XDECREF(dtype); - - if (npyarr->dec->curdim > 1) - { - PyErr_SetString(PyExc_ValueError, "Cannot decode multidimensional arrays with variable length elements to numpy"); - goto fail; - } - npyarr->elcount = 0; - npyarr->ret = PyList_New(0); - if (!npyarr->ret) - { - goto fail; - } - ((JSONObjectDecoder*)npyarr->dec)->newArray = Object_npyNewArrayList; - ((JSONObjectDecoder*)npyarr->dec)->arrayAddItem = Object_npyArrayListAddItem; - ((JSONObjectDecoder*)npyarr->dec)->endArray = Object_npyEndArrayList; - return Object_npyArrayListAddItem(prv, obj, value); + ret = Npy_returnLabelled(npyarr); + + npyarr->ret = NULL; + Npy_releaseContext(npyarr); } - npyarr->ret = PyArray_NewFromDescr(&PyArray_Type, dtype, 1, - &npyarr->elcount, NULL,NULL, 0, NULL); + return ret; +} - if (!npyarr->ret) - { - goto fail; +int Object_npyArrayAddItem(void *prv, JSOBJ obj, JSOBJ value) { + PyObject *type; + PyArray_Descr *dtype; + npy_intp i; + char *new_data, *item; + NpyArrContext *npyarr = (NpyArrContext *)obj; + PRINTMARK(); + if (!npyarr) { + return 0; } - } - if (i >= npyarr->elcount) { - // Grow PyArray_DATA(ret): - // this is similar for the strategy for PyListObject, but we use - // 50% overallocation => 0, 4, 8, 14, 23, 36, 56, 86 ... - if (npyarr->elsize == 0) - { - PyErr_SetString(PyExc_ValueError, "Cannot decode multidimensional arrays with variable length elements to numpy"); - goto fail; - } + i = npyarr->i; - npyarr->elcount = (i >> 1) + (i < 4 ? 4 : 2) + i; - if (npyarr->elcount <= NPY_MAX_INTP/npyarr->elsize) { - new_data = PyDataMem_RENEW(PyArray_DATA(npyarr->ret), npyarr->elcount * npyarr->elsize); + npyarr->shape.ptr[npyarr->dec->curdim - 1]++; + + if (PyArray_Check((PyObject *)value)) { + // multidimensional array, keep decoding values. + return 1; } - else { - PyErr_NoMemory(); - goto fail; + + if (!npyarr->ret) { + // Array not initialised yet. + // We do it here so we can 'sniff' the data type if none was provided + if (!npyarr->dec->dtype) { + type = PyObject_Type(value); + if (!PyArray_DescrConverter(type, &dtype)) { + Py_DECREF(type); + goto fail; + } + Py_INCREF(dtype); + Py_DECREF(type); + } else { + dtype = PyArray_DescrNew(npyarr->dec->dtype); + } + + // If it's an object or string then fill a Python list and subsequently + // convert. Otherwise we would need to somehow mess about with + // reference counts when renewing memory. + npyarr->elsize = dtype->elsize; + if (PyDataType_REFCHK(dtype) || npyarr->elsize == 0) { + Py_XDECREF(dtype); + + if (npyarr->dec->curdim > 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot decode multidimensional arrays with " + "variable length elements to numpy"); + goto fail; + } + npyarr->elcount = 0; + npyarr->ret = PyList_New(0); + if (!npyarr->ret) { + goto fail; + } + ((JSONObjectDecoder *)npyarr->dec)->newArray = + Object_npyNewArrayList; + ((JSONObjectDecoder *)npyarr->dec)->arrayAddItem = + Object_npyArrayListAddItem; + ((JSONObjectDecoder *)npyarr->dec)->endArray = + Object_npyEndArrayList; + return Object_npyArrayListAddItem(prv, obj, value); + } + + npyarr->ret = PyArray_NewFromDescr( + &PyArray_Type, dtype, 1, &npyarr->elcount, NULL, NULL, 0, NULL); + + if (!npyarr->ret) { + goto fail; + } } - ((PyArrayObject*) npyarr->ret)->data = (void*) new_data; - // PyArray_BYTES(npyarr->ret) = new_data; - } + if (i >= npyarr->elcount) { + // Grow PyArray_DATA(ret): + // this is similar for the strategy for PyListObject, but we use + // 50% overallocation => 0, 4, 8, 14, 23, 36, 56, 86 ... + if (npyarr->elsize == 0) { + PyErr_SetString(PyExc_ValueError, + "Cannot decode multidimensional arrays with " + "variable length elements to numpy"); + goto fail; + } + + npyarr->elcount = (i >> 1) + (i < 4 ? 4 : 2) + i; + if (npyarr->elcount <= NPY_MAX_INTP / npyarr->elsize) { + new_data = PyDataMem_RENEW(PyArray_DATA(npyarr->ret), + npyarr->elcount * npyarr->elsize); + } else { + PyErr_NoMemory(); + goto fail; + } + ((PyArrayObject *)npyarr->ret)->data = (void *)new_data; + + // PyArray_BYTES(npyarr->ret) = new_data; + } - PyArray_DIMS(npyarr->ret)[0] = i + 1; + PyArray_DIMS(npyarr->ret)[0] = i + 1; - if ((item = PyArray_GETPTR1(npyarr->ret, i)) == NULL - || PyArray_SETITEM(npyarr->ret, item, value) == -1) { - goto fail; - } + if ((item = PyArray_GETPTR1(npyarr->ret, i)) == NULL || + PyArray_SETITEM(npyarr->ret, item, value) == -1) { + goto fail; + } - Py_DECREF( (PyObject *) value); - npyarr->i++; - return 1; + Py_DECREF((PyObject *)value); + npyarr->i++; + return 1; fail: - Npy_releaseContext(npyarr); - return 0; + Npy_releaseContext(npyarr); + return 0; } -JSOBJ Object_npyNewArrayList(void *prv, void* _decoder) -{ - PyObjectDecoder* decoder = (PyObjectDecoder*) _decoder; - PRINTMARK(); - PyErr_SetString(PyExc_ValueError, "nesting not supported for object or variable length dtypes"); - Npy_releaseContext(decoder->npyarr); - return NULL; +JSOBJ Object_npyNewArrayList(void *prv, void *_decoder) { + PyObjectDecoder *decoder = (PyObjectDecoder *)_decoder; + PRINTMARK(); + PyErr_SetString( + PyExc_ValueError, + "nesting not supported for object or variable length dtypes"); + Npy_releaseContext(decoder->npyarr); + return NULL; } -JSOBJ Object_npyEndArrayList(void *prv, JSOBJ obj) -{ - PyObject *list, *ret; - NpyArrContext* npyarr = (NpyArrContext*) obj; - PRINTMARK(); - if (!npyarr) - { - return NULL; - } +JSOBJ Object_npyEndArrayList(void *prv, JSOBJ obj) { + PyObject *list, *ret; + NpyArrContext *npyarr = (NpyArrContext *)obj; + PRINTMARK(); + if (!npyarr) { + return NULL; + } - // convert decoded list to numpy array - list = (PyObject *) npyarr->ret; - npyarr->ret = PyArray_FROM_O(list); + // convert decoded list to numpy array + list = (PyObject *)npyarr->ret; + npyarr->ret = PyArray_FROM_O(list); - ret = Npy_returnLabelled(npyarr); - npyarr->ret = list; + ret = Npy_returnLabelled(npyarr); + npyarr->ret = list; - ((JSONObjectDecoder*)npyarr->dec)->newArray = Object_npyNewArray; - ((JSONObjectDecoder*)npyarr->dec)->arrayAddItem = Object_npyArrayAddItem; - ((JSONObjectDecoder*)npyarr->dec)->endArray = Object_npyEndArray; - Npy_releaseContext(npyarr); - return ret; + ((JSONObjectDecoder *)npyarr->dec)->newArray = Object_npyNewArray; + ((JSONObjectDecoder *)npyarr->dec)->arrayAddItem = Object_npyArrayAddItem; + ((JSONObjectDecoder *)npyarr->dec)->endArray = Object_npyEndArray; + Npy_releaseContext(npyarr); + return ret; } -int Object_npyArrayListAddItem(void *prv, JSOBJ obj, JSOBJ value) -{ - NpyArrContext* npyarr = (NpyArrContext*) obj; - PRINTMARK(); - if (!npyarr) - { - return 0; - } - PyList_Append((PyObject*) npyarr->ret, value); - Py_DECREF( (PyObject *) value); - npyarr->elcount++; - return 1; +int Object_npyArrayListAddItem(void *prv, JSOBJ obj, JSOBJ value) { + NpyArrContext *npyarr = (NpyArrContext *)obj; + PRINTMARK(); + if (!npyarr) { + return 0; + } + PyList_Append((PyObject *)npyarr->ret, value); + Py_DECREF((PyObject *)value); + npyarr->elcount++; + return 1; } +JSOBJ Object_npyNewObject(void *prv, void *_decoder) { + PyObjectDecoder *decoder = (PyObjectDecoder *)_decoder; + PRINTMARK(); + if (decoder->curdim > 1) { + PyErr_SetString(PyExc_ValueError, + "labels only supported up to 2 dimensions"); + return NULL; + } -JSOBJ Object_npyNewObject(void *prv, void* _decoder) -{ - PyObjectDecoder* decoder = (PyObjectDecoder*) _decoder; - PRINTMARK(); - if (decoder->curdim > 1) - { - PyErr_SetString(PyExc_ValueError, "labels only supported up to 2 dimensions"); - return NULL; - } - - return ((JSONObjectDecoder*)decoder)->newArray(prv, decoder); + return ((JSONObjectDecoder *)decoder)->newArray(prv, decoder); } -JSOBJ Object_npyEndObject(void *prv, JSOBJ obj) -{ - PyObject *list; - npy_intp labelidx; - NpyArrContext* npyarr = (NpyArrContext*) obj; - PRINTMARK(); - if (!npyarr) - { - return NULL; - } +JSOBJ Object_npyEndObject(void *prv, JSOBJ obj) { + PyObject *list; + npy_intp labelidx; + NpyArrContext *npyarr = (NpyArrContext *)obj; + PRINTMARK(); + if (!npyarr) { + return NULL; + } - labelidx = npyarr->dec->curdim-1; + labelidx = npyarr->dec->curdim - 1; - list = npyarr->labels[labelidx]; - if (list) - { - npyarr->labels[labelidx] = PyArray_FROM_O(list); - Py_DECREF(list); - } + list = npyarr->labels[labelidx]; + if (list) { + npyarr->labels[labelidx] = PyArray_FROM_O(list); + Py_DECREF(list); + } - return (PyObject*) ((JSONObjectDecoder*)npyarr->dec)->endArray(prv, obj); + return (PyObject *)((JSONObjectDecoder *)npyarr->dec)->endArray(prv, obj); } -int Object_npyObjectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value) -{ - PyObject *label; - npy_intp labelidx; - // add key to label array, value to values array - NpyArrContext* npyarr = (NpyArrContext*) obj; - PRINTMARK(); - if (!npyarr) - { +int Object_npyObjectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value) { + PyObject *label; + npy_intp labelidx; + // add key to label array, value to values array + NpyArrContext *npyarr = (NpyArrContext *)obj; + PRINTMARK(); + if (!npyarr) { + return 0; + } + + label = (PyObject *)name; + labelidx = npyarr->dec->curdim - 1; + + if (!npyarr->labels[labelidx]) { + npyarr->labels[labelidx] = PyList_New(0); + } + + // only fill label array once, assumes all column labels are the same + // for 2-dimensional arrays. + if (PyList_GET_SIZE(npyarr->labels[labelidx]) <= npyarr->elcount) { + PyList_Append(npyarr->labels[labelidx], label); + } + + if (((JSONObjectDecoder *)npyarr->dec)->arrayAddItem(prv, obj, value)) { + Py_DECREF(label); + return 1; + } return 0; - } - - label = (PyObject*) name; - labelidx = npyarr->dec->curdim-1; - - if (!npyarr->labels[labelidx]) - { - npyarr->labels[labelidx] = PyList_New(0); - } - - // only fill label array once, assumes all column labels are the same - // for 2-dimensional arrays. - if (PyList_GET_SIZE(npyarr->labels[labelidx]) <= npyarr->elcount) - { - PyList_Append(npyarr->labels[labelidx], label); - } - - if(((JSONObjectDecoder*)npyarr->dec)->arrayAddItem(prv, obj, value)) - { - Py_DECREF(label); - return 1; - } - return 0; } -int Object_objectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value) -{ - PyDict_SetItem (obj, name, value); - Py_DECREF( (PyObject *) name); - Py_DECREF( (PyObject *) value); - return 1; +int Object_objectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value) { + PyDict_SetItem(obj, name, value); + Py_DECREF((PyObject *)name); + Py_DECREF((PyObject *)value); + return 1; } -int Object_arrayAddItem(void *prv, JSOBJ obj, JSOBJ value) -{ - PyList_Append(obj, value); - Py_DECREF( (PyObject *) value); - return 1; +int Object_arrayAddItem(void *prv, JSOBJ obj, JSOBJ value) { + PyList_Append(obj, value); + Py_DECREF((PyObject *)value); + return 1; } -JSOBJ Object_newString(void *prv, wchar_t *start, wchar_t *end) -{ - return PyUnicode_FromWideChar (start, (end - start)); +JSOBJ Object_newString(void *prv, wchar_t *start, wchar_t *end) { + return PyUnicode_FromWideChar(start, (end - start)); } -JSOBJ Object_newTrue(void *prv) -{ - Py_RETURN_TRUE; -} +JSOBJ Object_newTrue(void *prv) { Py_RETURN_TRUE; } -JSOBJ Object_newFalse(void *prv) -{ - Py_RETURN_FALSE; -} +JSOBJ Object_newFalse(void *prv) { Py_RETURN_FALSE; } -JSOBJ Object_newNull(void *prv) -{ - Py_RETURN_NONE; -} +JSOBJ Object_newNull(void *prv) { Py_RETURN_NONE; } -JSOBJ Object_newObject(void *prv, void* decoder) -{ - return PyDict_New(); -} +JSOBJ Object_newObject(void *prv, void *decoder) { return PyDict_New(); } -JSOBJ Object_endObject(void *prv, JSOBJ obj) -{ - return obj; -} +JSOBJ Object_endObject(void *prv, JSOBJ obj) { return obj; } -JSOBJ Object_newArray(void *prv, void* decoder) -{ - return PyList_New(0); -} +JSOBJ Object_newArray(void *prv, void *decoder) { return PyList_New(0); } -JSOBJ Object_endArray(void *prv, JSOBJ obj) -{ - return obj; -} +JSOBJ Object_endArray(void *prv, JSOBJ obj) { return obj; } -JSOBJ Object_newInteger(void *prv, JSINT32 value) -{ - return PyInt_FromLong( (long) value); +JSOBJ Object_newInteger(void *prv, JSINT32 value) { + return PyInt_FromLong((long)value); } -JSOBJ Object_newLong(void *prv, JSINT64 value) -{ - return PyLong_FromLongLong (value); +JSOBJ Object_newLong(void *prv, JSINT64 value) { + return PyLong_FromLongLong(value); } -JSOBJ Object_newDouble(void *prv, double value) -{ - return PyFloat_FromDouble(value); +JSOBJ Object_newDouble(void *prv, double value) { + return PyFloat_FromDouble(value); } -static void Object_releaseObject(void *prv, JSOBJ obj, void* _decoder) -{ - PyObjectDecoder* decoder = (PyObjectDecoder*) _decoder; - if (obj != decoder->npyarr_addr) - { - Py_XDECREF( ((PyObject *)obj)); - } +static void Object_releaseObject(void *prv, JSOBJ obj, void *_decoder) { + PyObjectDecoder *decoder = (PyObjectDecoder *)_decoder; + if (obj != decoder->npyarr_addr) { + Py_XDECREF(((PyObject *)obj)); + } } -static char *g_kwlist[] = {"obj", "precise_float", "numpy", "labelled", "dtype", NULL}; - -PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs) -{ - PyObject *ret; - PyObject *sarg; - PyObject *arg; - PyObject *opreciseFloat = NULL; - JSONObjectDecoder *decoder; - PyObjectDecoder pyDecoder; - PyArray_Descr *dtype = NULL; - int numpy = 0, labelled = 0; - - JSONObjectDecoder dec = - { - Object_newString, - Object_objectAddKey, - Object_arrayAddItem, - Object_newTrue, - Object_newFalse, - Object_newNull, - Object_newObject, - Object_endObject, - Object_newArray, - Object_endArray, - Object_newInteger, - Object_newLong, - Object_newDouble, - Object_releaseObject, - PyObject_Malloc, - PyObject_Free, - PyObject_Realloc - }; - - dec.preciseFloat = 0; - dec.prv = NULL; - - pyDecoder.dec = dec; - pyDecoder.curdim = 0; - pyDecoder.npyarr = NULL; - pyDecoder.npyarr_addr = NULL; - - decoder = (JSONObjectDecoder*) &pyDecoder; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiiO&", g_kwlist, &arg, &opreciseFloat, &numpy, &labelled, PyArray_DescrConverter2, &dtype)) - { - Npy_releaseContext(pyDecoder.npyarr); - return NULL; - } - - if (opreciseFloat && PyObject_IsTrue(opreciseFloat)) - { - decoder->preciseFloat = 1; - } - - if (PyString_Check(arg)) - { - sarg = arg; - } - else - if (PyUnicode_Check(arg)) - { - sarg = PyUnicode_AsUTF8String(arg); - if (sarg == NULL) - { - //Exception raised above us by codec according to docs - return NULL; - } - } - else - { - PyErr_Format(PyExc_TypeError, "Expected String or Unicode"); - return NULL; - } - - decoder->errorStr = NULL; - decoder->errorOffset = NULL; +static char *g_kwlist[] = {"obj", "precise_float", "numpy", + "labelled", "dtype", NULL}; + +PyObject *JSONToObj(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject *ret; + PyObject *sarg; + PyObject *arg; + PyObject *opreciseFloat = NULL; + JSONObjectDecoder *decoder; + PyObjectDecoder pyDecoder; + PyArray_Descr *dtype = NULL; + int numpy = 0, labelled = 0; + + JSONObjectDecoder dec = { + Object_newString, Object_objectAddKey, Object_arrayAddItem, + Object_newTrue, Object_newFalse, Object_newNull, + Object_newObject, Object_endObject, Object_newArray, + Object_endArray, Object_newInteger, Object_newLong, + Object_newDouble, Object_releaseObject, PyObject_Malloc, + PyObject_Free, PyObject_Realloc}; + + dec.preciseFloat = 0; + dec.prv = NULL; + + pyDecoder.dec = dec; + pyDecoder.curdim = 0; + pyDecoder.npyarr = NULL; + pyDecoder.npyarr_addr = NULL; + + decoder = (JSONObjectDecoder *)&pyDecoder; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiiO&", g_kwlist, &arg, + &opreciseFloat, &numpy, &labelled, + PyArray_DescrConverter2, &dtype)) { + Npy_releaseContext(pyDecoder.npyarr); + return NULL; + } - if (numpy) - { - pyDecoder.dtype = dtype; - decoder->newArray = Object_npyNewArray; - decoder->endArray = Object_npyEndArray; - decoder->arrayAddItem = Object_npyArrayAddItem; + if (opreciseFloat && PyObject_IsTrue(opreciseFloat)) { + decoder->preciseFloat = 1; + } - if (labelled) - { - decoder->newObject = Object_npyNewObject; - decoder->endObject = Object_npyEndObject; - decoder->objectAddKey = Object_npyObjectAddKey; + if (PyString_Check(arg)) { + sarg = arg; + } else if (PyUnicode_Check(arg)) { + sarg = PyUnicode_AsUTF8String(arg); + if (sarg == NULL) { + // Exception raised above us by codec according to docs + return NULL; + } + } else { + PyErr_Format(PyExc_TypeError, "Expected String or Unicode"); + return NULL; } - } - ret = JSON_DecodeObject(decoder, PyString_AS_STRING(sarg), PyString_GET_SIZE(sarg)); + decoder->errorStr = NULL; + decoder->errorOffset = NULL; - if (sarg != arg) - { - Py_DECREF(sarg); - } + if (numpy) { + pyDecoder.dtype = dtype; + decoder->newArray = Object_npyNewArray; + decoder->endArray = Object_npyEndArray; + decoder->arrayAddItem = Object_npyArrayAddItem; - if (PyErr_Occurred()) - { - if (ret) - { - Py_DECREF( (PyObject *) ret); + if (labelled) { + decoder->newObject = Object_npyNewObject; + decoder->endObject = Object_npyEndObject; + decoder->objectAddKey = Object_npyObjectAddKey; + } } - Npy_releaseContext(pyDecoder.npyarr); - return NULL; - } - if (decoder->errorStr) - { - /* - FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/ + ret = JSON_DecodeObject(decoder, PyString_AS_STRING(sarg), + PyString_GET_SIZE(sarg)); - PyErr_Format (PyExc_ValueError, "%s", decoder->errorStr); + if (sarg != arg) { + Py_DECREF(sarg); + } - if (ret) - { - Py_DECREF( (PyObject *) ret); + if (PyErr_Occurred()) { + if (ret) { + Py_DECREF((PyObject *)ret); + } + Npy_releaseContext(pyDecoder.npyarr); + return NULL; } - Npy_releaseContext(pyDecoder.npyarr); - return NULL; - } + if (decoder->errorStr) { + /* + FIXME: It's possible to give a much nicer error message here with actual + failing element in input etc*/ + + PyErr_Format(PyExc_ValueError, "%s", decoder->errorStr); - return ret; + if (ret) { + Py_DECREF((PyObject *)ret); + } + Npy_releaseContext(pyDecoder.npyarr); + + return NULL; + } + + return ret; } -PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs) -{ - PyObject *read; - PyObject *string; - PyObject *result; - PyObject *file = NULL; - PyObject *argtuple; +PyObject *JSONFileToObj(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject *read; + PyObject *string; + PyObject *result; + PyObject *file = NULL; + PyObject *argtuple; - if (!PyArg_ParseTuple (args, "O", &file)) - { - return NULL; - } + if (!PyArg_ParseTuple(args, "O", &file)) { + return NULL; + } - if (!PyObject_HasAttrString (file, "read")) - { - PyErr_Format (PyExc_TypeError, "expected file"); - return NULL; - } + if (!PyObject_HasAttrString(file, "read")) { + PyErr_Format(PyExc_TypeError, "expected file"); + return NULL; + } - read = PyObject_GetAttrString (file, "read"); + read = PyObject_GetAttrString(file, "read"); - if (!PyCallable_Check (read)) { - Py_XDECREF(read); - PyErr_Format (PyExc_TypeError, "expected file"); - return NULL; - } + if (!PyCallable_Check(read)) { + Py_XDECREF(read); + PyErr_Format(PyExc_TypeError, "expected file"); + return NULL; + } - string = PyObject_CallObject (read, NULL); - Py_XDECREF(read); + string = PyObject_CallObject(read, NULL); + Py_XDECREF(read); - if (string == NULL) - { - return NULL; - } + if (string == NULL) { + return NULL; + } - argtuple = PyTuple_Pack(1, string); + argtuple = PyTuple_Pack(1, string); - result = JSONToObj (self, argtuple, kwargs); + result = JSONToObj(self, argtuple, kwargs); - Py_XDECREF(argtuple); - Py_XDECREF(string); + Py_XDECREF(argtuple); + Py_XDECREF(string); - if (result == NULL) { - return NULL; - } + if (result == NULL) { + return NULL; + } - return result; + return result; } diff --git a/pandas/src/ujson/python/objToJSON.c b/pandas/src/ujson/python/objToJSON.c index 75de63acbd7d6..42c0b62a57511 100644 --- a/pandas/src/ujson/python/objToJSON.c +++ b/pandas/src/ujson/python/objToJSON.c @@ -36,105 +36,104 @@ Numeric decoder derived from from TCL library */ #define PY_ARRAY_UNIQUE_SYMBOL UJSON_NUMPY -#include "py_defines.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static PyObject* type_decimal; +// "py_defines.h" needs to be included first to +// avoid compilation errors, but it does violate +// styleguide checks with regards to include order. +#include "py_defines.h" // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) +#include // NOLINT(build/include_order) + +static PyObject *type_decimal; #define NPY_JSON_BUFSIZE 32768 -static PyTypeObject* cls_dataframe; -static PyTypeObject* cls_series; -static PyTypeObject* cls_index; -static PyTypeObject* cls_nat; +static PyTypeObject *cls_dataframe; +static PyTypeObject *cls_series; +static PyTypeObject *cls_index; +static PyTypeObject *cls_nat; -typedef void *(*PFN_PyTypeToJSON)(JSOBJ obj, JSONTypeContext *ti, void *outValue, size_t *_outLen); +typedef void *(*PFN_PyTypeToJSON)(JSOBJ obj, JSONTypeContext *ti, + void *outValue, size_t *_outLen); #if (PY_VERSION_HEX < 0x02050000) typedef ssize_t Py_ssize_t; #endif +typedef struct __NpyArrContext { + PyObject *array; + char *dataptr; + int curdim; // current dimension in array's order + int stridedim; // dimension we are striding over + int inc; // stride dimension increment (+/- 1) + npy_intp dim; + npy_intp stride; + npy_intp ndim; + npy_intp index[NPY_MAXDIMS]; + int type_num; + PyArray_GetItemFunc *getitem; -typedef struct __NpyArrContext -{ - PyObject *array; - char* dataptr; - int curdim; // current dimension in array's order - int stridedim; // dimension we are striding over - int inc; // stride dimension increment (+/- 1) - npy_intp dim; - npy_intp stride; - npy_intp ndim; - npy_intp index[NPY_MAXDIMS]; - int type_num; - PyArray_GetItemFunc* getitem; - - char** rowLabels; - char** columnLabels; + char **rowLabels; + char **columnLabels; } NpyArrContext; -typedef struct __PdBlockContext -{ - int colIdx; - int ncols; - int transpose; +typedef struct __PdBlockContext { + int colIdx; + int ncols; + int transpose; - int* cindices; // frame column -> block column map - NpyArrContext** npyCtxts; // NpyArrContext for each column + int *cindices; // frame column -> block column map + NpyArrContext **npyCtxts; // NpyArrContext for each column } PdBlockContext; -typedef struct __TypeContext -{ - JSPFN_ITERBEGIN iterBegin; - JSPFN_ITEREND iterEnd; - JSPFN_ITERNEXT iterNext; - JSPFN_ITERGETNAME iterGetName; - JSPFN_ITERGETVALUE iterGetValue; - PFN_PyTypeToJSON PyTypeToJSON; - PyObject *newObj; - PyObject *dictObj; - Py_ssize_t index; - Py_ssize_t size; - PyObject *itemValue; - PyObject *itemName; - PyObject *attrList; - PyObject *iterator; - - double doubleValue; - JSINT64 longValue; - - char *cStr; - NpyArrContext *npyarr; - PdBlockContext *pdblock; - int transpose; - char** rowLabels; - char** columnLabels; - npy_intp rowLabelsLen; - npy_intp columnLabelsLen; +typedef struct __TypeContext { + JSPFN_ITERBEGIN iterBegin; + JSPFN_ITEREND iterEnd; + JSPFN_ITERNEXT iterNext; + JSPFN_ITERGETNAME iterGetName; + JSPFN_ITERGETVALUE iterGetValue; + PFN_PyTypeToJSON PyTypeToJSON; + PyObject *newObj; + PyObject *dictObj; + Py_ssize_t index; + Py_ssize_t size; + PyObject *itemValue; + PyObject *itemName; + PyObject *attrList; + PyObject *iterator; + + double doubleValue; + JSINT64 longValue; + + char *cStr; + NpyArrContext *npyarr; + PdBlockContext *pdblock; + int transpose; + char **rowLabels; + char **columnLabels; + npy_intp rowLabelsLen; + npy_intp columnLabelsLen; } TypeContext; -typedef struct __PyObjectEncoder -{ +typedef struct __PyObjectEncoder { JSONObjectEncoder enc; // pass through the NpyArrContext when encoding multi-dimensional arrays - NpyArrContext* npyCtxtPassthru; + NpyArrContext *npyCtxtPassthru; // pass through the PdBlockContext when encoding blocks - PdBlockContext* blkCtxtPassthru; + PdBlockContext *blkCtxtPassthru; // pass-through to encode numpy data directly int npyType; - void* npyValue; + void *npyValue; TypeContext basicTypeContext; int datetimeIso; @@ -149,16 +148,8 @@ typedef struct __PyObjectEncoder #define GET_TC(__ptrtc) ((TypeContext *)((__ptrtc)->prv)) -enum PANDAS_FORMAT -{ - SPLIT, - RECORDS, - INDEX, - COLUMNS, - VALUES -}; - -//#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__) +enum PANDAS_FORMAT { SPLIT, RECORDS, INDEX, COLUMNS, VALUES }; + #define PRINTMARK() int PdBlock_iterNext(JSOBJ, JSONTypeContext *); @@ -166,709 +157,624 @@ int PdBlock_iterNext(JSOBJ, JSONTypeContext *); // import_array() compat #if (PY_VERSION_HEX >= 0x03000000) void *initObjToJSON(void) - #else void initObjToJSON(void) #endif { - PyObject *mod_pandas; - PyObject *mod_tslib; - PyObject* mod_decimal = PyImport_ImportModule("decimal"); - type_decimal = PyObject_GetAttrString(mod_decimal, "Decimal"); - Py_INCREF(type_decimal); - Py_DECREF(mod_decimal); - - PyDateTime_IMPORT; - - mod_pandas = PyImport_ImportModule("pandas"); - if (mod_pandas) - { - cls_dataframe = (PyTypeObject*) PyObject_GetAttrString(mod_pandas, "DataFrame"); - cls_index = (PyTypeObject*) PyObject_GetAttrString(mod_pandas, "Index"); - cls_series = (PyTypeObject*) PyObject_GetAttrString(mod_pandas, "Series"); - Py_DECREF(mod_pandas); - } - - mod_tslib = PyImport_ImportModule("pandas.tslib"); - if (mod_tslib) - { - cls_nat = (PyTypeObject*) PyObject_GetAttrString(mod_tslib, "NaTType"); - Py_DECREF(mod_tslib); - } - - /* Initialise numpy API and use 2/3 compatible return */ - import_array(); - return NUMPY_IMPORT_ARRAY_RETVAL; -} - -static TypeContext* createTypeContext(void) -{ - TypeContext *pc; - - pc = PyObject_Malloc(sizeof(TypeContext)); - if (!pc) - { - PyErr_NoMemory(); - return NULL; - } - pc->newObj = NULL; - pc->dictObj = NULL; - pc->itemValue = NULL; - pc->itemName = NULL; - pc->attrList = NULL; - pc->index = 0; - pc->size = 0; - pc->longValue = 0; - pc->doubleValue = 0.0; - pc->cStr = NULL; - pc->npyarr = NULL; - pc->pdblock = NULL; - pc->rowLabels = NULL; - pc->columnLabels = NULL; - pc->transpose = 0; - pc->rowLabelsLen = 0; - pc->columnLabelsLen = 0; - - return pc; -} - -static PyObject* get_values(PyObject *obj) -{ - PyObject *values = PyObject_GetAttrString(obj, "values"); - PRINTMARK(); + PyObject *mod_pandas; + PyObject *mod_tslib; + PyObject *mod_decimal = PyImport_ImportModule("decimal"); + type_decimal = PyObject_GetAttrString(mod_decimal, "Decimal"); + Py_INCREF(type_decimal); + Py_DECREF(mod_decimal); - if (values && !PyArray_CheckExact(values)) - { - if (PyObject_HasAttrString(values, "values")) - { - PyObject *subvals = get_values(values); - PyErr_Clear(); - PRINTMARK(); - // subvals are sometimes missing a dimension - if (subvals) - { - PyArrayObject *reshape = (PyArrayObject*) subvals; - PyObject *shape = PyObject_GetAttrString(obj, "shape"); - PyArray_Dims dims; - PRINTMARK(); + PyDateTime_IMPORT; - if (!shape || !PyArray_IntpConverter(shape, &dims)) - { - subvals = NULL; - } - else - { - subvals = PyArray_Newshape(reshape, &dims, NPY_ANYORDER); - PyDimMem_FREE(dims.ptr); - } - Py_DECREF(reshape); - Py_XDECREF(shape); - } - Py_DECREF(values); - values = subvals; - } - else - { - PRINTMARK(); - Py_DECREF(values); - values = NULL; + mod_pandas = PyImport_ImportModule("pandas"); + if (mod_pandas) { + cls_dataframe = + (PyTypeObject *)PyObject_GetAttrString(mod_pandas, "DataFrame"); + cls_index = (PyTypeObject *)PyObject_GetAttrString(mod_pandas, "Index"); + cls_series = + (PyTypeObject *)PyObject_GetAttrString(mod_pandas, "Series"); + Py_DECREF(mod_pandas); } - } - if (!values && PyObject_HasAttrString(obj, "get_values")) - { - PRINTMARK(); - values = PyObject_CallMethod(obj, "get_values", NULL); - if (values && !PyArray_CheckExact(values)) - { - PRINTMARK(); - Py_DECREF(values); - values = NULL; + mod_tslib = PyImport_ImportModule("pandas.tslib"); + if (mod_tslib) { + cls_nat = (PyTypeObject *)PyObject_GetAttrString(mod_tslib, "NaTType"); + Py_DECREF(mod_tslib); } - } - if (!values) - { - PyObject *typeRepr = PyObject_Repr((PyObject*) Py_TYPE(obj)); - PyObject *repr; + /* Initialise numpy API and use 2/3 compatible return */ + import_array(); + return NUMPY_IMPORT_ARRAY_RETVAL; +} + +static TypeContext *createTypeContext(void) { + TypeContext *pc; + + pc = PyObject_Malloc(sizeof(TypeContext)); + if (!pc) { + PyErr_NoMemory(); + return NULL; + } + pc->newObj = NULL; + pc->dictObj = NULL; + pc->itemValue = NULL; + pc->itemName = NULL; + pc->attrList = NULL; + pc->index = 0; + pc->size = 0; + pc->longValue = 0; + pc->doubleValue = 0.0; + pc->cStr = NULL; + pc->npyarr = NULL; + pc->pdblock = NULL; + pc->rowLabels = NULL; + pc->columnLabels = NULL; + pc->transpose = 0; + pc->rowLabelsLen = 0; + pc->columnLabelsLen = 0; + + return pc; +} + +static PyObject *get_values(PyObject *obj) { + PyObject *values = PyObject_GetAttrString(obj, "values"); PRINTMARK(); - if (PyObject_HasAttrString(obj, "dtype")) - { - PyObject *dtype = PyObject_GetAttrString(obj, "dtype"); - repr = PyObject_Repr(dtype); - Py_DECREF(dtype); + + if (values && !PyArray_CheckExact(values)) { + if (PyObject_HasAttrString(values, "values")) { + PyObject *subvals = get_values(values); + PyErr_Clear(); + PRINTMARK(); + // subvals are sometimes missing a dimension + if (subvals) { + PyArrayObject *reshape = (PyArrayObject *)subvals; + PyObject *shape = PyObject_GetAttrString(obj, "shape"); + PyArray_Dims dims; + PRINTMARK(); + + if (!shape || !PyArray_IntpConverter(shape, &dims)) { + subvals = NULL; + } else { + subvals = PyArray_Newshape(reshape, &dims, NPY_ANYORDER); + PyDimMem_FREE(dims.ptr); + } + Py_DECREF(reshape); + Py_XDECREF(shape); + } + Py_DECREF(values); + values = subvals; + } else { + PRINTMARK(); + Py_DECREF(values); + values = NULL; + } } - else - { - repr = PyString_FromString(""); + + if (!values && PyObject_HasAttrString(obj, "get_values")) { + PRINTMARK(); + values = PyObject_CallMethod(obj, "get_values", NULL); + if (values && !PyArray_CheckExact(values)) { + PRINTMARK(); + Py_DECREF(values); + values = NULL; + } } - PyErr_Format(PyExc_ValueError, - "%s or %s are not JSON serializable yet", - PyString_AS_STRING(repr), - PyString_AS_STRING(typeRepr)); - Py_DECREF(repr); - Py_DECREF(typeRepr); + if (!values) { + PyObject *typeRepr = PyObject_Repr((PyObject *)Py_TYPE(obj)); + PyObject *repr; + PRINTMARK(); + if (PyObject_HasAttrString(obj, "dtype")) { + PyObject *dtype = PyObject_GetAttrString(obj, "dtype"); + repr = PyObject_Repr(dtype); + Py_DECREF(dtype); + } else { + repr = PyString_FromString(""); + } - return NULL; - } + PyErr_Format(PyExc_ValueError, "%s or %s are not JSON serializable yet", + PyString_AS_STRING(repr), PyString_AS_STRING(typeRepr)); + Py_DECREF(repr); + Py_DECREF(typeRepr); - return values; + return NULL; + } + + return values; } -static PyObject* get_sub_attr(PyObject *obj, char *attr, char *subAttr) -{ - PyObject *tmp = PyObject_GetAttrString(obj, attr); - PyObject *ret; +static PyObject *get_sub_attr(PyObject *obj, char *attr, char *subAttr) { + PyObject *tmp = PyObject_GetAttrString(obj, attr); + PyObject *ret; - if (tmp == 0) - { - return 0; - } - ret = PyObject_GetAttrString(tmp, subAttr); - Py_DECREF(tmp); + if (tmp == 0) { + return 0; + } + ret = PyObject_GetAttrString(tmp, subAttr); + Py_DECREF(tmp); - return ret; + return ret; } -static int is_simple_frame(PyObject *obj) -{ - PyObject *check = get_sub_attr(obj, "_data", "is_mixed_type"); - int ret = (check == Py_False); +static int is_simple_frame(PyObject *obj) { + PyObject *check = get_sub_attr(obj, "_data", "is_mixed_type"); + int ret = (check == Py_False); - if (!check) - { - return 0; - } + if (!check) { + return 0; + } - Py_DECREF(check); - return ret; + Py_DECREF(check); + return ret; } -static Py_ssize_t get_attr_length(PyObject *obj, char *attr) -{ - PyObject *tmp = PyObject_GetAttrString(obj, attr); - Py_ssize_t ret; +static Py_ssize_t get_attr_length(PyObject *obj, char *attr) { + PyObject *tmp = PyObject_GetAttrString(obj, attr); + Py_ssize_t ret; - if (tmp == 0) - { - return 0; - } - ret = PyObject_Length(tmp); - Py_DECREF(tmp); + if (tmp == 0) { + return 0; + } + ret = PyObject_Length(tmp); + Py_DECREF(tmp); - if (ret == -1) - { - return 0; - } + if (ret == -1) { + return 0; + } - return ret; + return ret; } -static PyObject* get_item(PyObject *obj, Py_ssize_t i) -{ - PyObject *tmp = PyInt_FromSsize_t(i); - PyObject *ret; +static PyObject *get_item(PyObject *obj, Py_ssize_t i) { + PyObject *tmp = PyInt_FromSsize_t(i); + PyObject *ret; - if (tmp == 0) - { - return 0; - } - ret = PyObject_GetItem(obj, tmp); - Py_DECREF(tmp); + if (tmp == 0) { + return 0; + } + ret = PyObject_GetItem(obj, tmp); + Py_DECREF(tmp); - return ret; + return ret; } -static void *CDouble(JSOBJ obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PRINTMARK(); - *((double *) outValue) = GET_TC(tc)->doubleValue; - return NULL; +static void *CDouble(JSOBJ obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PRINTMARK(); + *((double *)outValue) = GET_TC(tc)->doubleValue; + return NULL; } -static void *CLong(JSOBJ obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PRINTMARK(); - *((JSINT64 *) outValue) = GET_TC(tc)->longValue; - return NULL; +static void *CLong(JSOBJ obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PRINTMARK(); + *((JSINT64 *)outValue) = GET_TC(tc)->longValue; + return NULL; } #ifdef _LP64 -static void *PyIntToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - *((JSINT64 *) outValue) = PyInt_AS_LONG (obj); - return NULL; +static void *PyIntToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + *((JSINT64 *)outValue) = PyInt_AS_LONG(obj); + return NULL; } #else -static void *PyIntToINT32(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - *((JSINT32 *) outValue) = PyInt_AS_LONG (obj); - return NULL; +static void *PyIntToINT32(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + *((JSINT32 *)outValue) = PyInt_AS_LONG(obj); + return NULL; } #endif -static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - *((JSINT64 *) outValue) = GET_TC(tc)->longValue; - return NULL; +static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + *((JSINT64 *)outValue) = GET_TC(tc)->longValue; + return NULL; } -static void *NpyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - PyArray_CastScalarToCtype(obj, outValue, PyArray_DescrFromType(NPY_DOUBLE)); - return NULL; +static void *NpyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + PyArray_CastScalarToCtype(obj, outValue, PyArray_DescrFromType(NPY_DOUBLE)); + return NULL; } -static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - *((double *) outValue) = PyFloat_AsDouble (obj); - return NULL; +static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + *((double *)outValue) = PyFloat_AsDouble(obj); + return NULL; } -static void *PyStringToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - *_outLen = PyString_GET_SIZE(obj); - return PyString_AS_STRING(obj); +static void *PyStringToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + *_outLen = PyString_GET_SIZE(obj); + return PyString_AS_STRING(obj); } -static void *PyUnicodeToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PyObject *obj = (PyObject *) _obj; - PyObject *newObj = PyUnicode_EncodeUTF8 (PyUnicode_AS_UNICODE(obj), PyUnicode_GET_SIZE(obj), NULL); +static void *PyUnicodeToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PyObject *obj = (PyObject *)_obj; + PyObject *newObj = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(obj), + PyUnicode_GET_SIZE(obj), NULL); - GET_TC(tc)->newObj = newObj; + GET_TC(tc)->newObj = newObj; - *_outLen = PyString_GET_SIZE(newObj); - return PyString_AS_STRING(newObj); + *_outLen = PyString_GET_SIZE(newObj); + return PyString_AS_STRING(newObj); } -static void *PandasDateTimeStructToJSON(pandas_datetimestruct *dts, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - PANDAS_DATETIMEUNIT base = ((PyObjectEncoder*) tc->encoder)->datetimeUnit; +static void *PandasDateTimeStructToJSON(pandas_datetimestruct *dts, + JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + PANDAS_DATETIMEUNIT base = ((PyObjectEncoder *)tc->encoder)->datetimeUnit; - if (((PyObjectEncoder*) tc->encoder)->datetimeIso) - { - PRINTMARK(); - *_outLen = (size_t) get_datetime_iso_8601_strlen(0, base); - GET_TC(tc)->cStr = PyObject_Malloc(sizeof(char) * (*_outLen)); - if (!GET_TC(tc)->cStr) - { - PyErr_NoMemory(); - ((JSONObjectEncoder*) tc->encoder)->errorMsg = ""; - return NULL; - } + if (((PyObjectEncoder *)tc->encoder)->datetimeIso) { + PRINTMARK(); + *_outLen = (size_t)get_datetime_iso_8601_strlen(0, base); + GET_TC(tc)->cStr = PyObject_Malloc(sizeof(char) * (*_outLen)); + if (!GET_TC(tc)->cStr) { + PyErr_NoMemory(); + ((JSONObjectEncoder *)tc->encoder)->errorMsg = ""; + return NULL; + } - if (!make_iso_8601_datetime(dts, GET_TC(tc)->cStr, *_outLen, 0, base, -1, NPY_UNSAFE_CASTING)) - { - PRINTMARK(); - *_outLen = strlen(GET_TC(tc)->cStr); - return GET_TC(tc)->cStr; + if (!make_iso_8601_datetime(dts, GET_TC(tc)->cStr, *_outLen, 0, base, + -1, NPY_UNSAFE_CASTING)) { + PRINTMARK(); + *_outLen = strlen(GET_TC(tc)->cStr); + return GET_TC(tc)->cStr; + } else { + PRINTMARK(); + PyErr_SetString(PyExc_ValueError, + "Could not convert datetime value to string"); + ((JSONObjectEncoder *)tc->encoder)->errorMsg = ""; + PyObject_Free(GET_TC(tc)->cStr); + return NULL; + } + } else { + PRINTMARK(); + *((JSINT64 *)outValue) = pandas_datetimestruct_to_datetime(base, dts); + return NULL; } - else - { - PRINTMARK(); - PyErr_SetString(PyExc_ValueError, "Could not convert datetime value to string"); - ((JSONObjectEncoder*) tc->encoder)->errorMsg = ""; - PyObject_Free(GET_TC(tc)->cStr); - return NULL; - } - } - else - { - PRINTMARK(); - *((JSINT64*)outValue) = pandas_datetimestruct_to_datetime(base, dts); - return NULL; - } } -static void *NpyDateTimeScalarToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - pandas_datetimestruct dts; - PyDatetimeScalarObject *obj = (PyDatetimeScalarObject *) _obj; - PRINTMARK(); +static void *NpyDateTimeScalarToJSON(JSOBJ _obj, JSONTypeContext *tc, + void *outValue, size_t *_outLen) { + pandas_datetimestruct dts; + PyDatetimeScalarObject *obj = (PyDatetimeScalarObject *)_obj; + PRINTMARK(); - pandas_datetime_to_datetimestruct(obj->obval, (PANDAS_DATETIMEUNIT)obj->obmeta.base, &dts); - return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); + pandas_datetime_to_datetimestruct( + obj->obval, (PANDAS_DATETIMEUNIT)obj->obmeta.base, &dts); + return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); } -static void *PyDateTimeToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - pandas_datetimestruct dts; - PyObject *obj = (PyObject *) _obj; - - PRINTMARK(); +static void *PyDateTimeToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *_outLen) { + pandas_datetimestruct dts; + PyObject *obj = (PyObject *)_obj; - if (!convert_pydatetime_to_datetimestruct(obj, &dts, NULL, 1)) - { PRINTMARK(); - return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); - } - else - { - if (!PyErr_Occurred()) - { - PyErr_SetString(PyExc_ValueError, "Could not convert datetime value to string"); + + if (!convert_pydatetime_to_datetimestruct(obj, &dts, NULL, 1)) { + PRINTMARK(); + return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); + } else { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "Could not convert datetime value to string"); + } + ((JSONObjectEncoder *)tc->encoder)->errorMsg = ""; + return NULL; } - ((JSONObjectEncoder*) tc->encoder)->errorMsg = ""; - return NULL; - } } -static void *NpyDatetime64ToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen) -{ - pandas_datetimestruct dts; - PRINTMARK(); +static void *NpyDatetime64ToJSON(JSOBJ _obj, JSONTypeContext *tc, + void *outValue, size_t *_outLen) { + pandas_datetimestruct dts; + PRINTMARK(); - pandas_datetime_to_datetimestruct( - (npy_datetime) GET_TC(tc)->longValue, - PANDAS_FR_ns, &dts); - return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); + pandas_datetime_to_datetimestruct((npy_datetime)GET_TC(tc)->longValue, + PANDAS_FR_ns, &dts); + return PandasDateTimeStructToJSON(&dts, tc, outValue, _outLen); } -static void *PyTimeToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *outLen) -{ - PyObject *obj = (PyObject *) _obj; - PyObject *str; - PyObject *tmp; +static void *PyTimeToJSON(JSOBJ _obj, JSONTypeContext *tc, void *outValue, + size_t *outLen) { + PyObject *obj = (PyObject *)_obj; + PyObject *str; + PyObject *tmp; - str = PyObject_CallMethod(obj, "isoformat", NULL); - if (str == NULL) { - PRINTMARK(); - *outLen = 0; - if (!PyErr_Occurred()) - { - PyErr_SetString(PyExc_ValueError, "Failed to convert time"); + str = PyObject_CallMethod(obj, "isoformat", NULL); + if (str == NULL) { + PRINTMARK(); + *outLen = 0; + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "Failed to convert time"); + } + ((JSONObjectEncoder *)tc->encoder)->errorMsg = ""; + return NULL; + } + if (PyUnicode_Check(str)) { + tmp = str; + str = PyUnicode_AsUTF8String(str); + Py_DECREF(tmp); } - ((JSONObjectEncoder*) tc->encoder)->errorMsg = ""; - return NULL; - } - if (PyUnicode_Check(str)) - { - tmp = str; - str = PyUnicode_AsUTF8String(str); - Py_DECREF(tmp); - } - GET_TC(tc)->newObj = str; + GET_TC(tc)->newObj = str; - *outLen = PyString_GET_SIZE(str); - outValue = (void *) PyString_AS_STRING (str); - return outValue; + *outLen = PyString_GET_SIZE(str); + outValue = (void *)PyString_AS_STRING(str); + return outValue; } -static int NpyTypeToJSONType(PyObject* obj, JSONTypeContext* tc, int npyType, void* value) -{ - PyArray_VectorUnaryFunc* castfunc; - npy_double doubleVal; - npy_int64 longVal; +static int NpyTypeToJSONType(PyObject *obj, JSONTypeContext *tc, int npyType, + void *value) { + PyArray_VectorUnaryFunc *castfunc; + npy_double doubleVal; + npy_int64 longVal; - if (PyTypeNum_ISFLOAT(npyType)) - { - PRINTMARK(); - castfunc = PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_DOUBLE); - if (!castfunc) - { - PyErr_Format ( - PyExc_ValueError, - "Cannot cast numpy dtype %d to double", - npyType); + if (PyTypeNum_ISFLOAT(npyType)) { + PRINTMARK(); + castfunc = + PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_DOUBLE); + if (!castfunc) { + PyErr_Format(PyExc_ValueError, + "Cannot cast numpy dtype %d to double", npyType); + } + castfunc(value, &doubleVal, 1, NULL, NULL); + if (npy_isnan(doubleVal) || npy_isinf(doubleVal)) { + PRINTMARK(); + return JT_NULL; + } + GET_TC(tc)->doubleValue = (double)doubleVal; + GET_TC(tc)->PyTypeToJSON = CDouble; + return JT_DOUBLE; } - castfunc(value, &doubleVal, 1, NULL, NULL); - if (npy_isnan(doubleVal) || npy_isinf(doubleVal)) - { - PRINTMARK(); - return JT_NULL; + + if (PyTypeNum_ISDATETIME(npyType)) { + PRINTMARK(); + castfunc = + PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_INT64); + if (!castfunc) { + PyErr_Format(PyExc_ValueError, "Cannot cast numpy dtype %d to long", + npyType); + } + castfunc(value, &longVal, 1, NULL, NULL); + if (longVal == get_nat()) { + PRINTMARK(); + return JT_NULL; + } + GET_TC(tc)->longValue = (JSINT64)longVal; + GET_TC(tc)->PyTypeToJSON = NpyDatetime64ToJSON; + return ((PyObjectEncoder *)tc->encoder)->datetimeIso ? JT_UTF8 + : JT_LONG; } - GET_TC(tc)->doubleValue = (double) doubleVal; - GET_TC(tc)->PyTypeToJSON = CDouble; - return JT_DOUBLE; - } - if (PyTypeNum_ISDATETIME(npyType)) - { - PRINTMARK(); - castfunc = PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_INT64); - if (!castfunc) - { - PyErr_Format ( - PyExc_ValueError, - "Cannot cast numpy dtype %d to long", - npyType); + if (PyTypeNum_ISINTEGER(npyType)) { + PRINTMARK(); + castfunc = + PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_INT64); + if (!castfunc) { + PyErr_Format(PyExc_ValueError, "Cannot cast numpy dtype %d to long", + npyType); + } + castfunc(value, &longVal, 1, NULL, NULL); + GET_TC(tc)->longValue = (JSINT64)longVal; + GET_TC(tc)->PyTypeToJSON = CLong; + return JT_LONG; } - castfunc(value, &longVal, 1, NULL, NULL); - if (longVal == get_nat()) - { - PRINTMARK(); - return JT_NULL; + + if (PyTypeNum_ISBOOL(npyType)) { + PRINTMARK(); + return *((npy_bool *)value) == NPY_TRUE ? JT_TRUE : JT_FALSE; } - GET_TC(tc)->longValue = (JSINT64) longVal; - GET_TC(tc)->PyTypeToJSON = NpyDatetime64ToJSON; - return ((PyObjectEncoder *) tc->encoder)->datetimeIso ? JT_UTF8 : JT_LONG; - } - if (PyTypeNum_ISINTEGER(npyType)) - { - PRINTMARK(); - castfunc = PyArray_GetCastFunc(PyArray_DescrFromType(npyType), NPY_INT64); - if (!castfunc) - { - PyErr_Format ( - PyExc_ValueError, - "Cannot cast numpy dtype %d to long", - npyType); - } - castfunc(value, &longVal, 1, NULL, NULL); - GET_TC(tc)->longValue = (JSINT64) longVal; - GET_TC(tc)->PyTypeToJSON = CLong; - return JT_LONG; - } - - if (PyTypeNum_ISBOOL(npyType)) - { PRINTMARK(); - return *((npy_bool *) value) == NPY_TRUE ? JT_TRUE : JT_FALSE; - } - - PRINTMARK(); - return JT_INVALID; + return JT_INVALID; } - //============================================================================= // Numpy array iteration functions //============================================================================= -static void NpyArr_freeItemValue(JSOBJ _obj, JSONTypeContext *tc) -{ - if (GET_TC(tc)->npyarr && GET_TC(tc)->itemValue != GET_TC(tc)->npyarr->array) - { - PRINTMARK(); - Py_XDECREF(GET_TC(tc)->itemValue); - GET_TC(tc)->itemValue = NULL; - } +static void NpyArr_freeItemValue(JSOBJ _obj, JSONTypeContext *tc) { + if (GET_TC(tc)->npyarr && + GET_TC(tc)->itemValue != GET_TC(tc)->npyarr->array) { + PRINTMARK(); + Py_XDECREF(GET_TC(tc)->itemValue); + GET_TC(tc)->itemValue = NULL; + } } -int NpyArr_iterNextNone(JSOBJ _obj, JSONTypeContext *tc) -{ - return 0; -} +int NpyArr_iterNextNone(JSOBJ _obj, JSONTypeContext *tc) { return 0; } -void NpyArr_iterBegin(JSOBJ _obj, JSONTypeContext *tc) -{ - PyArrayObject *obj; - NpyArrContext *npyarr; - - if (GET_TC(tc)->newObj) - { - obj = (PyArrayObject *) GET_TC(tc)->newObj; - } - else - { - obj = (PyArrayObject *) _obj; - } - - if (PyArray_SIZE(obj) < 0) - { - PRINTMARK(); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - } - else - { - PRINTMARK(); - npyarr = PyObject_Malloc(sizeof(NpyArrContext)); - GET_TC(tc)->npyarr = npyarr; +void NpyArr_iterBegin(JSOBJ _obj, JSONTypeContext *tc) { + PyArrayObject *obj; + NpyArrContext *npyarr; - if (!npyarr) - { - PyErr_NoMemory(); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - return; + if (GET_TC(tc)->newObj) { + obj = (PyArrayObject *)GET_TC(tc)->newObj; + } else { + obj = (PyArrayObject *)_obj; } - npyarr->array = (PyObject*) obj; - npyarr->getitem = (PyArray_GetItemFunc*) PyArray_DESCR(obj)->f->getitem; - npyarr->dataptr = PyArray_DATA(obj); - npyarr->ndim = PyArray_NDIM(obj) - 1; - npyarr->curdim = 0; - npyarr->type_num = PyArray_DESCR(obj)->type_num; + if (PyArray_SIZE(obj) < 0) { + PRINTMARK(); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + } else { + PRINTMARK(); + npyarr = PyObject_Malloc(sizeof(NpyArrContext)); + GET_TC(tc)->npyarr = npyarr; - if (GET_TC(tc)->transpose) - { - npyarr->dim = PyArray_DIM(obj, npyarr->ndim); - npyarr->stride = PyArray_STRIDE(obj, npyarr->ndim); - npyarr->stridedim = npyarr->ndim; - npyarr->index[npyarr->ndim] = 0; - npyarr->inc = -1; - } - else - { - npyarr->dim = PyArray_DIM(obj, 0); - npyarr->stride = PyArray_STRIDE(obj, 0); - npyarr->stridedim = 0; - npyarr->index[0] = 0; - npyarr->inc = 1; - } + if (!npyarr) { + PyErr_NoMemory(); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + return; + } + + npyarr->array = (PyObject *)obj; + npyarr->getitem = (PyArray_GetItemFunc *)PyArray_DESCR(obj)->f->getitem; + npyarr->dataptr = PyArray_DATA(obj); + npyarr->ndim = PyArray_NDIM(obj) - 1; + npyarr->curdim = 0; + npyarr->type_num = PyArray_DESCR(obj)->type_num; + + if (GET_TC(tc)->transpose) { + npyarr->dim = PyArray_DIM(obj, npyarr->ndim); + npyarr->stride = PyArray_STRIDE(obj, npyarr->ndim); + npyarr->stridedim = npyarr->ndim; + npyarr->index[npyarr->ndim] = 0; + npyarr->inc = -1; + } else { + npyarr->dim = PyArray_DIM(obj, 0); + npyarr->stride = PyArray_STRIDE(obj, 0); + npyarr->stridedim = 0; + npyarr->index[0] = 0; + npyarr->inc = 1; + } - npyarr->columnLabels = GET_TC(tc)->columnLabels; - npyarr->rowLabels = GET_TC(tc)->rowLabels; - } + npyarr->columnLabels = GET_TC(tc)->columnLabels; + npyarr->rowLabels = GET_TC(tc)->rowLabels; + } } -void NpyArr_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - NpyArrContext *npyarr = GET_TC(tc)->npyarr; - PRINTMARK(); +void NpyArr_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + NpyArrContext *npyarr = GET_TC(tc)->npyarr; + PRINTMARK(); - if (npyarr) - { - NpyArr_freeItemValue(obj, tc); - PyObject_Free(npyarr); - } + if (npyarr) { + NpyArr_freeItemValue(obj, tc); + PyObject_Free(npyarr); + } } -void NpyArrPassThru_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - PRINTMARK(); -} +void NpyArrPassThru_iterBegin(JSOBJ obj, JSONTypeContext *tc) { PRINTMARK(); } -void NpyArrPassThru_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - NpyArrContext* npyarr = GET_TC(tc)->npyarr; - PRINTMARK(); - // finished this dimension, reset the data pointer - npyarr->curdim--; - npyarr->dataptr -= npyarr->stride * npyarr->index[npyarr->stridedim]; - npyarr->stridedim -= npyarr->inc; - npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim); - npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim); - npyarr->dataptr += npyarr->stride; +void NpyArrPassThru_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + NpyArrContext *npyarr = GET_TC(tc)->npyarr; + PRINTMARK(); + // finished this dimension, reset the data pointer + npyarr->curdim--; + npyarr->dataptr -= npyarr->stride * npyarr->index[npyarr->stridedim]; + npyarr->stridedim -= npyarr->inc; + npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim); + npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim); + npyarr->dataptr += npyarr->stride; - NpyArr_freeItemValue(obj, tc); + NpyArr_freeItemValue(obj, tc); } -int NpyArr_iterNextItem(JSOBJ obj, JSONTypeContext *tc) -{ - NpyArrContext* npyarr = GET_TC(tc)->npyarr; - PRINTMARK(); +int NpyArr_iterNextItem(JSOBJ obj, JSONTypeContext *tc) { + NpyArrContext *npyarr = GET_TC(tc)->npyarr; + PRINTMARK(); - if (PyErr_Occurred()) - { - return 0; - } + if (PyErr_Occurred()) { + return 0; + } - if (npyarr->index[npyarr->stridedim] >= npyarr->dim) - { - PRINTMARK(); - return 0; - } + if (npyarr->index[npyarr->stridedim] >= npyarr->dim) { + PRINTMARK(); + return 0; + } - NpyArr_freeItemValue(obj, tc); + NpyArr_freeItemValue(obj, tc); #if NPY_API_VERSION < 0x00000007 - if(PyArray_ISDATETIME(npyarr->array)) - { - PRINTMARK(); - GET_TC(tc)->itemValue = PyArray_ToScalar(npyarr->dataptr, npyarr->array); - } - else - if (PyArray_ISNUMBER(npyarr->array)) + if (PyArray_ISDATETIME(npyarr->array)) { + PRINTMARK(); + GET_TC(tc) + ->itemValue = PyArray_ToScalar(npyarr->dataptr, npyarr->array); + } else if (PyArray_ISNUMBER(npyarr->array)) // NOLINT #else - if (PyArray_ISNUMBER(npyarr->array) || PyArray_ISDATETIME(npyarr->array)) + if (PyArray_ISNUMBER(npyarr->array) || PyArray_ISDATETIME(npyarr->array)) // NOLINT #endif - { - PRINTMARK(); - GET_TC(tc)->itemValue = obj; - Py_INCREF(obj); - ((PyObjectEncoder*) tc->encoder)->npyType = PyArray_TYPE(npyarr->array); - ((PyObjectEncoder*) tc->encoder)->npyValue = npyarr->dataptr; - ((PyObjectEncoder*) tc->encoder)->npyCtxtPassthru = npyarr; - } - else - { - PRINTMARK(); - GET_TC(tc)->itemValue = npyarr->getitem(npyarr->dataptr, npyarr->array); - } + { + PRINTMARK(); + GET_TC(tc)->itemValue = obj; + Py_INCREF(obj); + ((PyObjectEncoder *)tc->encoder)->npyType = PyArray_TYPE(npyarr->array); + ((PyObjectEncoder *)tc->encoder)->npyValue = npyarr->dataptr; + ((PyObjectEncoder *)tc->encoder)->npyCtxtPassthru = npyarr; + } else { + PRINTMARK(); + GET_TC(tc)->itemValue = npyarr->getitem(npyarr->dataptr, npyarr->array); + } - npyarr->dataptr += npyarr->stride; - npyarr->index[npyarr->stridedim]++; - return 1; + npyarr->dataptr += npyarr->stride; + npyarr->index[npyarr->stridedim]++; + return 1; } -int NpyArr_iterNext(JSOBJ _obj, JSONTypeContext *tc) -{ - NpyArrContext* npyarr = GET_TC(tc)->npyarr; - PRINTMARK(); - - if (PyErr_Occurred()) - { +int NpyArr_iterNext(JSOBJ _obj, JSONTypeContext *tc) { + NpyArrContext *npyarr = GET_TC(tc)->npyarr; PRINTMARK(); - return 0; - } - if (npyarr->curdim >= npyarr->ndim || npyarr->index[npyarr->stridedim] >= npyarr->dim) - { - PRINTMARK(); - // innermost dimension, start retrieving item values - GET_TC(tc)->iterNext = NpyArr_iterNextItem; - return NpyArr_iterNextItem(_obj, tc); - } + if (PyErr_Occurred()) { + PRINTMARK(); + return 0; + } + + if (npyarr->curdim >= npyarr->ndim || + npyarr->index[npyarr->stridedim] >= npyarr->dim) { + PRINTMARK(); + // innermost dimension, start retrieving item values + GET_TC(tc)->iterNext = NpyArr_iterNextItem; + return NpyArr_iterNextItem(_obj, tc); + } - // dig a dimension deeper - npyarr->index[npyarr->stridedim]++; + // dig a dimension deeper + npyarr->index[npyarr->stridedim]++; - npyarr->curdim++; - npyarr->stridedim += npyarr->inc; - npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim); - npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim); - npyarr->index[npyarr->stridedim] = 0; + npyarr->curdim++; + npyarr->stridedim += npyarr->inc; + npyarr->dim = PyArray_DIM(npyarr->array, npyarr->stridedim); + npyarr->stride = PyArray_STRIDE(npyarr->array, npyarr->stridedim); + npyarr->index[npyarr->stridedim] = 0; - ((PyObjectEncoder*) tc->encoder)->npyCtxtPassthru = npyarr; - GET_TC(tc)->itemValue = npyarr->array; - return 1; + ((PyObjectEncoder *)tc->encoder)->npyCtxtPassthru = npyarr; + GET_TC(tc)->itemValue = npyarr->array; + return 1; } -JSOBJ NpyArr_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - PRINTMARK(); - return GET_TC(tc)->itemValue; +JSOBJ NpyArr_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + PRINTMARK(); + return GET_TC(tc)->itemValue; } -static void NpyArr_getLabel(JSOBJ obj, JSONTypeContext *tc, size_t *outLen, npy_intp idx, char** labels) -{ - JSONObjectEncoder* enc = (JSONObjectEncoder*) tc->encoder; - PRINTMARK(); - *outLen = strlen(labels[idx]); - memcpy(enc->offset, labels[idx], sizeof(char)*(*outLen)); - enc->offset += *outLen; - *outLen = 0; +static void NpyArr_getLabel(JSOBJ obj, JSONTypeContext *tc, size_t *outLen, + npy_intp idx, char **labels) { + JSONObjectEncoder *enc = (JSONObjectEncoder *)tc->encoder; + PRINTMARK(); + *outLen = strlen(labels[idx]); + memcpy(enc->offset, labels[idx], sizeof(char) * (*outLen)); + enc->offset += *outLen; + *outLen = 0; } -char *NpyArr_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - NpyArrContext* npyarr = GET_TC(tc)->npyarr; - npy_intp idx; - PRINTMARK(); +char *NpyArr_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + NpyArrContext *npyarr = GET_TC(tc)->npyarr; + npy_intp idx; + PRINTMARK(); - if (GET_TC(tc)->iterNext == NpyArr_iterNextItem) - { - idx = npyarr->index[npyarr->stridedim] - 1; - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); - } - else - { - idx = npyarr->index[npyarr->stridedim - npyarr->inc] - 1; - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); - } - return NULL; + if (GET_TC(tc)->iterNext == NpyArr_iterNextItem) { + idx = npyarr->index[npyarr->stridedim] - 1; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); + } else { + idx = npyarr->index[npyarr->stridedim - npyarr->inc] - 1; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); + } + return NULL; } - //============================================================================= // Pandas block iteration functions // @@ -878,442 +784,381 @@ char *NpyArr_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) // Uses a dedicated NpyArrContext for each column. //============================================================================= +void PdBlockPassThru_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + PRINTMARK(); -void PdBlockPassThru_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - PRINTMARK(); - - if (blkCtxt->transpose) - { - blkCtxt->colIdx++; - } - else - { - blkCtxt->colIdx = 0; - } + if (blkCtxt->transpose) { + blkCtxt->colIdx++; + } else { + blkCtxt->colIdx = 0; + } - NpyArr_freeItemValue(obj, tc); + NpyArr_freeItemValue(obj, tc); } -int PdBlock_iterNextItem(JSOBJ obj, JSONTypeContext *tc) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - PRINTMARK(); +int PdBlock_iterNextItem(JSOBJ obj, JSONTypeContext *tc) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + PRINTMARK(); - if (blkCtxt->colIdx >= blkCtxt->ncols) - { - return 0; - } + if (blkCtxt->colIdx >= blkCtxt->ncols) { + return 0; + } - GET_TC(tc)->npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; - blkCtxt->colIdx++; - return NpyArr_iterNextItem(obj, tc); + GET_TC(tc)->npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; + blkCtxt->colIdx++; + return NpyArr_iterNextItem(obj, tc); } -char *PdBlock_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - NpyArrContext *npyarr = blkCtxt->npyCtxts[0]; - npy_intp idx; - PRINTMARK(); - - if (GET_TC(tc)->iterNext == PdBlock_iterNextItem) - { - idx = blkCtxt->colIdx - 1; - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); - } - else - { - idx = GET_TC(tc)->iterNext != PdBlock_iterNext - ? npyarr->index[npyarr->stridedim - npyarr->inc] - 1 - : npyarr->index[npyarr->stridedim]; - - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); - } - return NULL; -} - -char *PdBlock_iterGetName_Transpose(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - NpyArrContext* npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; - npy_intp idx; - PRINTMARK(); - - if (GET_TC(tc)->iterNext == NpyArr_iterNextItem) - { - idx = npyarr->index[npyarr->stridedim] - 1; - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); - } - else - { - idx = blkCtxt->colIdx; - NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); - } - return NULL; -} - -int PdBlock_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - NpyArrContext* npyarr; - PRINTMARK(); - - if (PyErr_Occurred()) - { - return 0; - } - - if (blkCtxt->transpose) - { - if (blkCtxt->colIdx >= blkCtxt->ncols) - { - return 0; - } - } - else - { - npyarr = blkCtxt->npyCtxts[0]; - if (npyarr->index[npyarr->stridedim] >= npyarr->dim) - { - return 0; - } - } +char *PdBlock_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + NpyArrContext *npyarr = blkCtxt->npyCtxts[0]; + npy_intp idx; + PRINTMARK(); - ((PyObjectEncoder*) tc->encoder)->blkCtxtPassthru = blkCtxt; - GET_TC(tc)->itemValue = obj; + if (GET_TC(tc)->iterNext == PdBlock_iterNextItem) { + idx = blkCtxt->colIdx - 1; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); + } else { + idx = GET_TC(tc)->iterNext != PdBlock_iterNext + ? npyarr->index[npyarr->stridedim - npyarr->inc] - 1 + : npyarr->index[npyarr->stridedim]; - return 1; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); + } + return NULL; } -void PdBlockPassThru_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; - PRINTMARK(); - - if (blkCtxt->transpose) - { - // if transposed we exhaust each column before moving to the next - GET_TC(tc)->iterNext = NpyArr_iterNextItem; - GET_TC(tc)->iterGetName = PdBlock_iterGetName_Transpose; - GET_TC(tc)->npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; - } -} +char *PdBlock_iterGetName_Transpose(JSOBJ obj, JSONTypeContext *tc, + size_t *outLen) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + NpyArrContext *npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; + npy_intp idx; + PRINTMARK(); -void PdBlock_iterBegin(JSOBJ _obj, JSONTypeContext *tc) -{ - PyObject *obj, *blocks, *block, *values, *tmp; - PyArrayObject *locs; - PdBlockContext *blkCtxt; - NpyArrContext *npyarr; - Py_ssize_t i; - PyArray_Descr *dtype; - NpyIter *iter; - NpyIter_IterNextFunc *iternext; - npy_int64 **dataptr; - npy_int64 colIdx; - npy_intp idx; - - PRINTMARK(); - - i = 0; - blocks = NULL; - dtype = PyArray_DescrFromType(NPY_INT64); - obj = (PyObject *)_obj; - - GET_TC(tc)->iterGetName = GET_TC(tc)->transpose ? PdBlock_iterGetName_Transpose : PdBlock_iterGetName; - - blkCtxt = PyObject_Malloc(sizeof(PdBlockContext)); - if (!blkCtxt) - { - PyErr_NoMemory(); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - GET_TC(tc)->pdblock = blkCtxt; - - blkCtxt->colIdx = 0; - blkCtxt->transpose = GET_TC(tc)->transpose; - blkCtxt->ncols = get_attr_length(obj, "columns"); - - if (blkCtxt->ncols == 0) - { - blkCtxt->npyCtxts = NULL; - blkCtxt->cindices = NULL; - - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - - blkCtxt->npyCtxts = PyObject_Malloc(sizeof(NpyArrContext*) * blkCtxt->ncols); - if (!blkCtxt->npyCtxts) - { - PyErr_NoMemory(); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - for (i = 0; i < blkCtxt->ncols; i++) - { - blkCtxt->npyCtxts[i] = NULL; - } - - blkCtxt->cindices = PyObject_Malloc(sizeof(int) * blkCtxt->ncols); - if (!blkCtxt->cindices) - { - PyErr_NoMemory(); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - - blocks = get_sub_attr(obj, "_data", "blocks"); - if (!blocks) - { - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - - // force transpose so each NpyArrContext strides down its column - GET_TC(tc)->transpose = 1; - - for (i = 0; i < PyObject_Length(blocks); i++) - { - block = get_item(blocks, i); - if (!block) - { - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; + if (GET_TC(tc)->iterNext == NpyArr_iterNextItem) { + idx = npyarr->index[npyarr->stridedim] - 1; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->columnLabels); + } else { + idx = blkCtxt->colIdx; + NpyArr_getLabel(obj, tc, outLen, idx, npyarr->rowLabels); } + return NULL; +} - tmp = get_values(block); - if (!tmp) - { - ((JSONObjectEncoder*) tc->encoder)->errorMsg = ""; - Py_DECREF(block); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } +int PdBlock_iterNext(JSOBJ obj, JSONTypeContext *tc) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + NpyArrContext *npyarr; + PRINTMARK(); - values = PyArray_Transpose((PyArrayObject*) tmp, NULL); - Py_DECREF(tmp); - if (!values) - { - Py_DECREF(block); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; + if (PyErr_Occurred()) { + return 0; } - - locs = (PyArrayObject*) get_sub_attr(block, "mgr_locs", "as_array"); - if (!locs) - { - Py_DECREF(block); - Py_DECREF(values); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; + if (blkCtxt->transpose) { + if (blkCtxt->colIdx >= blkCtxt->ncols) { + return 0; + } + } else { + npyarr = blkCtxt->npyCtxts[0]; + if (npyarr->index[npyarr->stridedim] >= npyarr->dim) { + return 0; + } } - iter = NpyIter_New(locs, NPY_ITER_READONLY, NPY_KEEPORDER, NPY_NO_CASTING, dtype); - if (!iter) - { - Py_DECREF(block); - Py_DECREF(values); - Py_DECREF(locs); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - iternext = NpyIter_GetIterNext(iter, NULL); - if (!iternext) - { - NpyIter_Deallocate(iter); - Py_DECREF(block); - Py_DECREF(values); - Py_DECREF(locs); - GET_TC(tc)->iterNext = NpyArr_iterNextNone; - goto BLKRET; - } - dataptr = (npy_int64 **) NpyIter_GetDataPtrArray(iter); - do - { - colIdx = **dataptr; - idx = NpyIter_GetIterIndex(iter); + ((PyObjectEncoder *)tc->encoder)->blkCtxtPassthru = blkCtxt; + GET_TC(tc)->itemValue = obj; - blkCtxt->cindices[colIdx] = idx; + return 1; +} - // Reference freed in Pdblock_iterend - Py_INCREF(values); - GET_TC(tc)->newObj = values; +void PdBlockPassThru_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + PdBlockContext *blkCtxt = GET_TC(tc)->pdblock; + PRINTMARK(); - // init a dedicated context for this column - NpyArr_iterBegin(obj, tc); - npyarr = GET_TC(tc)->npyarr; + if (blkCtxt->transpose) { + // if transposed we exhaust each column before moving to the next + GET_TC(tc)->iterNext = NpyArr_iterNextItem; + GET_TC(tc)->iterGetName = PdBlock_iterGetName_Transpose; + GET_TC(tc)->npyarr = blkCtxt->npyCtxts[blkCtxt->colIdx]; + } +} - // set the dataptr to our desired column and initialise - if (npyarr != NULL) - { - npyarr->dataptr += npyarr->stride * idx; - NpyArr_iterNext(obj, tc); +void PdBlock_iterBegin(JSOBJ _obj, JSONTypeContext *tc) { + PyObject *obj, *blocks, *block, *values, *tmp; + PyArrayObject *locs; + PdBlockContext *blkCtxt; + NpyArrContext *npyarr; + Py_ssize_t i; + PyArray_Descr *dtype; + NpyIter *iter; + NpyIter_IterNextFunc *iternext; + npy_int64 **dataptr; + npy_int64 colIdx; + npy_intp idx; + + PRINTMARK(); + + i = 0; + blocks = NULL; + dtype = PyArray_DescrFromType(NPY_INT64); + obj = (PyObject *)_obj; + + GET_TC(tc) + ->iterGetName = GET_TC(tc)->transpose ? PdBlock_iterGetName_Transpose + : PdBlock_iterGetName; + + blkCtxt = PyObject_Malloc(sizeof(PdBlockContext)); + if (!blkCtxt) { + PyErr_NoMemory(); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + GET_TC(tc)->pdblock = blkCtxt; + + blkCtxt->colIdx = 0; + blkCtxt->transpose = GET_TC(tc)->transpose; + blkCtxt->ncols = get_attr_length(obj, "columns"); + + if (blkCtxt->ncols == 0) { + blkCtxt->npyCtxts = NULL; + blkCtxt->cindices = NULL; + + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + + blkCtxt->npyCtxts = + PyObject_Malloc(sizeof(NpyArrContext *) * blkCtxt->ncols); + if (!blkCtxt->npyCtxts) { + PyErr_NoMemory(); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + for (i = 0; i < blkCtxt->ncols; i++) { + blkCtxt->npyCtxts[i] = NULL; + } + + blkCtxt->cindices = PyObject_Malloc(sizeof(int) * blkCtxt->ncols); + if (!blkCtxt->cindices) { + PyErr_NoMemory(); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + + blocks = get_sub_attr(obj, "_data", "blocks"); + if (!blocks) { + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + + // force transpose so each NpyArrContext strides down its column + GET_TC(tc)->transpose = 1; + + for (i = 0; i < PyObject_Length(blocks); i++) { + block = get_item(blocks, i); + if (!block) { + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; } - GET_TC(tc)->itemValue = NULL; - ((PyObjectEncoder*) tc->encoder)->npyCtxtPassthru = NULL; - blkCtxt->npyCtxts[colIdx] = npyarr; - GET_TC(tc)->newObj = NULL; + tmp = get_values(block); + if (!tmp) { + ((JSONObjectEncoder *)tc->encoder)->errorMsg = ""; + Py_DECREF(block); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + + values = PyArray_Transpose((PyArrayObject *)tmp, NULL); + Py_DECREF(tmp); + if (!values) { + Py_DECREF(block); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } - } while (iternext(iter)); + locs = (PyArrayObject *)get_sub_attr(block, "mgr_locs", "as_array"); + if (!locs) { + Py_DECREF(block); + Py_DECREF(values); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + + iter = NpyIter_New(locs, NPY_ITER_READONLY, NPY_KEEPORDER, + NPY_NO_CASTING, dtype); + if (!iter) { + Py_DECREF(block); + Py_DECREF(values); + Py_DECREF(locs); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + iternext = NpyIter_GetIterNext(iter, NULL); + if (!iternext) { + NpyIter_Deallocate(iter); + Py_DECREF(block); + Py_DECREF(values); + Py_DECREF(locs); + GET_TC(tc)->iterNext = NpyArr_iterNextNone; + goto BLKRET; + } + dataptr = (npy_int64 **)NpyIter_GetDataPtrArray(iter); + do { + colIdx = **dataptr; + idx = NpyIter_GetIterIndex(iter); + + blkCtxt->cindices[colIdx] = idx; + + // Reference freed in Pdblock_iterend + Py_INCREF(values); + GET_TC(tc)->newObj = values; + + // init a dedicated context for this column + NpyArr_iterBegin(obj, tc); + npyarr = GET_TC(tc)->npyarr; + + // set the dataptr to our desired column and initialise + if (npyarr != NULL) { + npyarr->dataptr += npyarr->stride * idx; + NpyArr_iterNext(obj, tc); + } + GET_TC(tc)->itemValue = NULL; + ((PyObjectEncoder *)tc->encoder)->npyCtxtPassthru = NULL; - NpyIter_Deallocate(iter); - Py_DECREF(block); - Py_DECREF(values); - Py_DECREF(locs); - } - GET_TC(tc)->npyarr = blkCtxt->npyCtxts[0]; + blkCtxt->npyCtxts[colIdx] = npyarr; + GET_TC(tc)->newObj = NULL; + } while (iternext(iter)); + + NpyIter_Deallocate(iter); + Py_DECREF(block); + Py_DECREF(values); + Py_DECREF(locs); + } + GET_TC(tc)->npyarr = blkCtxt->npyCtxts[0]; BLKRET: - Py_XDECREF(dtype); - Py_XDECREF(blocks); + Py_XDECREF(dtype); + Py_XDECREF(blocks); } -void PdBlock_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - PdBlockContext *blkCtxt; - NpyArrContext *npyarr; - int i; - PRINTMARK(); +void PdBlock_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + PdBlockContext *blkCtxt; + NpyArrContext *npyarr; + int i; + PRINTMARK(); - GET_TC(tc)->itemValue = NULL; - npyarr = GET_TC(tc)->npyarr; + GET_TC(tc)->itemValue = NULL; + npyarr = GET_TC(tc)->npyarr; - blkCtxt = GET_TC(tc)->pdblock; + blkCtxt = GET_TC(tc)->pdblock; - if (blkCtxt) - { - for (i = 0; i < blkCtxt->ncols; i++) - { - npyarr = blkCtxt->npyCtxts[i]; - if (npyarr) - { - if (npyarr->array) - { - Py_DECREF(npyarr->array); - npyarr->array = NULL; - } + if (blkCtxt) { + for (i = 0; i < blkCtxt->ncols; i++) { + npyarr = blkCtxt->npyCtxts[i]; + if (npyarr) { + if (npyarr->array) { + Py_DECREF(npyarr->array); + npyarr->array = NULL; + } - GET_TC(tc)->npyarr = npyarr; - NpyArr_iterEnd(obj, tc); + GET_TC(tc)->npyarr = npyarr; + NpyArr_iterEnd(obj, tc); - blkCtxt->npyCtxts[i] = NULL; - } - } + blkCtxt->npyCtxts[i] = NULL; + } + } - if (blkCtxt->npyCtxts) - { - PyObject_Free(blkCtxt->npyCtxts); - } - if (blkCtxt->cindices) - { - PyObject_Free(blkCtxt->cindices); + if (blkCtxt->npyCtxts) { + PyObject_Free(blkCtxt->npyCtxts); + } + if (blkCtxt->cindices) { + PyObject_Free(blkCtxt->cindices); + } + PyObject_Free(blkCtxt); } - PyObject_Free(blkCtxt); - } } - //============================================================================= // Tuple iteration functions // itemValue is borrowed reference, no ref counting //============================================================================= -void Tuple_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->index = 0; - GET_TC(tc)->size = PyTuple_GET_SIZE( (PyObject *) obj); - GET_TC(tc)->itemValue = NULL; +void Tuple_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->index = 0; + GET_TC(tc)->size = PyTuple_GET_SIZE((PyObject *)obj); + GET_TC(tc)->itemValue = NULL; } -int Tuple_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - PyObject *item; +int Tuple_iterNext(JSOBJ obj, JSONTypeContext *tc) { + PyObject *item; - if (GET_TC(tc)->index >= GET_TC(tc)->size) - { - return 0; - } + if (GET_TC(tc)->index >= GET_TC(tc)->size) { + return 0; + } - item = PyTuple_GET_ITEM (obj, GET_TC(tc)->index); + item = PyTuple_GET_ITEM(obj, GET_TC(tc)->index); - GET_TC(tc)->itemValue = item; - GET_TC(tc)->index ++; - return 1; + GET_TC(tc)->itemValue = item; + GET_TC(tc)->index++; + return 1; } -void Tuple_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ -} +void Tuple_iterEnd(JSOBJ obj, JSONTypeContext *tc) {} -JSOBJ Tuple_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ Tuple_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *Tuple_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - return NULL; +char *Tuple_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + return NULL; } //============================================================================= // Iterator iteration functions // itemValue is borrowed reference, no ref counting //============================================================================= -void Iter_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->itemValue = NULL; - GET_TC(tc)->iterator = PyObject_GetIter(obj); +void Iter_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->itemValue = NULL; + GET_TC(tc)->iterator = PyObject_GetIter(obj); } -int Iter_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - PyObject *item; +int Iter_iterNext(JSOBJ obj, JSONTypeContext *tc) { + PyObject *item; - if (GET_TC(tc)->itemValue) - { - Py_DECREF(GET_TC(tc)->itemValue); - GET_TC(tc)->itemValue = NULL; - } + if (GET_TC(tc)->itemValue) { + Py_DECREF(GET_TC(tc)->itemValue); + GET_TC(tc)->itemValue = NULL; + } - item = PyIter_Next(GET_TC(tc)->iterator); + item = PyIter_Next(GET_TC(tc)->iterator); - if (item == NULL) - { - return 0; - } + if (item == NULL) { + return 0; + } - GET_TC(tc)->itemValue = item; - return 1; + GET_TC(tc)->itemValue = item; + return 1; } -void Iter_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - if (GET_TC(tc)->itemValue) - { - Py_DECREF(GET_TC(tc)->itemValue); - GET_TC(tc)->itemValue = NULL; - } +void Iter_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + if (GET_TC(tc)->itemValue) { + Py_DECREF(GET_TC(tc)->itemValue); + GET_TC(tc)->itemValue = NULL; + } - if (GET_TC(tc)->iterator) - { - Py_DECREF(GET_TC(tc)->iterator); - GET_TC(tc)->iterator = NULL; - } + if (GET_TC(tc)->iterator) { + Py_DECREF(GET_TC(tc)->iterator); + GET_TC(tc)->iterator = NULL; + } } -JSOBJ Iter_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ Iter_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *Iter_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - return NULL; +char *Iter_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + return NULL; } //============================================================================= @@ -1321,387 +1166,312 @@ char *Iter_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) // itemName ref is borrowed from PyObject_Dir (attrList). No refcount // itemValue ref is from PyObject_GetAttr. Ref counted //============================================================================= -void Dir_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->attrList = PyObject_Dir(obj); - GET_TC(tc)->index = 0; - GET_TC(tc)->size = PyList_GET_SIZE(GET_TC(tc)->attrList); - PRINTMARK(); +void Dir_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->attrList = PyObject_Dir(obj); + GET_TC(tc)->index = 0; + GET_TC(tc)->size = PyList_GET_SIZE(GET_TC(tc)->attrList); + PRINTMARK(); } -void Dir_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - if (GET_TC(tc)->itemValue) - { - Py_DECREF(GET_TC(tc)->itemValue); - GET_TC(tc)->itemValue = NULL; - } +void Dir_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + if (GET_TC(tc)->itemValue) { + Py_DECREF(GET_TC(tc)->itemValue); + GET_TC(tc)->itemValue = NULL; + } - if (GET_TC(tc)->itemName) - { - Py_DECREF(GET_TC(tc)->itemName); - GET_TC(tc)->itemName = NULL; - } + if (GET_TC(tc)->itemName) { + Py_DECREF(GET_TC(tc)->itemName); + GET_TC(tc)->itemName = NULL; + } - Py_DECREF( (PyObject *) GET_TC(tc)->attrList); - PRINTMARK(); + Py_DECREF((PyObject *)GET_TC(tc)->attrList); + PRINTMARK(); } -int Dir_iterNext(JSOBJ _obj, JSONTypeContext *tc) -{ - PyObject *obj = (PyObject *) _obj; - PyObject *itemValue = GET_TC(tc)->itemValue; - PyObject *itemName = GET_TC(tc)->itemName; - PyObject* attr; - PyObject* attrName; - char* attrStr; - - if (itemValue) - { - Py_DECREF(GET_TC(tc)->itemValue); - GET_TC(tc)->itemValue = itemValue = NULL; - } - - if (itemName) - { - Py_DECREF(GET_TC(tc)->itemName); - GET_TC(tc)->itemName = itemName = NULL; - } - - for (; GET_TC(tc)->index < GET_TC(tc)->size; GET_TC(tc)->index ++) - { - attrName = PyList_GET_ITEM(GET_TC(tc)->attrList, GET_TC(tc)->index); +int Dir_iterNext(JSOBJ _obj, JSONTypeContext *tc) { + PyObject *obj = (PyObject *)_obj; + PyObject *itemValue = GET_TC(tc)->itemValue; + PyObject *itemName = GET_TC(tc)->itemName; + PyObject *attr; + PyObject *attrName; + char *attrStr; + + if (itemValue) { + Py_DECREF(GET_TC(tc)->itemValue); + GET_TC(tc)->itemValue = itemValue = NULL; + } + + if (itemName) { + Py_DECREF(GET_TC(tc)->itemName); + GET_TC(tc)->itemName = itemName = NULL; + } + + for (; GET_TC(tc)->index < GET_TC(tc)->size; GET_TC(tc)->index++) { + attrName = PyList_GET_ITEM(GET_TC(tc)->attrList, GET_TC(tc)->index); #if PY_MAJOR_VERSION >= 3 - attr = PyUnicode_AsUTF8String(attrName); + attr = PyUnicode_AsUTF8String(attrName); #else - attr = attrName; - Py_INCREF(attr); + attr = attrName; + Py_INCREF(attr); #endif - attrStr = PyString_AS_STRING(attr); + attrStr = PyString_AS_STRING(attr); - if (attrStr[0] == '_') - { - PRINTMARK(); - Py_DECREF(attr); - continue; - } + if (attrStr[0] == '_') { + PRINTMARK(); + Py_DECREF(attr); + continue; + } - itemValue = PyObject_GetAttr(obj, attrName); - if (itemValue == NULL) - { - PyErr_Clear(); - Py_DECREF(attr); - PRINTMARK(); - continue; + itemValue = PyObject_GetAttr(obj, attrName); + if (itemValue == NULL) { + PyErr_Clear(); + Py_DECREF(attr); + PRINTMARK(); + continue; + } + + if (PyCallable_Check(itemValue)) { + Py_DECREF(itemValue); + Py_DECREF(attr); + PRINTMARK(); + continue; + } + + GET_TC(tc)->itemName = itemName; + GET_TC(tc)->itemValue = itemValue; + GET_TC(tc)->index++; + + PRINTMARK(); + itemName = attr; + break; } - if (PyCallable_Check(itemValue)) - { - Py_DECREF(itemValue); - Py_DECREF(attr); - PRINTMARK(); - continue; + if (itemName == NULL) { + GET_TC(tc)->index = GET_TC(tc)->size; + GET_TC(tc)->itemValue = NULL; + return 0; } GET_TC(tc)->itemName = itemName; GET_TC(tc)->itemValue = itemValue; - GET_TC(tc)->index ++; + GET_TC(tc)->index++; PRINTMARK(); - itemName = attr; - break; - } - - if (itemName == NULL) - { - GET_TC(tc)->index = GET_TC(tc)->size; - GET_TC(tc)->itemValue = NULL; - return 0; - } - - GET_TC(tc)->itemName = itemName; - GET_TC(tc)->itemValue = itemValue; - GET_TC(tc)->index ++; - - PRINTMARK(); - return 1; + return 1; } -JSOBJ Dir_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - PRINTMARK(); - return GET_TC(tc)->itemValue; +JSOBJ Dir_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + PRINTMARK(); + return GET_TC(tc)->itemValue; } -char *Dir_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - PRINTMARK(); - *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName); - return PyString_AS_STRING(GET_TC(tc)->itemName); +char *Dir_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + PRINTMARK(); + *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName); + return PyString_AS_STRING(GET_TC(tc)->itemName); } - //============================================================================= // List iteration functions // itemValue is borrowed from object (which is list). No refcounting //============================================================================= -void List_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->index = 0; - GET_TC(tc)->size = PyList_GET_SIZE( (PyObject *) obj); +void List_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->index = 0; + GET_TC(tc)->size = PyList_GET_SIZE((PyObject *)obj); } -int List_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - if (GET_TC(tc)->index >= GET_TC(tc)->size) - { - PRINTMARK(); - return 0; - } +int List_iterNext(JSOBJ obj, JSONTypeContext *tc) { + if (GET_TC(tc)->index >= GET_TC(tc)->size) { + PRINTMARK(); + return 0; + } - GET_TC(tc)->itemValue = PyList_GET_ITEM (obj, GET_TC(tc)->index); - GET_TC(tc)->index ++; - return 1; + GET_TC(tc)->itemValue = PyList_GET_ITEM(obj, GET_TC(tc)->index); + GET_TC(tc)->index++; + return 1; } -void List_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ -} +void List_iterEnd(JSOBJ obj, JSONTypeContext *tc) {} -JSOBJ List_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ List_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *List_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - return NULL; +char *List_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + return NULL; } //============================================================================= // pandas Index iteration functions //============================================================================= -void Index_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->index = 0; - GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); - if (!GET_TC(tc)->cStr) - { - PyErr_NoMemory(); - } - PRINTMARK(); +void Index_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->index = 0; + GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); + if (!GET_TC(tc)->cStr) { + PyErr_NoMemory(); + } + PRINTMARK(); } -int Index_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - Py_ssize_t index; - if (!GET_TC(tc)->cStr) - { - return 0; - } - - index = GET_TC(tc)->index; - Py_XDECREF(GET_TC(tc)->itemValue); - if (index == 0) - { - memcpy(GET_TC(tc)->cStr, "name", sizeof(char)*5); - GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "name"); - } - else - if (index == 1) - { - memcpy(GET_TC(tc)->cStr, "data", sizeof(char)*5); - GET_TC(tc)->itemValue = get_values(obj); - if (!GET_TC(tc)->itemValue) - { - return 0; +int Index_iterNext(JSOBJ obj, JSONTypeContext *tc) { + Py_ssize_t index; + if (!GET_TC(tc)->cStr) { + return 0; } - } - else - { - PRINTMARK(); - return 0; - } - GET_TC(tc)->index++; - PRINTMARK(); - return 1; -} + index = GET_TC(tc)->index; + Py_XDECREF(GET_TC(tc)->itemValue); + if (index == 0) { + memcpy(GET_TC(tc)->cStr, "name", sizeof(char) * 5); + GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "name"); + } else if (index == 1) { + memcpy(GET_TC(tc)->cStr, "data", sizeof(char) * 5); + GET_TC(tc)->itemValue = get_values(obj); + if (!GET_TC(tc)->itemValue) { + return 0; + } + } else { + PRINTMARK(); + return 0; + } -void Index_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - PRINTMARK(); + GET_TC(tc)->index++; + PRINTMARK(); + return 1; } -JSOBJ Index_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +void Index_iterEnd(JSOBJ obj, JSONTypeContext *tc) { PRINTMARK(); } + +JSOBJ Index_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *Index_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - *outLen = strlen(GET_TC(tc)->cStr); - return GET_TC(tc)->cStr; +char *Index_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + *outLen = strlen(GET_TC(tc)->cStr); + return GET_TC(tc)->cStr; } //============================================================================= // pandas Series iteration functions //============================================================================= -void Series_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - PyObjectEncoder* enc = (PyObjectEncoder*) tc->encoder; - GET_TC(tc)->index = 0; - GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); - enc->outputFormat = VALUES; // for contained series - if (!GET_TC(tc)->cStr) - { - PyErr_NoMemory(); - } - PRINTMARK(); -} - -int Series_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - Py_ssize_t index; - if (!GET_TC(tc)->cStr) - { - return 0; - } - - index = GET_TC(tc)->index; - Py_XDECREF(GET_TC(tc)->itemValue); - if (index == 0) - { - memcpy(GET_TC(tc)->cStr, "name", sizeof(char)*5); - GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "name"); - } - else - if (index == 1) - { - memcpy(GET_TC(tc)->cStr, "index", sizeof(char)*6); - GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "index"); - } - else - if (index == 2) - { - memcpy(GET_TC(tc)->cStr, "data", sizeof(char)*5); - GET_TC(tc)->itemValue = get_values(obj); - if (!GET_TC(tc)->itemValue) - { - return 0; +void Series_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + PyObjectEncoder *enc = (PyObjectEncoder *)tc->encoder; + GET_TC(tc)->index = 0; + GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); + enc->outputFormat = VALUES; // for contained series + if (!GET_TC(tc)->cStr) { + PyErr_NoMemory(); } - } - else - { PRINTMARK(); - return 0; - } +} + +int Series_iterNext(JSOBJ obj, JSONTypeContext *tc) { + Py_ssize_t index; + if (!GET_TC(tc)->cStr) { + return 0; + } + + index = GET_TC(tc)->index; + Py_XDECREF(GET_TC(tc)->itemValue); + if (index == 0) { + memcpy(GET_TC(tc)->cStr, "name", sizeof(char) * 5); + GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "name"); + } else if (index == 1) { + memcpy(GET_TC(tc)->cStr, "index", sizeof(char) * 6); + GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "index"); + } else if (index == 2) { + memcpy(GET_TC(tc)->cStr, "data", sizeof(char) * 5); + GET_TC(tc)->itemValue = get_values(obj); + if (!GET_TC(tc)->itemValue) { + return 0; + } + } else { + PRINTMARK(); + return 0; + } - GET_TC(tc)->index++; - PRINTMARK(); - return 1; + GET_TC(tc)->index++; + PRINTMARK(); + return 1; } -void Series_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - PyObjectEncoder* enc = (PyObjectEncoder*) tc->encoder; - enc->outputFormat = enc->originalOutputFormat; - PRINTMARK(); +void Series_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + PyObjectEncoder *enc = (PyObjectEncoder *)tc->encoder; + enc->outputFormat = enc->originalOutputFormat; + PRINTMARK(); } -JSOBJ Series_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ Series_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *Series_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - *outLen = strlen(GET_TC(tc)->cStr); - return GET_TC(tc)->cStr; +char *Series_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + *outLen = strlen(GET_TC(tc)->cStr); + return GET_TC(tc)->cStr; } //============================================================================= // pandas DataFrame iteration functions //============================================================================= -void DataFrame_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - PyObjectEncoder* enc = (PyObjectEncoder*) tc->encoder; - GET_TC(tc)->index = 0; - GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); - enc->outputFormat = VALUES; // for contained series & index - if (!GET_TC(tc)->cStr) - { - PyErr_NoMemory(); - } - PRINTMARK(); -} - -int DataFrame_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - Py_ssize_t index; - if (!GET_TC(tc)->cStr) - { - return 0; - } - - index = GET_TC(tc)->index; - Py_XDECREF(GET_TC(tc)->itemValue); - if (index == 0) - { - memcpy(GET_TC(tc)->cStr, "columns", sizeof(char)*8); - GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "columns"); - } - else - if (index == 1) - { - memcpy(GET_TC(tc)->cStr, "index", sizeof(char)*6); - GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "index"); - } - else - if (index == 2) - { - memcpy(GET_TC(tc)->cStr, "data", sizeof(char)*5); - if (is_simple_frame(obj)) - { - GET_TC(tc)->itemValue = get_values(obj); - if (!GET_TC(tc)->itemValue) - { +void DataFrame_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + PyObjectEncoder *enc = (PyObjectEncoder *)tc->encoder; + GET_TC(tc)->index = 0; + GET_TC(tc)->cStr = PyObject_Malloc(20 * sizeof(char)); + enc->outputFormat = VALUES; // for contained series & index + if (!GET_TC(tc)->cStr) { + PyErr_NoMemory(); + } + PRINTMARK(); +} + +int DataFrame_iterNext(JSOBJ obj, JSONTypeContext *tc) { + Py_ssize_t index; + if (!GET_TC(tc)->cStr) { return 0; - } } - else - { - Py_INCREF(obj); - GET_TC(tc)->itemValue = obj; + + index = GET_TC(tc)->index; + Py_XDECREF(GET_TC(tc)->itemValue); + if (index == 0) { + memcpy(GET_TC(tc)->cStr, "columns", sizeof(char) * 8); + GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "columns"); + } else if (index == 1) { + memcpy(GET_TC(tc)->cStr, "index", sizeof(char) * 6); + GET_TC(tc)->itemValue = PyObject_GetAttrString(obj, "index"); + } else if (index == 2) { + memcpy(GET_TC(tc)->cStr, "data", sizeof(char) * 5); + if (is_simple_frame(obj)) { + GET_TC(tc)->itemValue = get_values(obj); + if (!GET_TC(tc)->itemValue) { + return 0; + } + } else { + Py_INCREF(obj); + GET_TC(tc)->itemValue = obj; + } + } else { + PRINTMARK(); + return 0; } - } - else - { - PRINTMARK(); - return 0; - } - GET_TC(tc)->index++; - PRINTMARK(); - return 1; + GET_TC(tc)->index++; + PRINTMARK(); + return 1; } -void DataFrame_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - PyObjectEncoder* enc = (PyObjectEncoder*) tc->encoder; - enc->outputFormat = enc->originalOutputFormat; - PRINTMARK(); +void DataFrame_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + PyObjectEncoder *enc = (PyObjectEncoder *)tc->encoder; + enc->outputFormat = enc->originalOutputFormat; + PRINTMARK(); } -JSOBJ DataFrame_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ DataFrame_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *DataFrame_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - *outLen = strlen(GET_TC(tc)->cStr); - return GET_TC(tc)->cStr; +char *DataFrame_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + *outLen = strlen(GET_TC(tc)->cStr); + return GET_TC(tc)->cStr; } //============================================================================= @@ -1709,124 +1479,105 @@ char *DataFrame_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) // itemName might converted to string (Python_Str). Do refCounting // itemValue is borrowed from object (which is dict). No refCounting //============================================================================= -void Dict_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->index = 0; - PRINTMARK(); +void Dict_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->index = 0; + PRINTMARK(); } -int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ +int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc) { #if PY_MAJOR_VERSION >= 3 - PyObject* itemNameTmp; + PyObject *itemNameTmp; #endif - if (GET_TC(tc)->itemName) - { - Py_DECREF(GET_TC(tc)->itemName); - GET_TC(tc)->itemName = NULL; - } + if (GET_TC(tc)->itemName) { + Py_DECREF(GET_TC(tc)->itemName); + GET_TC(tc)->itemName = NULL; + } + if (!PyDict_Next((PyObject *)GET_TC(tc)->dictObj, &GET_TC(tc)->index, + &GET_TC(tc)->itemName, &GET_TC(tc)->itemValue)) { + PRINTMARK(); + return 0; + } - if (!PyDict_Next ( (PyObject *)GET_TC(tc)->dictObj, &GET_TC(tc)->index, &GET_TC(tc)->itemName, &GET_TC(tc)->itemValue)) - { - PRINTMARK(); - return 0; - } - - if (PyUnicode_Check(GET_TC(tc)->itemName)) - { - GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName); - } - else - if (!PyString_Check(GET_TC(tc)->itemName)) - { - GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName); + if (PyUnicode_Check(GET_TC(tc)->itemName)) { + GET_TC(tc)->itemName = PyUnicode_AsUTF8String(GET_TC(tc)->itemName); + } else if (!PyString_Check(GET_TC(tc)->itemName)) { + GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName); #if PY_MAJOR_VERSION >= 3 - itemNameTmp = GET_TC(tc)->itemName; - GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName); - Py_DECREF(itemNameTmp); + itemNameTmp = GET_TC(tc)->itemName; + GET_TC(tc)->itemName = PyUnicode_AsUTF8String(GET_TC(tc)->itemName); + Py_DECREF(itemNameTmp); #endif - } - else - { - Py_INCREF(GET_TC(tc)->itemName); + } else { + Py_INCREF(GET_TC(tc)->itemName); } PRINTMARK(); return 1; } -void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - if (GET_TC(tc)->itemName) - { - Py_DECREF(GET_TC(tc)->itemName); - GET_TC(tc)->itemName = NULL; - } - Py_DECREF(GET_TC(tc)->dictObj); - PRINTMARK(); +void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + if (GET_TC(tc)->itemName) { + Py_DECREF(GET_TC(tc)->itemName); + GET_TC(tc)->itemName = NULL; + } + Py_DECREF(GET_TC(tc)->dictObj); + PRINTMARK(); } -JSOBJ Dict_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->itemValue; +JSOBJ Dict_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->itemValue; } -char *Dict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName); - return PyString_AS_STRING(GET_TC(tc)->itemName); +char *Dict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName); + return PyString_AS_STRING(GET_TC(tc)->itemName); } -void NpyArr_freeLabels(char** labels, npy_intp len) -{ +void NpyArr_freeLabels(char **labels, npy_intp len) { npy_intp i; - if (labels) - { - for (i = 0; i < len; i++) - { + if (labels) { + for (i = 0; i < len; i++) { PyObject_Free(labels[i]); } PyObject_Free(labels); } } -char** NpyArr_encodeLabels(PyArrayObject* labels, JSONObjectEncoder* enc, npy_intp num) -{ +char **NpyArr_encodeLabels(PyArrayObject *labels, JSONObjectEncoder *enc, + npy_intp num) { // NOTE this function steals a reference to labels. - PyObjectEncoder* pyenc = (PyObjectEncoder *) enc; - PyObject* item = NULL; + PyObjectEncoder *pyenc = (PyObjectEncoder *)enc; + PyObject *item = NULL; npy_intp i, stride, len, need_quotes; - char** ret; + char **ret; char *dataptr, *cLabel, *origend, *origst, *origoffset; char labelBuffer[NPY_JSON_BUFSIZE]; - PyArray_GetItemFunc* getitem; + PyArray_GetItemFunc *getitem; int type_num; PRINTMARK(); - if (!labels) - { - return 0; + if (!labels) { + return 0; } - if (PyArray_SIZE(labels) < num) - { - PyErr_SetString(PyExc_ValueError, "Label array sizes do not match corresponding data shape"); + if (PyArray_SIZE(labels) < num) { + PyErr_SetString( + PyExc_ValueError, + "Label array sizes do not match corresponding data shape"); Py_DECREF(labels); return 0; } - ret = PyObject_Malloc(sizeof(char*)*num); - if (!ret) - { + ret = PyObject_Malloc(sizeof(char *) * num); + if (!ret) { PyErr_NoMemory(); Py_DECREF(labels); return 0; } - for (i = 0; i < num; i++) - { + for (i = 0; i < num; i++) { ret[i] = NULL; } @@ -1836,45 +1587,37 @@ char** NpyArr_encodeLabels(PyArrayObject* labels, JSONObjectEncoder* enc, npy_in stride = PyArray_STRIDE(labels, 0); dataptr = PyArray_DATA(labels); - getitem = (PyArray_GetItemFunc*) PyArray_DESCR(labels)->f->getitem; + getitem = (PyArray_GetItemFunc *)PyArray_DESCR(labels)->f->getitem; type_num = PyArray_TYPE(labels); - for (i = 0; i < num; i++) - { + for (i = 0; i < num; i++) { #if NPY_API_VERSION < 0x00000007 - if(PyTypeNum_ISDATETIME(type_num)) - { - item = PyArray_ToScalar(dataptr, labels); - } - else if(PyTypeNum_ISNUMBER(type_num)) + if (PyTypeNum_ISDATETIME(type_num)) { + item = PyArray_ToScalar(dataptr, labels); + } else if (PyTypeNum_ISNUMBER(type_num)) // NOLINT #else - if(PyTypeNum_ISDATETIME(type_num) || PyTypeNum_ISNUMBER(type_num)) + if (PyTypeNum_ISDATETIME(type_num) || PyTypeNum_ISNUMBER(type_num)) // NOLINT #endif { - item = (PyObject *) labels; - pyenc->npyType = type_num; - pyenc->npyValue = dataptr; - } - else - { - item = getitem(dataptr, labels); - if (!item) - { - NpyArr_freeLabels(ret, num); - ret = 0; - break; - } + item = (PyObject *)labels; + pyenc->npyType = type_num; + pyenc->npyValue = dataptr; + } else { + item = getitem(dataptr, labels); + if (!item) { + NpyArr_freeLabels(ret, num); + ret = 0; + break; + } } cLabel = JSON_EncodeObject(item, enc, labelBuffer, NPY_JSON_BUFSIZE); - if (item != (PyObject *) labels) - { - Py_DECREF(item); + if (item != (PyObject *)labels) { + Py_DECREF(item); } - if (PyErr_Occurred() || enc->errorMsg) - { + if (PyErr_Occurred() || enc->errorMsg) { NpyArr_freeLabels(ret, num); ret = 0; break; @@ -1882,27 +1625,23 @@ char** NpyArr_encodeLabels(PyArrayObject* labels, JSONObjectEncoder* enc, npy_in need_quotes = ((*cLabel) != '"'); len = enc->offset - cLabel + 1 + 2 * need_quotes; - ret[i] = PyObject_Malloc(sizeof(char)*len); + ret[i] = PyObject_Malloc(sizeof(char) * len); - if (!ret[i]) - { + if (!ret[i]) { PyErr_NoMemory(); ret = 0; break; } - if (need_quotes) - { - ret[i][0] = '"'; - memcpy(ret[i]+1, cLabel, sizeof(char)*(len-4)); - ret[i][len-3] = '"'; - } - else - { - memcpy(ret[i], cLabel, sizeof(char)*(len-2)); + if (need_quotes) { + ret[i][0] = '"'; + memcpy(ret[i] + 1, cLabel, sizeof(char) * (len - 4)); + ret[i][len - 3] = '"'; + } else { + memcpy(ret[i], cLabel, sizeof(char) * (len - 2)); } - ret[i][len-2] = ':'; - ret[i][len-1] = '\0'; + ret[i][len - 2] = ':'; + ret[i][len - 1] = '\0'; dataptr += stride; } @@ -1914,772 +1653,650 @@ char** NpyArr_encodeLabels(PyArrayObject* labels, JSONObjectEncoder* enc, npy_in return ret; } -void Object_invokeDefaultHandler(PyObject *obj, PyObjectEncoder *enc) -{ - PyObject *tmpObj = NULL; - PRINTMARK(); - tmpObj = PyObject_CallFunctionObjArgs(enc->defaultHandler, obj, NULL); - if (!PyErr_Occurred()) - { - if (tmpObj == NULL) - { - PyErr_SetString(PyExc_TypeError, "Failed to execute default handler"); - } - else - { - encode (tmpObj, (JSONObjectEncoder*) enc, NULL, 0); +void Object_invokeDefaultHandler(PyObject *obj, PyObjectEncoder *enc) { + PyObject *tmpObj = NULL; + PRINTMARK(); + tmpObj = PyObject_CallFunctionObjArgs(enc->defaultHandler, obj, NULL); + if (!PyErr_Occurred()) { + if (tmpObj == NULL) { + PyErr_SetString(PyExc_TypeError, + "Failed to execute default handler"); + } else { + encode(tmpObj, (JSONObjectEncoder *)enc, NULL, 0); + } } - } - Py_XDECREF(tmpObj); - return; + Py_XDECREF(tmpObj); + return; } -void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc) -{ - PyObject *obj, *exc, *toDictFunc, *tmpObj, *values; - TypeContext *pc; - PyObjectEncoder *enc; - double val; - npy_int64 value; - int base; - PRINTMARK(); - - tc->prv = NULL; +void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) { + PyObject *obj, *exc, *toDictFunc, *tmpObj, *values; + TypeContext *pc; + PyObjectEncoder *enc; + double val; + npy_int64 value; + int base; + PRINTMARK(); - if (!_obj) { - tc->type = JT_INVALID; - return; - } + tc->prv = NULL; - obj = (PyObject*) _obj; - enc = (PyObjectEncoder*) tc->encoder; + if (!_obj) { + tc->type = JT_INVALID; + return; + } - if (enc->npyType >= 0) - { - PRINTMARK(); - tc->prv = &(enc->basicTypeContext); - tc->type = NpyTypeToJSONType(obj, tc, enc->npyType, enc->npyValue); + obj = (PyObject *)_obj; + enc = (PyObjectEncoder *)tc->encoder; - if (tc->type == JT_INVALID) - { - if(enc->defaultHandler) - { + if (enc->npyType >= 0) { + PRINTMARK(); + tc->prv = &(enc->basicTypeContext); + tc->type = NpyTypeToJSONType(obj, tc, enc->npyType, enc->npyValue); + + if (tc->type == JT_INVALID) { + if (enc->defaultHandler) { + enc->npyType = -1; + PRINTMARK(); + Object_invokeDefaultHandler( + enc->npyCtxtPassthru->getitem(enc->npyValue, + enc->npyCtxtPassthru->array), + enc); + } else { + PyErr_Format(PyExc_RuntimeError, "Unhandled numpy dtype %d", + enc->npyType); + } + } + enc->npyCtxtPassthru = NULL; enc->npyType = -1; + return; + } + + if (PyBool_Check(obj)) { PRINTMARK(); - Object_invokeDefaultHandler(enc->npyCtxtPassthru->getitem(enc->npyValue, enc->npyCtxtPassthru->array), enc); - } - else - { - PyErr_Format ( - PyExc_RuntimeError, - "Unhandled numpy dtype %d", - enc->npyType); - } - } - enc->npyCtxtPassthru = NULL; - enc->npyType = -1; - return; - } + tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; + return; + } else if (obj == Py_None) { + PRINTMARK(); + tc->type = JT_NULL; + return; + } - if (PyBool_Check(obj)) - { - PRINTMARK(); - tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; - return; - } - else - if (obj == Py_None) - { - PRINTMARK(); - tc->type = JT_NULL; - return; - } - - pc = createTypeContext(); - if (!pc) - { - tc->type = JT_INVALID; - return; - } - tc->prv = pc; + pc = createTypeContext(); + if (!pc) { + tc->type = JT_INVALID; + return; + } + tc->prv = pc; - if (PyIter_Check(obj) || (PyArray_Check(obj) && !PyArray_CheckScalar(obj) )) - { - PRINTMARK(); - goto ISITERABLE; - } + if (PyIter_Check(obj) || + (PyArray_Check(obj) && !PyArray_CheckScalar(obj))) { + PRINTMARK(); + goto ISITERABLE; + } - if (PyLong_Check(obj)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyLongToINT64; - tc->type = JT_LONG; - GET_TC(tc)->longValue = PyLong_AsLongLong(obj); + if (PyLong_Check(obj)) { + PRINTMARK(); + pc->PyTypeToJSON = PyLongToINT64; + tc->type = JT_LONG; + GET_TC(tc)->longValue = PyLong_AsLongLong(obj); - exc = PyErr_Occurred(); + exc = PyErr_Occurred(); - if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) - { - PRINTMARK(); - goto INVALID; - } + if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PRINTMARK(); + goto INVALID; + } - return; - } - else - if (PyInt_Check(obj)) - { - PRINTMARK(); + return; + } else if (PyInt_Check(obj)) { + PRINTMARK(); #ifdef _LP64 - pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; + pc->PyTypeToJSON = PyIntToINT64; + tc->type = JT_LONG; #else - pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; + pc->PyTypeToJSON = PyIntToINT32; + tc->type = JT_INT; #endif - return; - } - else - if (PyFloat_Check(obj)) - { - PRINTMARK(); - val = PyFloat_AS_DOUBLE (obj); - if (npy_isnan(val) || npy_isinf(val)) - { - tc->type = JT_NULL; - } - else - { - pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; - } - return; - } - else - if (PyString_Check(obj)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; - return; - } - else - if (PyUnicode_Check(obj)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; - return; - } - else - if (PyObject_IsInstance(obj, type_decimal)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; - return; - } - else - if (PyDateTime_Check(obj) || PyDate_Check(obj)) - { - if (PyObject_TypeCheck(obj, cls_nat)) - { - PRINTMARK(); - tc->type = JT_NULL; - return; - } - - PRINTMARK(); - pc->PyTypeToJSON = PyDateTimeToJSON; - if (enc->datetimeIso) - { - PRINTMARK(); - tc->type = JT_UTF8; - } - else - { - PRINTMARK(); - tc->type = JT_LONG; - } - return; - } - else - if (PyTime_Check(obj)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyTimeToJSON; tc->type = JT_UTF8; - return; - } - else - if (PyArray_IsScalar(obj, Datetime)) - { - PRINTMARK(); - if (((PyDatetimeScalarObject*) obj)->obval == get_nat()) { - PRINTMARK(); - tc->type = JT_NULL; - return; - } - - PRINTMARK(); - pc->PyTypeToJSON = NpyDateTimeScalarToJSON; - tc->type = enc->datetimeIso ? JT_UTF8 : JT_LONG; - return; - } - else - if (PyDelta_Check(obj)) - { - if (PyObject_HasAttrString(obj, "value")) - { - PRINTMARK(); - value = get_long_attr(obj, "value"); - } - else - { - PRINTMARK(); - value = total_seconds(obj) * 1000000000LL; // nanoseconds per second - } - - base = ((PyObjectEncoder*) tc->encoder)->datetimeUnit; - switch (base) - { - case PANDAS_FR_ns: - break; - case PANDAS_FR_us: - value /= 1000LL; - break; - case PANDAS_FR_ms: - value /= 1000000LL; - break; - case PANDAS_FR_s: - value /= 1000000000LL; - break; - } - - exc = PyErr_Occurred(); + return; + } else if (PyFloat_Check(obj)) { + PRINTMARK(); + val = PyFloat_AS_DOUBLE(obj); + if (npy_isnan(val) || npy_isinf(val)) { + tc->type = JT_NULL; + } else { + pc->PyTypeToJSON = PyFloatToDOUBLE; + tc->type = JT_DOUBLE; + } + return; + } else if (PyString_Check(obj)) { + PRINTMARK(); + pc->PyTypeToJSON = PyStringToUTF8; + tc->type = JT_UTF8; + return; + } else if (PyUnicode_Check(obj)) { + PRINTMARK(); + pc->PyTypeToJSON = PyUnicodeToUTF8; + tc->type = JT_UTF8; + return; + } else if (PyObject_IsInstance(obj, type_decimal)) { + PRINTMARK(); + pc->PyTypeToJSON = PyFloatToDOUBLE; + tc->type = JT_DOUBLE; + return; + } else if (PyDateTime_Check(obj) || PyDate_Check(obj)) { + if (PyObject_TypeCheck(obj, cls_nat)) { + PRINTMARK(); + tc->type = JT_NULL; + return; + } - if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) - { - PRINTMARK(); - goto INVALID; - } + PRINTMARK(); + pc->PyTypeToJSON = PyDateTimeToJSON; + if (enc->datetimeIso) { + PRINTMARK(); + tc->type = JT_UTF8; + } else { + PRINTMARK(); + tc->type = JT_LONG; + } + return; + } else if (PyTime_Check(obj)) { + PRINTMARK(); + pc->PyTypeToJSON = PyTimeToJSON; + tc->type = JT_UTF8; + return; + } else if (PyArray_IsScalar(obj, Datetime)) { + PRINTMARK(); + if (((PyDatetimeScalarObject *)obj)->obval == get_nat()) { + PRINTMARK(); + tc->type = JT_NULL; + return; + } - if (value == get_nat()) - { - PRINTMARK(); - tc->type = JT_NULL; - return; - } + PRINTMARK(); + pc->PyTypeToJSON = NpyDateTimeScalarToJSON; + tc->type = enc->datetimeIso ? JT_UTF8 : JT_LONG; + return; + } else if (PyDelta_Check(obj)) { + if (PyObject_HasAttrString(obj, "value")) { + PRINTMARK(); + value = get_long_attr(obj, "value"); + } else { + PRINTMARK(); + value = + total_seconds(obj) * 1000000000LL; // nanoseconds per second + } - GET_TC(tc)->longValue = value; + base = ((PyObjectEncoder *)tc->encoder)->datetimeUnit; + switch (base) { + case PANDAS_FR_ns: + break; + case PANDAS_FR_us: + value /= 1000LL; + break; + case PANDAS_FR_ms: + value /= 1000000LL; + break; + case PANDAS_FR_s: + value /= 1000000000LL; + break; + } - PRINTMARK(); - pc->PyTypeToJSON = PyLongToINT64; - tc->type = JT_LONG; - return; - } - else - if (PyArray_IsScalar(obj, Integer)) - { - PRINTMARK(); - pc->PyTypeToJSON = PyLongToINT64; - tc->type = JT_LONG; - PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->longValue), PyArray_DescrFromType(NPY_INT64)); + exc = PyErr_Occurred(); - exc = PyErr_Occurred(); + if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PRINTMARK(); + goto INVALID; + } - if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) - { - PRINTMARK(); - goto INVALID; - } + if (value == get_nat()) { + PRINTMARK(); + tc->type = JT_NULL; + return; + } - return; - } - else - if (PyArray_IsScalar(obj, Bool)) - { - PRINTMARK(); - PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->longValue), PyArray_DescrFromType(NPY_BOOL)); - tc->type = (GET_TC(tc)->longValue) ? JT_TRUE : JT_FALSE; - return; - } - else - if (PyArray_IsScalar(obj, Float) || PyArray_IsScalar(obj, Double)) - { - PRINTMARK(); - pc->PyTypeToJSON = NpyFloatToDOUBLE; tc->type = JT_DOUBLE; - return; - } - else - if (PyArray_Check(obj) && PyArray_CheckScalar(obj)) { - tmpObj = PyObject_Repr(obj); - PyErr_Format( - PyExc_TypeError, - "%s (0d array) is not JSON serializable at the moment", - PyString_AS_STRING(tmpObj) - ); - Py_DECREF(tmpObj); - goto INVALID; - } + GET_TC(tc)->longValue = value; -ISITERABLE: + PRINTMARK(); + pc->PyTypeToJSON = PyLongToINT64; + tc->type = JT_LONG; + return; + } else if (PyArray_IsScalar(obj, Integer)) { + PRINTMARK(); + pc->PyTypeToJSON = PyLongToINT64; + tc->type = JT_LONG; + PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->longValue), + PyArray_DescrFromType(NPY_INT64)); - if (PyObject_TypeCheck(obj, cls_index)) - { - if (enc->outputFormat == SPLIT) - { - PRINTMARK(); - tc->type = JT_OBJECT; - pc->iterBegin = Index_iterBegin; - pc->iterEnd = Index_iterEnd; - pc->iterNext = Index_iterNext; - pc->iterGetValue = Index_iterGetValue; - pc->iterGetName = Index_iterGetName; - return; - } - - pc->newObj = get_values(obj); - if (pc->newObj) - { - PRINTMARK(); - tc->type = JT_ARRAY; - pc->iterBegin = NpyArr_iterBegin; - pc->iterEnd = NpyArr_iterEnd; - pc->iterNext = NpyArr_iterNext; - pc->iterGetValue = NpyArr_iterGetValue; - pc->iterGetName = NpyArr_iterGetName; - } - else - { - goto INVALID; - } + exc = PyErr_Occurred(); - return; - } - else - if (PyObject_TypeCheck(obj, cls_series)) - { - if (enc->outputFormat == SPLIT) - { - PRINTMARK(); - tc->type = JT_OBJECT; - pc->iterBegin = Series_iterBegin; - pc->iterEnd = Series_iterEnd; - pc->iterNext = Series_iterNext; - pc->iterGetValue = Series_iterGetValue; - pc->iterGetName = Series_iterGetName; - return; - } - - pc->newObj = get_values(obj); - if (!pc->newObj) - { - goto INVALID; - } + if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PRINTMARK(); + goto INVALID; + } - if (enc->outputFormat == INDEX || enc->outputFormat == COLUMNS) - { - PRINTMARK(); - tc->type = JT_OBJECT; - tmpObj = PyObject_GetAttrString(obj, "index"); - if (!tmpObj) - { - goto INVALID; - } - values = get_values(tmpObj); - Py_DECREF(tmpObj); - if (!values) - { - goto INVALID; - } - pc->columnLabelsLen = PyArray_DIM(pc->newObj, 0); - pc->columnLabels = NpyArr_encodeLabels((PyArrayObject*) values, (JSONObjectEncoder*) enc, pc->columnLabelsLen); - if (!pc->columnLabels) - { + return; + } else if (PyArray_IsScalar(obj, Bool)) { + PRINTMARK(); + PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->longValue), + PyArray_DescrFromType(NPY_BOOL)); + tc->type = (GET_TC(tc)->longValue) ? JT_TRUE : JT_FALSE; + return; + } else if (PyArray_IsScalar(obj, Float) || PyArray_IsScalar(obj, Double)) { + PRINTMARK(); + pc->PyTypeToJSON = NpyFloatToDOUBLE; + tc->type = JT_DOUBLE; + return; + } else if (PyArray_Check(obj) && PyArray_CheckScalar(obj)) { + tmpObj = PyObject_Repr(obj); + PyErr_Format(PyExc_TypeError, + "%s (0d array) is not JSON serializable at the moment", + PyString_AS_STRING(tmpObj)); + Py_DECREF(tmpObj); goto INVALID; - } } - else - { - PRINTMARK(); - tc->type = JT_ARRAY; - } - pc->iterBegin = NpyArr_iterBegin; - pc->iterEnd = NpyArr_iterEnd; - pc->iterNext = NpyArr_iterNext; - pc->iterGetValue = NpyArr_iterGetValue; - pc->iterGetName = NpyArr_iterGetName; - return; - } - else - if (PyArray_Check(obj)) - { - if (enc->npyCtxtPassthru) - { - PRINTMARK(); - pc->npyarr = enc->npyCtxtPassthru; - tc->type = (pc->npyarr->columnLabels ? JT_OBJECT : JT_ARRAY); - pc->iterBegin = NpyArrPassThru_iterBegin; - pc->iterNext = NpyArr_iterNext; - pc->iterEnd = NpyArrPassThru_iterEnd; - pc->iterGetValue = NpyArr_iterGetValue; - pc->iterGetName = NpyArr_iterGetName; +ISITERABLE: - enc->npyCtxtPassthru = NULL; - return; - } + if (PyObject_TypeCheck(obj, cls_index)) { + if (enc->outputFormat == SPLIT) { + PRINTMARK(); + tc->type = JT_OBJECT; + pc->iterBegin = Index_iterBegin; + pc->iterEnd = Index_iterEnd; + pc->iterNext = Index_iterNext; + pc->iterGetValue = Index_iterGetValue; + pc->iterGetName = Index_iterGetName; + return; + } - PRINTMARK(); - tc->type = JT_ARRAY; - pc->iterBegin = NpyArr_iterBegin; - pc->iterEnd = NpyArr_iterEnd; - pc->iterNext = NpyArr_iterNext; - pc->iterGetValue = NpyArr_iterGetValue; - pc->iterGetName = NpyArr_iterGetName; - return; - } - else - if (PyObject_TypeCheck(obj, cls_dataframe)) - { - if (enc->blkCtxtPassthru) - { - PRINTMARK(); - pc->pdblock = enc->blkCtxtPassthru; - tc->type = (pc->pdblock->npyCtxts[0]->columnLabels ? JT_OBJECT : JT_ARRAY); + pc->newObj = get_values(obj); + if (pc->newObj) { + PRINTMARK(); + tc->type = JT_ARRAY; + pc->iterBegin = NpyArr_iterBegin; + pc->iterEnd = NpyArr_iterEnd; + pc->iterNext = NpyArr_iterNext; + pc->iterGetValue = NpyArr_iterGetValue; + pc->iterGetName = NpyArr_iterGetName; + } else { + goto INVALID; + } - pc->iterBegin = PdBlockPassThru_iterBegin; - pc->iterEnd = PdBlockPassThru_iterEnd; - pc->iterNext = PdBlock_iterNextItem; - pc->iterGetName = PdBlock_iterGetName; - pc->iterGetValue = NpyArr_iterGetValue; + return; + } else if (PyObject_TypeCheck(obj, cls_series)) { + if (enc->outputFormat == SPLIT) { + PRINTMARK(); + tc->type = JT_OBJECT; + pc->iterBegin = Series_iterBegin; + pc->iterEnd = Series_iterEnd; + pc->iterNext = Series_iterNext; + pc->iterGetValue = Series_iterGetValue; + pc->iterGetName = Series_iterGetName; + return; + } - enc->blkCtxtPassthru = NULL; - return; - } + pc->newObj = get_values(obj); + if (!pc->newObj) { + goto INVALID; + } - if (enc->outputFormat == SPLIT) - { - PRINTMARK(); - tc->type = JT_OBJECT; - pc->iterBegin = DataFrame_iterBegin; - pc->iterEnd = DataFrame_iterEnd; - pc->iterNext = DataFrame_iterNext; - pc->iterGetValue = DataFrame_iterGetValue; - pc->iterGetName = DataFrame_iterGetName; - return; - } + if (enc->outputFormat == INDEX || enc->outputFormat == COLUMNS) { + PRINTMARK(); + tc->type = JT_OBJECT; + tmpObj = PyObject_GetAttrString(obj, "index"); + if (!tmpObj) { + goto INVALID; + } + values = get_values(tmpObj); + Py_DECREF(tmpObj); + if (!values) { + goto INVALID; + } + pc->columnLabelsLen = PyArray_DIM(pc->newObj, 0); + pc->columnLabels = NpyArr_encodeLabels((PyArrayObject *)values, + (JSONObjectEncoder *)enc, + pc->columnLabelsLen); + if (!pc->columnLabels) { + goto INVALID; + } + } else { + PRINTMARK(); + tc->type = JT_ARRAY; + } + pc->iterBegin = NpyArr_iterBegin; + pc->iterEnd = NpyArr_iterEnd; + pc->iterNext = NpyArr_iterNext; + pc->iterGetValue = NpyArr_iterGetValue; + pc->iterGetName = NpyArr_iterGetName; + return; + } else if (PyArray_Check(obj)) { + if (enc->npyCtxtPassthru) { + PRINTMARK(); + pc->npyarr = enc->npyCtxtPassthru; + tc->type = (pc->npyarr->columnLabels ? JT_OBJECT : JT_ARRAY); + + pc->iterBegin = NpyArrPassThru_iterBegin; + pc->iterNext = NpyArr_iterNext; + pc->iterEnd = NpyArrPassThru_iterEnd; + pc->iterGetValue = NpyArr_iterGetValue; + pc->iterGetName = NpyArr_iterGetName; + + enc->npyCtxtPassthru = NULL; + return; + } - PRINTMARK(); - if (is_simple_frame(obj)) - { - pc->iterBegin = NpyArr_iterBegin; - pc->iterEnd = NpyArr_iterEnd; - pc->iterNext = NpyArr_iterNext; - pc->iterGetName = NpyArr_iterGetName; - - pc->newObj = get_values(obj); - if (!pc->newObj) - { - goto INVALID; - } - } - else - { - pc->iterBegin = PdBlock_iterBegin; - pc->iterEnd = PdBlock_iterEnd; - pc->iterNext = PdBlock_iterNext; - pc->iterGetName = PdBlock_iterGetName; - } - pc->iterGetValue = NpyArr_iterGetValue; + PRINTMARK(); + tc->type = JT_ARRAY; + pc->iterBegin = NpyArr_iterBegin; + pc->iterEnd = NpyArr_iterEnd; + pc->iterNext = NpyArr_iterNext; + pc->iterGetValue = NpyArr_iterGetValue; + pc->iterGetName = NpyArr_iterGetName; + return; + } else if (PyObject_TypeCheck(obj, cls_dataframe)) { + if (enc->blkCtxtPassthru) { + PRINTMARK(); + pc->pdblock = enc->blkCtxtPassthru; + tc->type = + (pc->pdblock->npyCtxts[0]->columnLabels ? JT_OBJECT : JT_ARRAY); + + pc->iterBegin = PdBlockPassThru_iterBegin; + pc->iterEnd = PdBlockPassThru_iterEnd; + pc->iterNext = PdBlock_iterNextItem; + pc->iterGetName = PdBlock_iterGetName; + pc->iterGetValue = NpyArr_iterGetValue; + + enc->blkCtxtPassthru = NULL; + return; + } - if (enc->outputFormat == VALUES) - { - PRINTMARK(); - tc->type = JT_ARRAY; - } - else - if (enc->outputFormat == RECORDS) - { - PRINTMARK(); - tc->type = JT_ARRAY; - tmpObj = PyObject_GetAttrString(obj, "columns"); - if (!tmpObj) - { - goto INVALID; - } - values = get_values(tmpObj); - if (!values) - { - Py_DECREF(tmpObj); - goto INVALID; - } - pc->columnLabelsLen = PyObject_Size(tmpObj); - pc->columnLabels = NpyArr_encodeLabels((PyArrayObject*) values, (JSONObjectEncoder*) enc, pc->columnLabelsLen); - Py_DECREF(tmpObj); - if (!pc->columnLabels) - { - goto INVALID; - } - } - else - if (enc->outputFormat == INDEX || enc->outputFormat == COLUMNS) - { - PRINTMARK(); - tc->type = JT_OBJECT; - tmpObj = (enc->outputFormat == INDEX ? PyObject_GetAttrString(obj, "index") : PyObject_GetAttrString(obj, "columns")); - if (!tmpObj) - { - goto INVALID; - } - values = get_values(tmpObj); - if (!values) - { - Py_DECREF(tmpObj); - goto INVALID; - } - pc->rowLabelsLen = PyObject_Size(tmpObj); - pc->rowLabels = NpyArr_encodeLabels((PyArrayObject*) values, (JSONObjectEncoder*) enc, pc->rowLabelsLen); - Py_DECREF(tmpObj); - tmpObj = (enc->outputFormat == INDEX ? PyObject_GetAttrString(obj, "columns") : PyObject_GetAttrString(obj, "index")); - if (!tmpObj) - { - NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); - pc->rowLabels = NULL; - goto INVALID; - } - values = get_values(tmpObj); - if (!values) - { - Py_DECREF(tmpObj); - NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); - pc->rowLabels = NULL; - goto INVALID; - } - pc->columnLabelsLen = PyObject_Size(tmpObj); - pc->columnLabels = NpyArr_encodeLabels((PyArrayObject*) values, (JSONObjectEncoder*) enc, pc->columnLabelsLen); - Py_DECREF(tmpObj); - if (!pc->columnLabels) - { - NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); - pc->rowLabels = NULL; - goto INVALID; - } + if (enc->outputFormat == SPLIT) { + PRINTMARK(); + tc->type = JT_OBJECT; + pc->iterBegin = DataFrame_iterBegin; + pc->iterEnd = DataFrame_iterEnd; + pc->iterNext = DataFrame_iterNext; + pc->iterGetValue = DataFrame_iterGetValue; + pc->iterGetName = DataFrame_iterGetName; + return; + } - if (enc->outputFormat == COLUMNS) - { PRINTMARK(); - pc->transpose = 1; - } - } - else - { - goto INVALID; - } - return; - } - else - if (PyDict_Check(obj)) - { - PRINTMARK(); - tc->type = JT_OBJECT; - pc->iterBegin = Dict_iterBegin; - pc->iterEnd = Dict_iterEnd; - pc->iterNext = Dict_iterNext; - pc->iterGetValue = Dict_iterGetValue; - pc->iterGetName = Dict_iterGetName; - pc->dictObj = obj; - Py_INCREF(obj); - - return; - } - else - if (PyList_Check(obj)) - { - PRINTMARK(); - tc->type = JT_ARRAY; - pc->iterBegin = List_iterBegin; - pc->iterEnd = List_iterEnd; - pc->iterNext = List_iterNext; - pc->iterGetValue = List_iterGetValue; - pc->iterGetName = List_iterGetName; - return; - } - else - if (PyTuple_Check(obj)) - { - PRINTMARK(); - tc->type = JT_ARRAY; - pc->iterBegin = Tuple_iterBegin; - pc->iterEnd = Tuple_iterEnd; - pc->iterNext = Tuple_iterNext; - pc->iterGetValue = Tuple_iterGetValue; - pc->iterGetName = Tuple_iterGetName; - return; - } - else - if (PyAnySet_Check(obj)) - { - PRINTMARK(); - tc->type = JT_ARRAY; - pc->iterBegin = Iter_iterBegin; - pc->iterEnd = Iter_iterEnd; - pc->iterNext = Iter_iterNext; - pc->iterGetValue = Iter_iterGetValue; - pc->iterGetName = Iter_iterGetName; - return; - } - - toDictFunc = PyObject_GetAttrString(obj, "toDict"); + if (is_simple_frame(obj)) { + pc->iterBegin = NpyArr_iterBegin; + pc->iterEnd = NpyArr_iterEnd; + pc->iterNext = NpyArr_iterNext; + pc->iterGetName = NpyArr_iterGetName; + + pc->newObj = get_values(obj); + if (!pc->newObj) { + goto INVALID; + } + } else { + pc->iterBegin = PdBlock_iterBegin; + pc->iterEnd = PdBlock_iterEnd; + pc->iterNext = PdBlock_iterNext; + pc->iterGetName = PdBlock_iterGetName; + } + pc->iterGetValue = NpyArr_iterGetValue; + + if (enc->outputFormat == VALUES) { + PRINTMARK(); + tc->type = JT_ARRAY; + } else if (enc->outputFormat == RECORDS) { + PRINTMARK(); + tc->type = JT_ARRAY; + tmpObj = PyObject_GetAttrString(obj, "columns"); + if (!tmpObj) { + goto INVALID; + } + values = get_values(tmpObj); + if (!values) { + Py_DECREF(tmpObj); + goto INVALID; + } + pc->columnLabelsLen = PyObject_Size(tmpObj); + pc->columnLabels = NpyArr_encodeLabels((PyArrayObject *)values, + (JSONObjectEncoder *)enc, + pc->columnLabelsLen); + Py_DECREF(tmpObj); + if (!pc->columnLabels) { + goto INVALID; + } + } else if (enc->outputFormat == INDEX || enc->outputFormat == COLUMNS) { + PRINTMARK(); + tc->type = JT_OBJECT; + tmpObj = (enc->outputFormat == INDEX + ? PyObject_GetAttrString(obj, "index") + : PyObject_GetAttrString(obj, "columns")); + if (!tmpObj) { + goto INVALID; + } + values = get_values(tmpObj); + if (!values) { + Py_DECREF(tmpObj); + goto INVALID; + } + pc->rowLabelsLen = PyObject_Size(tmpObj); + pc->rowLabels = + NpyArr_encodeLabels((PyArrayObject *)values, + (JSONObjectEncoder *)enc, pc->rowLabelsLen); + Py_DECREF(tmpObj); + tmpObj = (enc->outputFormat == INDEX + ? PyObject_GetAttrString(obj, "columns") + : PyObject_GetAttrString(obj, "index")); + if (!tmpObj) { + NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); + pc->rowLabels = NULL; + goto INVALID; + } + values = get_values(tmpObj); + if (!values) { + Py_DECREF(tmpObj); + NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); + pc->rowLabels = NULL; + goto INVALID; + } + pc->columnLabelsLen = PyObject_Size(tmpObj); + pc->columnLabels = NpyArr_encodeLabels((PyArrayObject *)values, + (JSONObjectEncoder *)enc, + pc->columnLabelsLen); + Py_DECREF(tmpObj); + if (!pc->columnLabels) { + NpyArr_freeLabels(pc->rowLabels, pc->rowLabelsLen); + pc->rowLabels = NULL; + goto INVALID; + } + + if (enc->outputFormat == COLUMNS) { + PRINTMARK(); + pc->transpose = 1; + } + } else { + goto INVALID; + } + return; + } else if (PyDict_Check(obj)) { + PRINTMARK(); + tc->type = JT_OBJECT; + pc->iterBegin = Dict_iterBegin; + pc->iterEnd = Dict_iterEnd; + pc->iterNext = Dict_iterNext; + pc->iterGetValue = Dict_iterGetValue; + pc->iterGetName = Dict_iterGetName; + pc->dictObj = obj; + Py_INCREF(obj); + + return; + } else if (PyList_Check(obj)) { + PRINTMARK(); + tc->type = JT_ARRAY; + pc->iterBegin = List_iterBegin; + pc->iterEnd = List_iterEnd; + pc->iterNext = List_iterNext; + pc->iterGetValue = List_iterGetValue; + pc->iterGetName = List_iterGetName; + return; + } else if (PyTuple_Check(obj)) { + PRINTMARK(); + tc->type = JT_ARRAY; + pc->iterBegin = Tuple_iterBegin; + pc->iterEnd = Tuple_iterEnd; + pc->iterNext = Tuple_iterNext; + pc->iterGetValue = Tuple_iterGetValue; + pc->iterGetName = Tuple_iterGetName; + return; + } else if (PyAnySet_Check(obj)) { + PRINTMARK(); + tc->type = JT_ARRAY; + pc->iterBegin = Iter_iterBegin; + pc->iterEnd = Iter_iterEnd; + pc->iterNext = Iter_iterNext; + pc->iterGetValue = Iter_iterGetValue; + pc->iterGetName = Iter_iterGetName; + return; + } + + toDictFunc = PyObject_GetAttrString(obj, "toDict"); + + if (toDictFunc) { + PyObject *tuple = PyTuple_New(0); + PyObject *toDictResult = PyObject_Call(toDictFunc, tuple, NULL); + Py_DECREF(tuple); + Py_DECREF(toDictFunc); + + if (toDictResult == NULL) { + PyErr_Clear(); + tc->type = JT_NULL; + return; + } - if (toDictFunc) - { - PyObject* tuple = PyTuple_New(0); - PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); - Py_DECREF(tuple); - Py_DECREF(toDictFunc); + if (!PyDict_Check(toDictResult)) { + Py_DECREF(toDictResult); + tc->type = JT_NULL; + return; + } - if (toDictResult == NULL) - { - PyErr_Clear(); - tc->type = JT_NULL; - return; + PRINTMARK(); + tc->type = JT_OBJECT; + pc->iterBegin = Dict_iterBegin; + pc->iterEnd = Dict_iterEnd; + pc->iterNext = Dict_iterNext; + pc->iterGetValue = Dict_iterGetValue; + pc->iterGetName = Dict_iterGetName; + pc->dictObj = toDictResult; + return; } - if (!PyDict_Check(toDictResult)) - { - Py_DECREF(toDictResult); - tc->type = JT_NULL; - return; + PyErr_Clear(); + + if (enc->defaultHandler) { + Object_invokeDefaultHandler(obj, enc); + goto INVALID; } PRINTMARK(); tc->type = JT_OBJECT; - pc->iterBegin = Dict_iterBegin; - pc->iterEnd = Dict_iterEnd; - pc->iterNext = Dict_iterNext; - pc->iterGetValue = Dict_iterGetValue; - pc->iterGetName = Dict_iterGetName; - pc->dictObj = toDictResult; + pc->iterBegin = Dir_iterBegin; + pc->iterEnd = Dir_iterEnd; + pc->iterNext = Dir_iterNext; + pc->iterGetValue = Dir_iterGetValue; + pc->iterGetName = Dir_iterGetName; return; - } - - PyErr_Clear(); - - if (enc->defaultHandler) - { - Object_invokeDefaultHandler(obj, enc); - goto INVALID; - } - - PRINTMARK(); - tc->type = JT_OBJECT; - pc->iterBegin = Dir_iterBegin; - pc->iterEnd = Dir_iterEnd; - pc->iterNext = Dir_iterNext; - pc->iterGetValue = Dir_iterGetValue; - pc->iterGetName = Dir_iterGetName; - return; INVALID: - tc->type = JT_INVALID; - PyObject_Free(tc->prv); - tc->prv = NULL; - return; + tc->type = JT_INVALID; + PyObject_Free(tc->prv); + tc->prv = NULL; + return; } -void Object_endTypeContext(JSOBJ obj, JSONTypeContext *tc) -{ - PRINTMARK(); - if(tc->prv) - { - Py_XDECREF(GET_TC(tc)->newObj); - GET_TC(tc)->newObj = NULL; - NpyArr_freeLabels(GET_TC(tc)->rowLabels, GET_TC(tc)->rowLabelsLen); - GET_TC(tc)->rowLabels = NULL; - NpyArr_freeLabels(GET_TC(tc)->columnLabels, GET_TC(tc)->columnLabelsLen); - GET_TC(tc)->columnLabels = NULL; - - PyObject_Free(GET_TC(tc)->cStr); - GET_TC(tc)->cStr = NULL; - if (tc->prv != &(((PyObjectEncoder*) tc->encoder)->basicTypeContext)) - { - PyObject_Free(tc->prv); +void Object_endTypeContext(JSOBJ obj, JSONTypeContext *tc) { + PRINTMARK(); + if (tc->prv) { + Py_XDECREF(GET_TC(tc)->newObj); + GET_TC(tc)->newObj = NULL; + NpyArr_freeLabels(GET_TC(tc)->rowLabels, GET_TC(tc)->rowLabelsLen); + GET_TC(tc)->rowLabels = NULL; + NpyArr_freeLabels(GET_TC(tc)->columnLabels, + GET_TC(tc)->columnLabelsLen); + GET_TC(tc)->columnLabels = NULL; + + PyObject_Free(GET_TC(tc)->cStr); + GET_TC(tc)->cStr = NULL; + if (tc->prv != &(((PyObjectEncoder *)tc->encoder)->basicTypeContext)) { // NOLINT + PyObject_Free(tc->prv); + } + tc->prv = NULL; } - tc->prv = NULL; - } } -const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen) -{ - return GET_TC(tc)->PyTypeToJSON (obj, tc, NULL, _outLen); +const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc, + size_t *_outLen) { + return GET_TC(tc)->PyTypeToJSON(obj, tc, NULL, _outLen); } -JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc) -{ - JSINT64 ret; - GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL); - return ret; +JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc) { + JSINT64 ret; + GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL); + return ret; } -JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc) -{ - JSINT32 ret; - GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL); - return ret; +JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc) { + JSINT32 ret; + GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL); + return ret; } -double Object_getDoubleValue(JSOBJ obj, JSONTypeContext *tc) -{ - double ret; - GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL); - return ret; +double Object_getDoubleValue(JSOBJ obj, JSONTypeContext *tc) { + double ret; + GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL); + return ret; } -static void Object_releaseObject(JSOBJ _obj) -{ - Py_DECREF( (PyObject *) _obj); -} +static void Object_releaseObject(JSOBJ _obj) { Py_DECREF((PyObject *)_obj); } -void Object_iterBegin(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->iterBegin(obj, tc); +void Object_iterBegin(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->iterBegin(obj, tc); } -int Object_iterNext(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->iterNext(obj, tc); +int Object_iterNext(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->iterNext(obj, tc); } -void Object_iterEnd(JSOBJ obj, JSONTypeContext *tc) -{ - GET_TC(tc)->iterEnd(obj, tc); +void Object_iterEnd(JSOBJ obj, JSONTypeContext *tc) { + GET_TC(tc)->iterEnd(obj, tc); } -JSOBJ Object_iterGetValue(JSOBJ obj, JSONTypeContext *tc) -{ - return GET_TC(tc)->iterGetValue(obj, tc); +JSOBJ Object_iterGetValue(JSOBJ obj, JSONTypeContext *tc) { + return GET_TC(tc)->iterGetValue(obj, tc); } -char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) -{ - return GET_TC(tc)->iterGetName(obj, tc, outLen); +char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) { + return GET_TC(tc)->iterGetName(obj, tc, outLen); } -PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = { "obj", "ensure_ascii", "double_precision", "encode_html_chars", "orient", "date_unit", "iso_dates", "default_handler", NULL}; - - char buffer[65536]; - char *ret; - PyObject *newobj; - PyObject *oinput = NULL; - PyObject *oensureAscii = NULL; - int idoublePrecision = 10; // default double precision setting - PyObject *oencodeHTMLChars = NULL; - char *sOrient = NULL; - char *sdateFormat = NULL; - PyObject *oisoDates = 0; - PyObject *odefHandler = 0; - - PyObjectEncoder pyEncoder = - { - { +PyObject *objToJSON(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = { + "obj", "ensure_ascii", "double_precision", "encode_html_chars", + "orient", "date_unit", "iso_dates", "default_handler", + NULL}; + + char buffer[65536]; + char *ret; + PyObject *newobj; + PyObject *oinput = NULL; + PyObject *oensureAscii = NULL; + int idoublePrecision = 10; // default double precision setting + PyObject *oencodeHTMLChars = NULL; + char *sOrient = NULL; + char *sdateFormat = NULL; + PyObject *oisoDates = 0; + PyObject *odefHandler = 0; + + PyObjectEncoder pyEncoder = {{ Object_beginTypeContext, Object_endTypeContext, Object_getStringValue, @@ -2695,230 +2312,188 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) PyObject_Malloc, PyObject_Realloc, PyObject_Free, - -1, //recursionMax + -1, // recursionMax idoublePrecision, - 1, //forceAscii - 0, //encodeHTMLChars - } - }; - JSONObjectEncoder* encoder = (JSONObjectEncoder*) &pyEncoder; - - pyEncoder.npyCtxtPassthru = NULL; - pyEncoder.blkCtxtPassthru = NULL; - pyEncoder.npyType = -1; - pyEncoder.npyValue = NULL; - pyEncoder.datetimeIso = 0; - pyEncoder.datetimeUnit = PANDAS_FR_ms; - pyEncoder.outputFormat = COLUMNS; - pyEncoder.defaultHandler = 0; - pyEncoder.basicTypeContext.newObj = NULL; - pyEncoder.basicTypeContext.dictObj = NULL; - pyEncoder.basicTypeContext.itemValue = NULL; - pyEncoder.basicTypeContext.itemName = NULL; - pyEncoder.basicTypeContext.attrList = NULL; - pyEncoder.basicTypeContext.iterator = NULL; - pyEncoder.basicTypeContext.cStr = NULL; - pyEncoder.basicTypeContext.npyarr = NULL; - pyEncoder.basicTypeContext.rowLabels = NULL; - pyEncoder.basicTypeContext.columnLabels = NULL; - - PRINTMARK(); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiOssOO", kwlist, &oinput, &oensureAscii, &idoublePrecision, &oencodeHTMLChars, &sOrient, &sdateFormat, &oisoDates, &odefHandler)) - { - return NULL; - } - - if (oensureAscii != NULL && !PyObject_IsTrue(oensureAscii)) - { - encoder->forceASCII = 0; - } - - if (oencodeHTMLChars != NULL && PyObject_IsTrue(oencodeHTMLChars)) - { - encoder->encodeHTMLChars = 1; - } - - if (idoublePrecision > JSON_DOUBLE_MAX_DECIMALS || idoublePrecision < 0) - { - PyErr_Format ( - PyExc_ValueError, - "Invalid value '%d' for option 'double_precision', max is '%u'", - idoublePrecision, - JSON_DOUBLE_MAX_DECIMALS); - return NULL; - } - encoder->doublePrecision = idoublePrecision; - - if (sOrient != NULL) - { - if (strcmp(sOrient, "records") == 0) - { - pyEncoder.outputFormat = RECORDS; - } - else - if (strcmp(sOrient, "index") == 0) - { - pyEncoder.outputFormat = INDEX; - } - else - if (strcmp(sOrient, "split") == 0) - { - pyEncoder.outputFormat = SPLIT; - } - else - if (strcmp(sOrient, "values") == 0) - { - pyEncoder.outputFormat = VALUES; - } - else - if (strcmp(sOrient, "columns") != 0) - { - PyErr_Format (PyExc_ValueError, "Invalid value '%s' for option 'orient'", sOrient); - return NULL; - } - } + 1, // forceAscii + 0, // encodeHTMLChars + }}; + JSONObjectEncoder *encoder = (JSONObjectEncoder *)&pyEncoder; + + pyEncoder.npyCtxtPassthru = NULL; + pyEncoder.blkCtxtPassthru = NULL; + pyEncoder.npyType = -1; + pyEncoder.npyValue = NULL; + pyEncoder.datetimeIso = 0; + pyEncoder.datetimeUnit = PANDAS_FR_ms; + pyEncoder.outputFormat = COLUMNS; + pyEncoder.defaultHandler = 0; + pyEncoder.basicTypeContext.newObj = NULL; + pyEncoder.basicTypeContext.dictObj = NULL; + pyEncoder.basicTypeContext.itemValue = NULL; + pyEncoder.basicTypeContext.itemName = NULL; + pyEncoder.basicTypeContext.attrList = NULL; + pyEncoder.basicTypeContext.iterator = NULL; + pyEncoder.basicTypeContext.cStr = NULL; + pyEncoder.basicTypeContext.npyarr = NULL; + pyEncoder.basicTypeContext.rowLabels = NULL; + pyEncoder.basicTypeContext.columnLabels = NULL; - if (sdateFormat != NULL) - { - if (strcmp(sdateFormat, "s") == 0) - { - pyEncoder.datetimeUnit = PANDAS_FR_s; - } - else - if (strcmp(sdateFormat, "ms") == 0) - { - pyEncoder.datetimeUnit = PANDAS_FR_ms; + PRINTMARK(); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiOssOO", kwlist, &oinput, + &oensureAscii, &idoublePrecision, + &oencodeHTMLChars, &sOrient, &sdateFormat, + &oisoDates, &odefHandler)) { + return NULL; } - else - if (strcmp(sdateFormat, "us") == 0) - { - pyEncoder.datetimeUnit = PANDAS_FR_us; + + if (oensureAscii != NULL && !PyObject_IsTrue(oensureAscii)) { + encoder->forceASCII = 0; } - else - if (strcmp(sdateFormat, "ns") == 0) - { - pyEncoder.datetimeUnit = PANDAS_FR_ns; + + if (oencodeHTMLChars != NULL && PyObject_IsTrue(oencodeHTMLChars)) { + encoder->encodeHTMLChars = 1; } - else - { - PyErr_Format (PyExc_ValueError, "Invalid value '%s' for option 'date_unit'", sdateFormat); - return NULL; + + if (idoublePrecision > JSON_DOUBLE_MAX_DECIMALS || idoublePrecision < 0) { + PyErr_Format( + PyExc_ValueError, + "Invalid value '%d' for option 'double_precision', max is '%u'", + idoublePrecision, JSON_DOUBLE_MAX_DECIMALS); + return NULL; } - } + encoder->doublePrecision = idoublePrecision; - if (oisoDates != NULL && PyObject_IsTrue(oisoDates)) - { - pyEncoder.datetimeIso = 1; - } + if (sOrient != NULL) { + if (strcmp(sOrient, "records") == 0) { + pyEncoder.outputFormat = RECORDS; + } else if (strcmp(sOrient, "index") == 0) { + pyEncoder.outputFormat = INDEX; + } else if (strcmp(sOrient, "split") == 0) { + pyEncoder.outputFormat = SPLIT; + } else if (strcmp(sOrient, "values") == 0) { + pyEncoder.outputFormat = VALUES; + } else if (strcmp(sOrient, "columns") != 0) { + PyErr_Format(PyExc_ValueError, + "Invalid value '%s' for option 'orient'", sOrient); + return NULL; + } + } + if (sdateFormat != NULL) { + if (strcmp(sdateFormat, "s") == 0) { + pyEncoder.datetimeUnit = PANDAS_FR_s; + } else if (strcmp(sdateFormat, "ms") == 0) { + pyEncoder.datetimeUnit = PANDAS_FR_ms; + } else if (strcmp(sdateFormat, "us") == 0) { + pyEncoder.datetimeUnit = PANDAS_FR_us; + } else if (strcmp(sdateFormat, "ns") == 0) { + pyEncoder.datetimeUnit = PANDAS_FR_ns; + } else { + PyErr_Format(PyExc_ValueError, + "Invalid value '%s' for option 'date_unit'", + sdateFormat); + return NULL; + } + } - if (odefHandler != NULL && odefHandler != Py_None) - { - if (!PyCallable_Check(odefHandler)) - { - PyErr_SetString (PyExc_TypeError, "Default handler is not callable"); - return NULL; + if (oisoDates != NULL && PyObject_IsTrue(oisoDates)) { + pyEncoder.datetimeIso = 1; } - pyEncoder.defaultHandler = odefHandler; - } - pyEncoder.originalOutputFormat = pyEncoder.outputFormat; - PRINTMARK(); - ret = JSON_EncodeObject (oinput, encoder, buffer, sizeof (buffer)); - PRINTMARK(); + if (odefHandler != NULL && odefHandler != Py_None) { + if (!PyCallable_Check(odefHandler)) { + PyErr_SetString(PyExc_TypeError, "Default handler is not callable"); + return NULL; + } + pyEncoder.defaultHandler = odefHandler; + } - if (PyErr_Occurred()) - { + pyEncoder.originalOutputFormat = pyEncoder.outputFormat; PRINTMARK(); - return NULL; - } - - if (encoder->errorMsg) - { + ret = JSON_EncodeObject(oinput, encoder, buffer, sizeof(buffer)); PRINTMARK(); - if (ret != buffer) - { - encoder->free (ret); + + if (PyErr_Occurred()) { + PRINTMARK(); + return NULL; } - PyErr_Format (PyExc_OverflowError, "%s", encoder->errorMsg); - return NULL; - } + if (encoder->errorMsg) { + PRINTMARK(); + if (ret != buffer) { + encoder->free(ret); + } + + PyErr_Format(PyExc_OverflowError, "%s", encoder->errorMsg); + return NULL; + } - newobj = PyString_FromString (ret); + newobj = PyString_FromString(ret); - if (ret != buffer) - { - encoder->free (ret); - } + if (ret != buffer) { + encoder->free(ret); + } - PRINTMARK(); + PRINTMARK(); - return newobj; + return newobj; } -PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs) -{ - PyObject *data; - PyObject *file; - PyObject *string; - PyObject *write; - PyObject *argtuple; +PyObject *objToJSONFile(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject *data; + PyObject *file; + PyObject *string; + PyObject *write; + PyObject *argtuple; - PRINTMARK(); + PRINTMARK(); - if (!PyArg_ParseTuple (args, "OO", &data, &file)) - { - return NULL; - } + if (!PyArg_ParseTuple(args, "OO", &data, &file)) { + return NULL; + } - if (!PyObject_HasAttrString (file, "write")) - { - PyErr_Format (PyExc_TypeError, "expected file"); - return NULL; - } + if (!PyObject_HasAttrString(file, "write")) { + PyErr_Format(PyExc_TypeError, "expected file"); + return NULL; + } - write = PyObject_GetAttrString (file, "write"); + write = PyObject_GetAttrString(file, "write"); - if (!PyCallable_Check (write)) - { - Py_XDECREF(write); - PyErr_Format (PyExc_TypeError, "expected file"); - return NULL; - } + if (!PyCallable_Check(write)) { + Py_XDECREF(write); + PyErr_Format(PyExc_TypeError, "expected file"); + return NULL; + } - argtuple = PyTuple_Pack(1, data); + argtuple = PyTuple_Pack(1, data); - string = objToJSON (self, argtuple, kwargs); + string = objToJSON(self, argtuple, kwargs); + + if (string == NULL) { + Py_XDECREF(write); + Py_XDECREF(argtuple); + return NULL; + } - if (string == NULL) - { - Py_XDECREF(write); Py_XDECREF(argtuple); - return NULL; - } - Py_XDECREF(argtuple); + argtuple = PyTuple_Pack(1, string); + if (argtuple == NULL) { + Py_XDECREF(write); + return NULL; + } + if (PyObject_CallObject(write, argtuple) == NULL) { + Py_XDECREF(write); + Py_XDECREF(argtuple); + return NULL; + } - argtuple = PyTuple_Pack (1, string); - if (argtuple == NULL) - { - Py_XDECREF(write); - return NULL; - } - if (PyObject_CallObject (write, argtuple) == NULL) - { Py_XDECREF(write); - Py_XDECREF(argtuple); - return NULL; - } + Py_DECREF(argtuple); + Py_XDECREF(string); - Py_XDECREF(write); - Py_DECREF(argtuple); - Py_XDECREF(string); - - PRINTMARK(); + PRINTMARK(); - Py_RETURN_NONE; + Py_RETURN_NONE; } diff --git a/pandas/src/ujson/python/py_defines.h b/pandas/src/ujson/python/py_defines.h index 723eaed336f6b..b32285766c86a 100644 --- a/pandas/src/ujson/python/py_defines.h +++ b/pandas/src/ujson/python/py_defines.h @@ -35,6 +35,9 @@ Numeric decoder derived from from TCL library * Copyright (c) 1994 Sun Microsystems, Inc. */ +#ifndef PANDAS_SRC_UJSON_PYTHON_PY_DEFINES_H_ +#define PANDAS_SRC_UJSON_PYTHON_PY_DEFINES_H_ + #include #if PY_MAJOR_VERSION >= 3 @@ -51,3 +54,5 @@ Numeric decoder derived from from TCL library #define PyString_FromString PyUnicode_FromString #endif + +#endif // PANDAS_SRC_UJSON_PYTHON_PY_DEFINES_H_ diff --git a/pandas/src/ujson/python/ujson.c b/pandas/src/ujson/python/ujson.c index 48ea92ed3bc8c..8c25975f12409 100644 --- a/pandas/src/ujson/python/ujson.c +++ b/pandas/src/ujson/python/ujson.c @@ -39,74 +39,84 @@ Numeric decoder derived from from TCL library #include "version.h" /* objToJSON */ -PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs); +PyObject *objToJSON(PyObject *self, PyObject *args, PyObject *kwargs); void initObjToJSON(void); /* JSONToObj */ -PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs); +PyObject *JSONToObj(PyObject *self, PyObject *args, PyObject *kwargs); /* objToJSONFile */ -PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs); +PyObject *objToJSONFile(PyObject *self, PyObject *args, PyObject *kwargs); /* JSONFileToObj */ -PyObject* JSONFileToObj(PyObject* self, PyObject *args, PyObject *kwargs); +PyObject *JSONFileToObj(PyObject *self, PyObject *args, PyObject *kwargs); - -#define ENCODER_HELP_TEXT "Use ensure_ascii=false to output UTF-8. Pass in double_precision to alter the maximum digit precision of doubles. Set encode_html_chars=True to encode < > & as unicode escape sequences." +#define ENCODER_HELP_TEXT \ + "Use ensure_ascii=false to output UTF-8. Pass in double_precision to " \ + "alter the maximum digit precision of doubles. Set " \ + "encode_html_chars=True to encode < > & as unicode escape sequences." static PyMethodDef ujsonMethods[] = { - {"encode", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. " ENCODER_HELP_TEXT}, - {"decode", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure. Use precise_float=True to use high precision float decoder."}, - {"dumps", (PyCFunction) objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. " ENCODER_HELP_TEXT}, - {"loads", (PyCFunction) JSONToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as string to dict object structure. Use precise_float=True to use high precision float decoder."}, - {"dump", (PyCFunction) objToJSONFile, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursively into JSON file. " ENCODER_HELP_TEXT}, - {"load", (PyCFunction) JSONFileToObj, METH_VARARGS | METH_KEYWORDS, "Converts JSON as file to dict object structure. Use precise_float=True to use high precision float decoder."}, - {NULL, NULL, 0, NULL} /* Sentinel */ + {"encode", (PyCFunction)objToJSON, METH_VARARGS | METH_KEYWORDS, + "Converts arbitrary object recursivly into JSON. " ENCODER_HELP_TEXT}, + {"decode", (PyCFunction)JSONToObj, METH_VARARGS | METH_KEYWORDS, + "Converts JSON as string to dict object structure. Use precise_float=True " + "to use high precision float decoder."}, + {"dumps", (PyCFunction)objToJSON, METH_VARARGS | METH_KEYWORDS, + "Converts arbitrary object recursivly into JSON. " ENCODER_HELP_TEXT}, + {"loads", (PyCFunction)JSONToObj, METH_VARARGS | METH_KEYWORDS, + "Converts JSON as string to dict object structure. Use precise_float=True " + "to use high precision float decoder."}, + {"dump", (PyCFunction)objToJSONFile, METH_VARARGS | METH_KEYWORDS, + "Converts arbitrary object recursively into JSON " + "file. " ENCODER_HELP_TEXT}, + {"load", (PyCFunction)JSONFileToObj, METH_VARARGS | METH_KEYWORDS, + "Converts JSON as file to dict object structure. Use precise_float=True " + "to use high precision float decoder."}, + {NULL, NULL, 0, NULL} /* Sentinel */ }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_pandasujson", - 0, /* m_doc */ - -1, /* m_size */ - ujsonMethods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ + PyModuleDef_HEAD_INIT, + "_pandasujson", + 0, /* m_doc */ + -1, /* m_size */ + ujsonMethods, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ }; -#define PYMODINITFUNC PyMODINIT_FUNC PyInit_json(void) -#define PYMODULE_CREATE() PyModule_Create(&moduledef) -#define MODINITERROR return NULL +#define PYMODINITFUNC PyMODINIT_FUNC PyInit_json(void) +#define PYMODULE_CREATE() PyModule_Create(&moduledef) +#define MODINITERROR return NULL #else -#define PYMODINITFUNC PyMODINIT_FUNC initjson(void) -#define PYMODULE_CREATE() Py_InitModule("json", ujsonMethods) -#define MODINITERROR return +#define PYMODINITFUNC PyMODINIT_FUNC initjson(void) +#define PYMODULE_CREATE() Py_InitModule("json", ujsonMethods) +#define MODINITERROR return #endif -PYMODINITFUNC -{ - PyObject *module; - PyObject *version_string; +PYMODINITFUNC { + PyObject *module; + PyObject *version_string; - initObjToJSON(); - module = PYMODULE_CREATE(); + initObjToJSON(); + module = PYMODULE_CREATE(); - if (module == NULL) - { - MODINITERROR; - } + if (module == NULL) { + MODINITERROR; + } - version_string = PyString_FromString (UJSON_VERSION); - PyModule_AddObject (module, "__version__", version_string); + version_string = PyString_FromString(UJSON_VERSION); + PyModule_AddObject(module, "__version__", version_string); #if PY_MAJOR_VERSION >= 3 - return module; + return module; #endif } diff --git a/pandas/src/ujson/python/version.h b/pandas/src/ujson/python/version.h index 2d4fd137edefe..c074ef572101d 100644 --- a/pandas/src/ujson/python/version.h +++ b/pandas/src/ujson/python/version.h @@ -35,4 +35,9 @@ Numeric decoder derived from from TCL library * Copyright (c) 1994 Sun Microsystems, Inc. */ +#ifndef PANDAS_SRC_UJSON_PYTHON_VERSION_H_ +#define PANDAS_SRC_UJSON_PYTHON_VERSION_H_ + #define UJSON_VERSION "1.33" + +#endif // PANDAS_SRC_UJSON_PYTHON_VERSION_H_