File: pygdavalue_conversions.c

package info (click to toggle)
gnome-python-extras 2.14.3-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,756 kB
  • ctags: 731
  • sloc: sh: 8,856; ansic: 5,011; xml: 1,319; python: 725; makefile: 415
file content (158 lines) | stat: -rw-r--r-- 6,833 bytes parent folder | download
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
#include <Python.h>
#if PY_VERSION_HEX >= 0x02040000
# include <datetime.h> /* From Python */
#endif
#include "pygdavalue_conversions.h"


/**
 * pygda_value_from_pyobject:
 * @value: the GdaValue object to store the converted value in.
 * @obj: the Python object to convert.
 *
 * This function converts a Python object and stores the result in a
 * GdaValue. If the Python object can't be converted to the
 * type of the GdaValue, then an error is returned.
 *
 * Returns: 0 on success, -1 on error.
 */
int
pygda_value_from_pyobject(GdaValue *boxed, PyObject *input)
{
    /* Use an appropriate gda_value_set_*() function.
       We can not know what GdaValue type is actually wanted, so
       we must still have the get_*() functions in the python API.
     */
    if (PyString_Check (input)) {
      const char* text = PyString_AsString (input);
      gda_value_set_string (boxed, text);
    } else if (PyInt_Check (input)) {
      gda_value_set_integer (boxed, PyInt_AsLong (input));
    } else if (PyLong_Check (input)) {
      gda_value_set_integer (boxed, PyInt_AsLong (input));
    } else if (PyFloat_Check (input)) {
      gda_value_set_double (boxed, PyFloat_AsDouble (input));
    } else if (PyBool_Check (input)) {
      gda_value_set_boolean (boxed, (input == Py_True));
#if PY_VERSION_HEX >= 0x02040000
    } else if (PyDateTime_Check (input)) {
         GdaTimestamp gda;
         gda.year = PyDateTime_GET_YEAR(input);
         gda.month = PyDateTime_GET_MONTH(input);
         gda.day = PyDateTime_GET_DAY(input);
         gda.hour = PyDateTime_DATE_GET_HOUR(input);
         gda.minute = PyDateTime_DATE_GET_MINUTE(input);
         gda.second = PyDateTime_DATE_GET_SECOND(input);
         gda.timezone = 0;
         gda_value_set_timestamp (boxed, &gda);
     } else if (PyDate_Check (input)) {
         GdaDate gda;
         gda.year = PyDateTime_GET_YEAR(input);
         gda.month = PyDateTime_GET_MONTH(input);
         gda.day = PyDateTime_GET_DAY(input);
         gda_value_set_date(boxed, &gda);
     } else if (PyTime_Check (input)) {
         GdaTime gda;
         gda.hour = PyDateTime_TIME_GET_HOUR(input);
         gda.minute = PyDateTime_TIME_GET_MINUTE(input);
         gda.second = PyDateTime_TIME_GET_SECOND(input);
         gda.timezone = 0;
         gda_value_set_time (boxed, &gda);
#endif
    } else {
      g_warning("Unhandled python type.");
      return -1; //failed.
    }

    return 0; //success.
}

/**
 * pygda_value_as_pyobject:
 * @value: the GdaValue object.
 * @copy_boxed: true if boxed values should be copied.
 *
 * This function creates/returns a Python wrapper object that
 * represents the GdaValue passed as an argument.
 *
 * Returns: a PyObject representing the value.
 */
