-
Notifications
You must be signed in to change notification settings - Fork 561
/
pyodbccompat.h
130 lines (106 loc) · 3.49 KB
/
pyodbccompat.h
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
#ifndef PYODBCCOMPAT_H
#define PYODBCCOMPAT_H
// Macros and functions to ease compatibility with Python 2 and Python 3.
#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03010000
#error Python 3.0 is not supported. Please use 3.1 and higher.
#endif
// Macros introduced in 2.6, backported for 2.4 and 2.5.
#ifndef PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif
// Used for items that are ANSI in Python 2 and Unicode in Python 3 or in int 2 and long in 3.
#if PY_MAJOR_VERSION >= 3
#define PyString_FromString PyUnicode_FromString
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
#define PyString_Check PyUnicode_Check
#define PyString_Type PyUnicode_Type
#define PyString_Size PyUnicode_Size
#define PyInt_FromLong PyLong_FromLong
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG
#define PyInt_Type PyLong_Type
#define PyString_FromFormatV PyUnicode_FromFormatV
#define PyString_FromFormat PyUnicode_FromFormat
#define Py_TPFLAGS_HAVE_ITER 0
#define PyString_AsString PyUnicode_AsString
#define TEXT_T Py_UNICODE
#define PyString_Join PyUnicode_Join
inline void PyString_ConcatAndDel(PyObject** lhs, PyObject* rhs)
{
PyUnicode_Concat(*lhs, rhs);
Py_DECREF(rhs);
}
#else
#include <stringobject.h>
#include <intobject.h>
#include <bufferobject.h>
#define TEXT_T char
#define PyString_Join _PyString_Join
#endif
inline PyObject* Text_New(Py_ssize_t length)
{
// Returns a new, uninitialized String (Python 2) or Unicode object (Python 3) object.
#if PY_MAJOR_VERSION < 3
return PyString_FromStringAndSize(0, length);
#else
return PyUnicode_FromUnicode(0, length);
#endif
}
inline TEXT_T* Text_Buffer(PyObject* o)
{
#if PY_MAJOR_VERSION < 3
I(PyString_Check(o));
return PyString_AS_STRING(o);
#else
I(PyUnicode_Check(o));
return PyUnicode_AS_UNICODE(o);
#endif
}
inline bool Text_Check(PyObject* o)
{
// A compatibility function that determines if the object is a string, based on the version of Python.
// For Python 2, an ASCII or Unicode string is allowed. For Python 3, it must be a Unicode object.
#if PY_MAJOR_VERSION < 3
if (o && PyString_Check(o))
return true;
#endif
return o && PyUnicode_Check(o);
}
bool Text_EqualsI(PyObject* lhs, const char* rhs);
// Case-insensitive comparison for a Python string object (Unicode in Python 3, ASCII or Unicode in Python 2) against
// an ASCII string. If lhs is 0 or None, false is returned.
inline Py_ssize_t Text_Size(PyObject* o)
{
#if PY_MAJOR_VERSION < 3
if (o && PyString_Check(o))
return PyString_GET_SIZE(o);
#endif
return (o && PyUnicode_Check(o)) ? PyUnicode_GET_SIZE(o) : 0;
}
inline Py_ssize_t TextCopyToUnicode(Py_UNICODE* buffer, PyObject* o)
{
// Copies a String or Unicode object to a Unicode buffer and returns the number of characters copied.
// No NULL terminator is appended!
#if PY_MAJOR_VERSION < 3
if (PyBytes_Check(o))
{
const Py_ssize_t cch = PyBytes_GET_SIZE(o);
const char * pch = PyBytes_AS_STRING(o);
for (Py_ssize_t i = 0; i < cch; i++)
*buffer++ = (Py_UNICODE)*pch++;
return cch;
}
else
{
#endif
Py_ssize_t cch = PyUnicode_GET_SIZE(o);
memcpy(buffer, PyUnicode_AS_UNICODE(o), cch * sizeof(Py_UNICODE));
return cch;
#if PY_MAJOR_VERSION < 3
}
#endif
}
#endif // PYODBCCOMPAT_H