Changeset: 7fc423e5191e for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7fc423e5191e Modified Files: sql/backends/monet5/UDF/pyapi/Tests/pyapi_types_string.stable.out sql/backends/monet5/UDF/pyapi/type_conversion.c Branch: Dec2016 Log Message:
Code reuse and code deduplication.
Added benefit: closer to correctness, so also approved test.
diffs (truncated from 359 to 300 lines):
diff --git a/sql/backends/monet5/UDF/pyapi/Tests/pyapi_types_string.stable.out
b/sql/backends/monet5/UDF/pyapi/Tests/pyapi_types_string.stable.out
--- a/sql/backends/monet5/UDF/pyapi/Tests/pyapi_types_string.stable.out
+++ b/sql/backends/monet5/UDF/pyapi/Tests/pyapi_types_string.stable.out
@@ -180,8 +180,8 @@ Ready.
#--------------------------#
[ 0@0, 18042.895 ]
[ 1@0, 846.9309 ]
-[ 2@0, 16.816929 ]
-[ 3@0, 1714637 ]
+[ 2@0, 16.816927 ]
+[ 3@0, 1714636.9 ]
[ 4@0, nil ]
#io.print(rstr);
#--------------------------#
diff --git a/sql/backends/monet5/UDF/pyapi/type_conversion.c
b/sql/backends/monet5/UDF/pyapi/type_conversion.c
--- a/sql/backends/monet5/UDF/pyapi/type_conversion.c
+++ b/sql/backends/monet5/UDF/pyapi/type_conversion.c
@@ -25,7 +25,7 @@ bool string_copy(char * source, char* de
{
dest[i] = source[i];
if (dest[i] == 0) return TRUE;
- if (!allow_unicode && (*(unsigned char*)&source[i]) >= 128) return
FALSE;
+ if (!allow_unicode && source[i] & 0x80) return FALSE;
}
dest[max_size] = '\0';
return TRUE;
@@ -34,40 +34,9 @@ bool string_copy(char * source, char* de
#ifdef HAVE_HGE
int hge_to_string(char * str, hge x)
{
- int i = 0;
- size_t size = 1;
- hge cpy = x > 0 ? x : -x;
- while(cpy > 0) {
- cpy /= 10;
- size++;
- }
- if (x < 0) size++;
- if (x < 0)
- {
- x *= -1;
- str[0] = '-';
- }
- str[size - 1] = '\0';
- i = size - 1;
- while(x > 0)
- {
- int v = x % 10;
- i--;
- if (i < 0) return FALSE;
- if (v == 0) str[i] = '0';
- else if (v == 1) str[i] = '1';
- else if (v == 2) str[i] = '2';
- else if (v == 3) str[i] = '3';
- else if (v == 4) str[i] = '4';
- else if (v == 5) str[i] = '5';
- else if (v == 6) str[i] = '6';
- else if (v == 7) str[i] = '7';
- else if (v == 8) str[i] = '8';
- else if (v == 9) str[i] = '9';
- x = x / 10;
- }
-
- return TRUE;
+ int len = 256; /* assume str is large enough */
+ hgeToStr(&str, &len, &x);
+ return TRUE;
}
PyObject *PyLong_FromHge(hge h)
@@ -174,85 +143,121 @@ wrapup:
return msg;
}
+#define STRING_TO_NUMBER_FACTORY(tpe) \
+str str_to_##tpe(char *ptr, size_t maxsize, tpe *value)
\
+{ \
+ int len = sizeof(tpe); \
+ char buf[256]; \
+ if (maxsize > 0) { \
+ if (maxsize >= sizeof(buf)) \
+ maxsize = sizeof(buf) - 1; \
+ strncpy(buf, ptr, maxsize); \
+ buf[maxsize] = 0; \
+ if (strlen(buf) >= sizeof(buf) - 1) \
+ return GDKstrdup("string too long to convert."); \
+ ptr = buf; \
+ } \
+ if (BATatoms[TYPE_##tpe].atomFromStr(ptr, &len, (void **) &value) == 0)
\
+ return GDKstrdup("Error converting string."); \
+ return MAL_SUCCEED; \
+}
+
#ifndef IS_PY3K
-#define PY_TO_(type, inttpe)
\
-str pyobject_to_##type(PyObject **pyobj, size_t maxsize, type *value)
\
-{
\
- PyObject *ptr = *pyobj;
\
- str retval = MAL_SUCCEED;
\
- (void) maxsize;
\
- if (PyLong_CheckExact(ptr)) {
\
- PyLongObject *p = (PyLongObject*) ptr;
\
- inttpe h = 0;
\
- inttpe prev = 0;
\
- ssize_t i = Py_SIZE(p);
\
- int sign = i < 0 ? -1 : 1;
\
- i *= sign;
\
- while (--i >= 0) {
\
- prev = h; (void)prev;
\
- h = (h << PyLong_SHIFT) + p->ob_digit[i];
\
- if ((h >> PyLong_SHIFT) != prev) {
\
- return GDKstrdup("Overflow when converting value.");
\
- }
\
- }
\
- *value = (type)(h * sign);
\
- } else if (PyInt_CheckExact(ptr) || PyBool_Check(ptr)) {
\
- *value = (type)((PyIntObject*)ptr)->ob_ival;
\
- } else if (PyFloat_CheckExact(ptr)) {
\
- *value = (type) ((PyFloatObject*)ptr)->ob_fval;
\
- } else if (PyString_CheckExact(ptr)) {
\
- return str_to_##type(((PyStringObject*)ptr)->ob_sval, -1, value);
\
- } else if (PyByteArray_CheckExact(ptr)) {
\
- return str_to_##type(((PyByteArrayObject*)ptr)->ob_bytes, -1, value);
\
- } else if (PyUnicode_CheckExact(ptr)) {
\
- return unicode_to_##type(((PyUnicodeObject*)ptr)->str, -1, value);
\
- } else if (ptr == Py_None) {
\
- *value = type##_nil;
\
- }
\
- return retval;
\
+#define PY_TO_(type, inttpe) \
+str pyobject_to_##type(PyObject **pyobj, size_t maxsize, type *value) \
+{ \
+ PyObject *ptr = *pyobj; \
+ str retval = MAL_SUCCEED; \
+ (void) maxsize; \
+ if (PyLong_CheckExact(ptr)) { \
+ PyLongObject *p = (PyLongObject*) ptr; \
+ inttpe h = 0; \
+ inttpe prev = 0; \
+ ssize_t i = Py_SIZE(p);
\
+ int sign = i < 0 ? -1 : 1; \
+ i *= sign; \
+ while (--i >= 0) { \
+ prev = h; (void)prev; \
+ h = (h << PyLong_SHIFT) + p->ob_digit[i]; \
+ if ((h >> PyLong_SHIFT) != prev) { \
+ return GDKstrdup("Overflow when converting value."); \
+ } \
+ } \
+ *value = (type)(h * sign); \
+ } else if (PyInt_CheckExact(ptr) || PyBool_Check(ptr)) { \
+ *value = (type)((PyIntObject*)ptr)->ob_ival; \
+ } else if (PyFloat_CheckExact(ptr)) { \
+ *value = (type) ((PyFloatObject*)ptr)->ob_fval;
\
+ } else if (PyString_CheckExact(ptr)) { \
+ return str_to_##type(((PyStringObject*)ptr)->ob_sval, 0, value); \
+ } else if (PyByteArray_CheckExact(ptr)) { \
+ return str_to_##type(((PyByteArrayObject*)ptr)->ob_bytes, 0, value); \
+ } else if (PyUnicode_CheckExact(ptr)) { \
+ return unicode_to_##type(((PyUnicodeObject*)ptr)->str, 0, value); \
+ } else if (ptr == Py_None) { \
+ *value = type##_nil; \
+ } \
+ return retval; \
}
-#define CONVERSION_FUNCTION_FACTORY(tpe, inttpe) \
- str str_to_##tpe(char *ptr, size_t maxsize, tpe *value) \
- { \
- ssize_t i = maxsize - 1; \
- tpe factor = 1; \
- if (i < 0) i = strlen(ptr) - 1; \
- *value = 0; \
- for( ; i >= 0; i--) \
- { \
- switch(ptr[i]) \
- { \
- case '0': break; \
- case '1': *value += factor; break; \
- case '2': *value += 2 * factor; break; \
- case '3': *value += 3 * factor; break; \
- case '4': *value += 4 * factor; break; \
- case '5': *value += 5 * factor; break; \
- case '6': *value += 6 * factor; break; \
- case '7': *value += 7 * factor; break; \
- case '8': *value += 8 * factor; break; \
- case '9': *value += 9 * factor; break; \
- case '-': *value *= -1; break; \
- case '.': \
- case ',': *value /= factor; factor = 1; continue; \
- case '\0': continue; \
- default: \
- { \
- return GDKstrdup("Error converting string."); \
- } \
- } \
- factor *= 10; \
- } \
- return MAL_SUCCEED; \
- } \
- str unicode_to_##tpe(Py_UNICODE *ptr, size_t maxsize, tpe *value) \
- { \
- char utf8[255]; \
- unicode_to_utf8(0, 255, utf8, ptr); \
- return str_to_##tpe(utf8, maxsize, value); \
- } \
+#define CONVERSION_FUNCTION_FACTORY(tpe, inttpe) \
+ STRING_TO_NUMBER_FACTORY(tpe) \
+ str unicode_to_##tpe(Py_UNICODE *ptr, size_t maxsize, tpe *value) \
+ { \
+ char utf8[1024]; \
+ if (maxsize == 0) \
+ maxsize = utf32_strlen(ptr); \
+ if (maxsize > 255) \
+ maxsize = 255; \
+ unicode_to_utf8(0, maxsize, utf8, ptr);
\
+ return str_to_##tpe(utf8, 0, value); \
+ } \
PY_TO_(tpe, inttpe);
+#else
+#define PY_TO_(type, inttpe) \
+str pyobject_to_##type(PyObject **pyobj, size_t maxsize, type *value) \
+{ \
+ PyObject *ptr = *pyobj; \
+ str retval = MAL_SUCCEED; \
+ (void) maxsize; \
+ if (PyLong_CheckExact(ptr)) { \
+ PyLongObject *p = (PyLongObject*) ptr; \
+ inttpe h = 0; \
+ inttpe prev = 0; \
+ int i = Py_SIZE(p); \
+ int sign = i < 0 ? -1 : 1; \
+ i *= sign; \
+ while (--i >= 0) { \
+ prev = h; (void)prev; \
+ h = (h << PyLong_SHIFT) + p->ob_digit[i]; \
+ if ((h >> PyLong_SHIFT) != prev) { \
+ return GDKstrdup("Overflow when converting value."); \
+ } \
+ } \
+ *value = (type)(h * sign); \
+ } else if (PyBool_Check(ptr)) { \
+ *value = ptr == Py_True ? 1 : 0; \
+ } else if (PyFloat_CheckExact(ptr)) { \
+ *value = (type) ((PyFloatObject*)ptr)->ob_fval;
\
+ } else if (PyUnicode_CheckExact(ptr)) { \
+ return str_to_##type(PyUnicode_AsUTF8(ptr), 0, value); \
+ } else if (PyByteArray_CheckExact(ptr)) { \
+ return str_to_##type(((PyByteArrayObject*)ptr)->ob_bytes, 0, value); \
+ } else if (ptr == Py_None) { \
+ *value = type##_nil; \
+ } \
+ return retval; \
+}
+#define CONVERSION_FUNCTION_FACTORY(tpe, inttpe) \
+ STRING_TO_NUMBER_FACTORY(tpe) \
+ str unicode_to_##tpe(char *ptr, size_t maxsize, tpe *value)
\
+ { \
+ return str_to_##tpe(ptr, maxsize, value); \
+ } \
+ PY_TO_(tpe, inttpe);
+
+#endif
+
CONVERSION_FUNCTION_FACTORY(bte, bte)
CONVERSION_FUNCTION_FACTORY(oid, oid)
CONVERSION_FUNCTION_FACTORY(bit, bit)
@@ -267,91 +272,6 @@ CONVERSION_FUNCTION_FACTORY(dbl, hge)
#else
CONVERSION_FUNCTION_FACTORY(dbl, lng)
#endif
-#else
-#define PY_TO_(type, inttpe)
\
-str pyobject_to_##type(PyObject **pyobj, size_t maxsize, type *value)
\
-{
\
- PyObject *ptr = *pyobj;
\
- str retval = MAL_SUCCEED;
\
- (void) maxsize;
\
- if (PyLong_CheckExact(ptr)) {
\
- PyLongObject *p = (PyLongObject*) ptr;
\
- inttpe h = 0;
\
- inttpe prev = 0;
\
- int i = Py_SIZE(p);
\
- int sign = i < 0 ? -1 : 1;
\
- i *= sign;
\
- while (--i >= 0) {
\
- prev = h; (void)prev;
\
- h = (h << PyLong_SHIFT) + p->ob_digit[i];
\
- if ((h >> PyLong_SHIFT) != prev) {
\
- return GDKstrdup("Overflow when converting value.");
\
- }
\
- }
\
- *value = (type)(h * sign);
\
- } else if (PyBool_Check(ptr)) {
\
- *value = ptr == Py_True ? 1 : 0;
\
- } else if (PyFloat_CheckExact(ptr)) {
\
- *value = (type) ((PyFloatObject*)ptr)->ob_fval;
\
- } else if (PyUnicode_CheckExact(ptr)) {
\
- return str_to_##type(PyUnicode_AsUTF8(ptr), -1, value);
\
- } else if (PyByteArray_CheckExact(ptr)) {
\
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list