PyObject *
pygda_value_as_pyobject(const GdaValue *boxed, gboolean copy_boxed)
{
    GdaValueType value_type = GDA_VALUE_TYPE_UNKNOWN;
    PyObject* ret = 0;

    value_type = gda_value_get_type ((GdaValue*)boxed);

#if PY_VERSION_HEX >= 0x02040000
    PyDateTime_IMPORT; /* So we can use PyDate*() functions. */
#endif

    if (value_type == GDA_VALUE_TYPE_NULL) {
      Py_INCREF (Py_None);
      ret = Py_None;
    } else if (value_type == GDA_VALUE_TYPE_BIGINT) {
        ret = PyLong_FromLong (gda_value_get_bigint ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_BIGUINT) {
        ret = PyLong_FromLong (gda_value_get_biguint ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_BINARY) {
        glong size = 0;
        const gchar* val = (const gchar*)gda_value_get_binary ((GdaValue*)boxed, &size);
        ret = PyString_FromString (val); //TODO: Use the size.
    } else if (value_type == GDA_VALUE_TYPE_BLOB) {
        /* const GdaBlob* val = gda_value_get_blob ((GdaValue*)boxed); */
        ret = 0; /* TODO: This thing has a whole read/write API. */
    } else if (value_type == GDA_VALUE_TYPE_BOOLEAN) {
        ret = PyBool_FromLong (gda_value_get_boolean ((GdaValue*)boxed));
#if PY_VERSION_HEX >= 0x02040000
    } else if (value_type == GDA_VALUE_TYPE_DATE) {
        const GdaDate* val = gda_value_get_date ((GdaValue*)boxed);
        if(val)
          ret = PyDate_FromDate(val->year, val->month, val->day);
#endif
    } else if (value_type == GDA_VALUE_TYPE_DOUBLE) {
        ret = PyFloat_FromDouble (gda_value_get_double ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_GEOMETRIC_POINT) {
        const GdaGeometricPoint* val = gda_value_get_geometric_point ((GdaValue*)boxed);
        ret = Py_BuildValue ("(ii)", val->x, val->y);
    } else if (value_type == GDA_VALUE_TYPE_INTEGER) {
        ret = PyInt_FromLong (gda_value_get_integer ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_MONEY) {
        const GdaMoney* val = gda_value_get_money ((GdaValue*)boxed);
        ret = PyFloat_FromDouble(val->amount); /* TODO: We ignore the currency. */
    } else if (value_type == GDA_VALUE_TYPE_NUMERIC) {
        const GdaNumeric* val = gda_value_get_numeric ((GdaValue*)boxed);
        const gchar* number_as_text = val->number; /* Formatted according to the C locale, probably. */
        /* This would need a string _object_: ret = PyFloat_FromString(number_as_text, 0); */
        ret = PyFloat_FromDouble (g_ascii_strtod (number_as_text, NULL));
    } else if (value_type == GDA_VALUE_TYPE_SINGLE) {
        ret = PyFloat_FromDouble (gda_value_get_single ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_SMALLINT) {
        ret = PyInt_FromLong (gda_value_get_smallint ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_STRING) {
        const gchar* val = gda_value_get_string ((GdaValue*)boxed);
        ret = PyString_FromString (val);
    } else if (value_type == GDA_VALUE_TYPE_TIME) {
#if PY_VERSION_HEX >= 0x02040000
        const GdaTime* val = gda_value_get_time ((GdaValue*)boxed);
        ret = PyTime_FromTime(val->hour, val->minute, val->second, 0); /* TODO: Should we ignore GdaDate::timezone ? */
    } else if (value_type == GDA_VALUE_TYPE_TIMESTAMP) {
        const GdaTimestamp* val = gda_value_get_timestamp ((GdaValue*)boxed);
        ret = PyDateTime_FromDateAndTime(val->year, val->month, val->day, val->hour, val->minute, val->second, 0); /* TODO: Should we ignore GdaTimestamp::timezone ? */
#endif
    } else if (value_type == GDA_VALUE_TYPE_TINYINT) {
        ret = PyInt_FromLong (gda_value_get_tinyint ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_TINYUINT) {
        ret = PyInt_FromLong (gda_value_get_tinyuint ((GdaValue*)boxed));
    } else if (value_type == GDA_VALUE_TYPE_UINTEGER) {
        ret = PyInt_FromLong (gda_value_get_uinteger ((GdaValue*)boxed));
    } else {
      g_warning ("gda_value_get_type() returned unknown type %d", value_type);

      Py_INCREF (Py_None);
      ret = Py_None;
    }

    return ret;
}