1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/* KInterbasDB Python Package - Implementation of Parameter Conversion DB->Py
*
* Version 3.3
*
* The following contributors hold Copyright (C) over their respective
* portions of code (see license.txt for details):
*
* [Original Author (maintained through version 2.0-0.3.1):]
* 1998-2001 [alex] Alexander Kuznetsov <alexan@users.sourceforge.net>
* [Maintainers (after version 2.0-0.3.1):]
* 2001-2002 [maz] Marek Isalski <kinterbasdb@maz.nu>
* 2002-2007 [dsr] David Rushby <woodsplitter@rocketmail.com>
* [Contributors:]
* 2001 [eac] Evgeny A. Cherkashin <eugeneai@icc.ru>
* 2001-2002 [janez] Janez Jere <janez.jere@void.si>
*/
/* This source file is designed to be directly included in _kiconversion.c,
* without the involvement of a header file. */
/* The undocumented portion of ISC_TIME is ten-thousandths of a second: */
#define MICROSECONDS_FROM_ISC_TIME(t) \
(((t) % 10000) * 100)
#define MICROSECONDS_FROM_ISC_TIMESTAMP_PTR(tp) \
(((tp)->timestamp_time % 10000) * 100)
static PyObject *conv_out_char(char *data, size_t size) {
return PyString_FromStringAndSize(data, SIZE_T_TO_PYTHON_SIZE(size));
} /* conv_out_char */
static PyObject *conv_out_varchar(char *data) {
/* The first sizeof(short) bytes contain the size of the string. */
return PyString_FromStringAndSize(
data + sizeof(short),
(int) *( (short *)data )
);
} /* conv_out_varchar */
static PyObject *_conv_out_integer_types(
PyObject *py_raw, boolean is_fixed_point, short scale
)
{
/* Reference ownership note:
* This function is passed ownership of py_raw. In the non-fixed point case,
* we return that reference. For fixed point, we transfer ownership of the
* py_raw reference to the containing tuple, then return our owned reference
* to the tuple. */
assert (py_raw != NULL);
if (!is_fixed_point) {
/* Simply return the integer value. */
return py_raw;
} else {
/* We're converting a fixed-point rather than an integer; return a 2-tuple
* of the form: (value, scale) */
PyObject *fixed_tuple;
PyObject *py_scale;
fixed_tuple = PyTuple_New(2);
if (fixed_tuple == NULL) { return NULL; }
py_scale = PyInt_FromLong(scale);
if (py_scale == NULL) {
Py_DECREF(fixed_tuple);
return NULL;
}
PyTuple_SET_ITEM(fixed_tuple, 0, py_raw); /* "steals" ref to py_raw */
PyTuple_SET_ITEM(fixed_tuple, 1, py_scale); /* "steals" ref to py_scale */
return fixed_tuple;
}
} /* _conv_out_integer_types */
static PyObject *conv_out_short_long(
char *data,
short data_type, boolean is_fixed_point, short scale
)
{
/* 2004.04.16:64BC: On x86_64/1.5.1pre1, ISC_LONG is actually an int. */
long conv_long = (long)(
data_type == SQL_SHORT ?
( *((ISC_SHORT *) data) )
: ( *((ISC_LONG *) data) )
);
PyObject *py_int = PyInt_FromLong(conv_long);
if (py_int == NULL) { return NULL; }
return _conv_out_integer_types(py_int, is_fixed_point, scale);
} /* conv_out_short_long */
#ifdef INTERBASE_6_OR_LATER
static PyObject *conv_out_int64(
char *data,
boolean is_fixed_point, short scale
)
{
const LONG_LONG dataLL = *((LONG_LONG *) data);
PyObject *py_int = PythonIntOrLongFrom64BitValue(dataLL);
if (py_int == NULL) { return NULL; }
return _conv_out_integer_types(py_int, is_fixed_point, scale);
} /* conv_out_int64 */
#endif /* INTERBASE_6_OR_LATER */
static PyObject *conv_out_floating(const double raw,
const unsigned short dialect, const short scale
)
{
/* It's possible that a user would define a field as DECIMAL/NUMERIC with
* a scale of zero, but the API provides no way for us to detect that. */
if (dialect >= 3 || scale == 0) {
return PyFloat_FromDouble(raw);
}{
/* The value being converted is from a field that's logically fixed-point
* rather than floating-point. This can only arise in pre-dialect-3
* databases. */
/* This is a perfect application for Py_BuildValue, but it doesn't
* support 64-bit integers. */
PyObject *fixed_tuple;
PyObject *py_scaled_integer;
PyObject *py_scale;
fixed_tuple = PyTuple_New(2);
if (fixed_tuple != NULL) {
py_scaled_integer = PythonIntOrLongFrom64BitValue(
(LONG_LONG) (raw * pow(10.0f, (double) -scale))
);
if (py_scaled_integer == NULL) {
Py_DECREF(fixed_tuple);
fixed_tuple = NULL;
} else {
py_scale = PyInt_FromLong(scale);
if (py_scale == NULL) {
Py_DECREF(fixed_tuple);
fixed_tuple = NULL;
Py_DECREF(py_scaled_integer);
} else {
PyTuple_SET_ITEM(fixed_tuple, 0, py_scaled_integer); /* "steals" ref */
PyTuple_SET_ITEM(fixed_tuple, 1, py_scale); /* "steals" ref */
}
}
}
return fixed_tuple;
}} /* conv_out_floating */
/* Date/time types: */
static PyObject *conv_out_timestamp(char *data) {
struct tm c_tm;
int ported_ints[2]; /* sizeof(ported_ints) == sizeof(ISC_TIMESTAMP) */
int microseconds;
ENTER_GDAL
ported_ints[0] = isc_vax_integer(data, sizeof(int));
ported_ints[1] = isc_vax_integer(data + sizeof(int), sizeof(int));
isc_decode_timestamp((ISC_TIMESTAMP *) &ported_ints, &c_tm);
microseconds = MICROSECONDS_FROM_ISC_TIMESTAMP_PTR((ISC_TIMESTAMP *) data);
LEAVE_GDAL
return Py_BuildValue("(iiiiiii)",
c_tm.tm_year+1900, c_tm.tm_mon+1, c_tm.tm_mday,
c_tm.tm_hour, c_tm.tm_min, c_tm.tm_sec,
microseconds
);
} /* conv_out_timestamp */
#ifdef INTERBASE_6_OR_LATER
static PyObject *conv_out_date(char *data) {
struct tm c_tm;
int data_as_portable_int;
ENTER_GDAL
data_as_portable_int = isc_vax_integer(data, sizeof(int));
isc_decode_sql_date((ISC_DATE *) &data_as_portable_int, &c_tm);
LEAVE_GDAL
return Py_BuildValue("(iii)", c_tm.tm_year+1900, c_tm.tm_mon+1, c_tm.tm_mday);
} /* conv_out_date */
static PyObject *conv_out_time(char *data) {
struct tm c_tm;
int data_as_portable_int;
int microseconds;
ENTER_GDAL
data_as_portable_int = isc_vax_integer(data, sizeof(int));
isc_decode_sql_time((ISC_TIME *) &data_as_portable_int, &c_tm);
microseconds = MICROSECONDS_FROM_ISC_TIME(*((ISC_TIME *) data));
LEAVE_GDAL
return Py_BuildValue("(iiii)",
c_tm.tm_hour, c_tm.tm_min, c_tm.tm_sec, microseconds
);
} /* conv_out_time */
#endif /* INTERBASE_6_OR_LATER */
#define conv_out_boolean(data) \
PyBool_FromLong( *((ISC_BOOLEAN *) (data)) )
|