171 lines
5.8 KiB
C
171 lines
5.8 KiB
C
//-----------------------------------------------------------------------------
|
|
// StringUtils.c
|
|
// Defines constants and routines specific to handling strings.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// define structure for abstracting string buffers
|
|
typedef struct {
|
|
const void *ptr;
|
|
Py_ssize_t size;
|
|
#ifdef Py_UNICODE_WIDE
|
|
PyObject *encodedString;
|
|
#endif
|
|
} udt_StringBuffer;
|
|
|
|
|
|
// use the bytes methods in cx_Oracle and define them as the equivalent string
|
|
// type methods as is done in Python 2.6
|
|
#ifndef PyBytes_Check
|
|
#define PyBytes_Type PyString_Type
|
|
#define PyBytes_AS_STRING PyString_AS_STRING
|
|
#define PyBytes_GET_SIZE PyString_GET_SIZE
|
|
#define PyBytes_Check PyString_Check
|
|
#define PyBytes_Format PyString_Format
|
|
#define PyBytes_FromString PyString_FromString
|
|
#define PyBytes_FromStringAndSize PyString_FromStringAndSize
|
|
#endif
|
|
|
|
|
|
// define binary type and methods
|
|
#if PY_MAJOR_VERSION >= 3
|
|
#define cxBinary_Type PyBytes_Type
|
|
#define cxBinary_Check PyBytes_Check
|
|
#else
|
|
#define cxBinary_Type PyBuffer_Type
|
|
#define cxBinary_Check PyBuffer_Check
|
|
#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// StringBuffer_Init()
|
|
// Initialize the string buffer with an empty string. Returns 0 as a
|
|
// convenience to the caller.
|
|
//-----------------------------------------------------------------------------
|
|
static int StringBuffer_Init(
|
|
udt_StringBuffer *buf) // buffer to fill
|
|
{
|
|
buf->ptr = NULL;
|
|
buf->size = 0;
|
|
#ifdef Py_UNICODE_WIDE
|
|
buf->encodedString = NULL;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// StringBuffer_FromUnicode()
|
|
// Populate the string buffer from a unicode object.
|
|
//-----------------------------------------------------------------------------
|
|
static int StringBuffer_FromUnicode(
|
|
udt_StringBuffer *buf, // buffer to fill
|
|
PyObject *obj) // unicode object expected
|
|
{
|
|
if (!obj)
|
|
return StringBuffer_Init(buf);
|
|
#ifdef Py_UNICODE_WIDE
|
|
int one = 1;
|
|
int byteOrder = (IS_LITTLE_ENDIAN) ? -1 : 1;
|
|
buf->encodedString = PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(obj),
|
|
PyUnicode_GET_SIZE(obj), NULL, byteOrder);
|
|
if (!buf->encodedString)
|
|
return -1;
|
|
buf->ptr = PyBytes_AS_STRING(buf->encodedString);
|
|
buf->size = PyBytes_GET_SIZE(buf->encodedString);
|
|
#else
|
|
buf->ptr = (char*) PyUnicode_AS_UNICODE(obj);
|
|
buf->size = PyUnicode_GET_DATA_SIZE(obj);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// StringBuffer_FromBytes()
|
|
// Populate the string buffer from a bytes object.
|
|
//-----------------------------------------------------------------------------
|
|
static int StringBuffer_FromBytes(
|
|
udt_StringBuffer *buf, // buffer to fill
|
|
PyObject *obj) // bytes object expected
|
|
{
|
|
if (!obj)
|
|
return StringBuffer_Init(buf);
|
|
buf->ptr = PyBytes_AS_STRING(obj);
|
|
buf->size = PyBytes_GET_SIZE(obj);
|
|
#ifdef Py_UNICODE_WIDE
|
|
buf->encodedString = NULL;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
|
|
#if PY_MAJOR_VERSION < 3
|
|
//-----------------------------------------------------------------------------
|
|
// StringBuffer_FromBuffer()
|
|
// Populate the string buffer from a buffer object.
|
|
//-----------------------------------------------------------------------------
|
|
static int StringBuffer_FromBuffer(
|
|
udt_StringBuffer *buf, // buffer to fill
|
|
PyObject *obj) // bytes object expected
|
|
{
|
|
if (!obj)
|
|
return StringBuffer_Init(buf);
|
|
if (PyObject_AsReadBuffer(obj, &buf->ptr, &buf->size) < 0)
|
|
return -1;
|
|
#ifdef Py_UNICODE_WIDE
|
|
buf->encodedString = NULL;
|
|
#endif
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if PY_MAJOR_VERSION >= 3
|
|
#define StringBuffer_FromBinary StringBuffer_FromBytes
|
|
#else
|
|
#define StringBuffer_FromBinary StringBuffer_FromBuffer
|
|
#endif
|
|
|
|
|
|
#ifdef WITH_UNICODE
|
|
#define CXORA_CHARSETID OCI_UTF16ID
|
|
#define CXORA_BYTES_PER_CHAR 2
|
|
#define cxString_Type &PyUnicode_Type
|
|
#define cxString_Format PyUnicode_Format
|
|
#define cxString_Check PyUnicode_Check
|
|
#define cxString_GetSize PyUnicode_GET_SIZE
|
|
#if PY_MAJOR_VERSION >= 3
|
|
#define cxString_FromObject PyObject_Str
|
|
#else
|
|
#define cxString_FromObject PyObject_Unicode
|
|
#endif
|
|
#define cxString_FromAscii(str) \
|
|
PyUnicode_DecodeASCII(str, strlen(str), NULL)
|
|
#ifdef Py_UNICODE_WIDE
|
|
#define StringBuffer_Clear(buffer) \
|
|
Py_XDECREF((buffer)->encodedString)
|
|
#define cxString_FromEncodedString(buffer, numBytes) \
|
|
PyUnicode_DecodeUTF16(buffer, numBytes, NULL, NULL)
|
|
#else
|
|
#define StringBuffer_Clear(buffer)
|
|
#define cxString_FromEncodedString(buffer, numBytes) \
|
|
PyUnicode_FromUnicode((Py_UNICODE*) (buffer), (numBytes) / 2)
|
|
#endif
|
|
#define StringBuffer_Fill StringBuffer_FromUnicode
|
|
#else
|
|
#define CXORA_CHARSETID 0
|
|
#define CXORA_BYTES_PER_CHAR 1
|
|
#define cxString_Type &PyBytes_Type
|
|
#define cxString_Format PyBytes_Format
|
|
#define cxString_Check PyBytes_Check
|
|
#define cxString_GetSize PyBytes_GET_SIZE
|
|
#define cxString_FromObject PyObject_Str
|
|
#define StringBuffer_Clear(buffer)
|
|
#define cxString_FromAscii(str) \
|
|
PyBytes_FromString(str)
|
|
#define cxString_FromEncodedString(buffer, numBytes) \
|
|
PyBytes_FromStringAndSize(buffer, numBytes)
|
|
#define StringBuffer_Fill StringBuffer_FromBytes
|
|
#endif
|
|
|