@@ -212,6 +212,34 @@ static TypeContext *createTypeContext(void) {
212212 return pc ;
213213}
214214
215+ /*
216+ * Function: scaleNanosecToUnit
217+ * -----------------------------
218+ *
219+ * Scales an integer value representing time in nanoseconds to provided unit.
220+ *
221+ * Mutates the provided value directly. Returns 0 on success, non-zero on error.
222+ */
223+ static int scaleNanosecToUnit (npy_int64 * value , NPY_DATETIMEUNIT unit ) {
224+ switch (unit ) {
225+ case NPY_FR_ns :
226+ break ;
227+ case NPY_FR_us :
228+ * value /= 1000LL ;
229+ break ;
230+ case NPY_FR_ms :
231+ * value /= 1000000LL ;
232+ break ;
233+ case NPY_FR_s :
234+ * value /= 1000000000LL ;
235+ break ;
236+ default :
237+ return -1 ;
238+ }
239+
240+ return 0 ;
241+ }
242+
215243static PyObject * get_values (PyObject * obj ) {
216244 PyObject * values = NULL ;
217245
@@ -542,25 +570,14 @@ static int NpyTypeToJSONType(PyObject *obj, JSONTypeContext *tc, int npyType,
542570 GET_TC (tc )-> PyTypeToJSON = NpyDatetime64ToJSON ;
543571 return JT_UTF8 ;
544572 } else {
545-
546- // TODO: consolidate uses of this switch
547- switch (((PyObjectEncoder * )tc -> encoder )-> datetimeUnit ) {
548- case NPY_FR_ns :
549- break ;
550- case NPY_FR_us :
551- longVal /= 1000LL ;
552- break ;
553- case NPY_FR_ms :
554- longVal /= 1000000LL ;
555- break ;
556- case NPY_FR_s :
557- longVal /= 1000000000LL ;
558- break ;
559- default :
560- break ; // TODO: should raise error
573+ NPY_DATETIMEUNIT unit =
574+ ((PyObjectEncoder * )tc -> encoder )-> datetimeUnit ;
575+ if (!scaleNanosecToUnit (& longVal , unit )) {
576+ GET_TC (tc )-> longValue = longVal ;
577+ return JT_LONG ;
578+ } else {
579+ // TODO: some kind of error handling
561580 }
562- GET_TC (tc )-> longValue = longVal ;
563- return JT_LONG ;
564581 }
565582 }
566583
@@ -1653,19 +1670,8 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
16531670 }
16541671 Py_DECREF (ts );
16551672
1656- switch (enc -> datetimeUnit ) {
1657- case NPY_FR_ns :
1658- break ;
1659- case NPY_FR_us :
1660- value /= 1000LL ;
1661- break ;
1662- case NPY_FR_ms :
1663- value /= 1000000LL ;
1664- break ;
1665- case NPY_FR_s :
1666- value /= 1000000000LL ;
1667- break ;
1668- default :
1673+ NPY_DATETIMEUNIT unit = enc -> datetimeUnit ;
1674+ if (scaleNanosecToUnit (& value , unit ) != 0 ) {
16691675 Py_DECREF (item );
16701676 NpyArr_freeLabels (ret , num );
16711677 ret = 0 ;
@@ -1737,7 +1743,7 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
17371743 PyObjectEncoder * enc ;
17381744 double val ;
17391745 npy_int64 value ;
1740- int base ;
1746+ int unit ;
17411747 PRINTMARK ();
17421748
17431749 tc -> prv = NULL ;
@@ -1880,19 +1886,9 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
18801886 value = total_seconds (obj ) * 1000000000LL ; // nanoseconds per second
18811887 }
18821888
1883- base = ((PyObjectEncoder * )tc -> encoder )-> datetimeUnit ;
1884- switch (base ) {
1885- case NPY_FR_ns :
1886- break ;
1887- case NPY_FR_us :
1888- value /= 1000LL ;
1889- break ;
1890- case NPY_FR_ms :
1891- value /= 1000000LL ;
1892- break ;
1893- case NPY_FR_s :
1894- value /= 1000000000LL ;
1895- break ;
1889+ unit = ((PyObjectEncoder * )tc -> encoder )-> datetimeUnit ;
1890+ if (scaleNanosecToUnit (& value , unit ) != 0 ) {
1891+ // TODO: Add some kind of error handling here
18961892 }
18971893
18981894 exc = PyErr_Occurred ();
0 commit comments