188 lines
7.3 KiB
C
188 lines
7.3 KiB
C
//-----------------------------------------------------------------------------
|
|
// LongVar.c
|
|
// Defines the routines specific to the long type.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// long type
|
|
//-----------------------------------------------------------------------------
|
|
typedef struct {
|
|
Variable_HEAD
|
|
char *data;
|
|
} udt_LongVar;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// declaration of long variable functions.
|
|
//-----------------------------------------------------------------------------
|
|
static int LongVar_SetValue(udt_LongVar*, unsigned, PyObject*);
|
|
static PyObject *LongVar_GetValue(udt_LongVar*, unsigned);
|
|
static ub4 LongVar_GetBufferSize(udt_LongVar*);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Python type declarations
|
|
//-----------------------------------------------------------------------------
|
|
static PyTypeObject g_LongStringVarType = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
"cx_Oracle.LONG_STRING", // tp_name
|
|
sizeof(udt_LongVar), // tp_basicsize
|
|
0, // tp_itemsize
|
|
0, // tp_dealloc
|
|
0, // tp_print
|
|
0, // tp_getattr
|
|
0, // tp_setattr
|
|
0, // tp_compare
|
|
0, // tp_repr
|
|
0, // tp_as_number
|
|
0, // tp_as_sequence
|
|
0, // tp_as_mapping
|
|
0, // tp_hash
|
|
0, // tp_call
|
|
0, // tp_str
|
|
0, // tp_getattro
|
|
0, // tp_setattro
|
|
0, // tp_as_buffer
|
|
Py_TPFLAGS_DEFAULT, // tp_flags
|
|
0 // tp_doc
|
|
};
|
|
|
|
|
|
static PyTypeObject g_LongBinaryVarType = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
"cx_Oracle.LONG_BINARY", // tp_name
|
|
sizeof(udt_LongVar), // tp_basicsize
|
|
0, // tp_itemsize
|
|
0, // tp_dealloc
|
|
0, // tp_print
|
|
0, // tp_getattr
|
|
0, // tp_setattr
|
|
0, // tp_compare
|
|
0, // tp_repr
|
|
0, // tp_as_number
|
|
0, // tp_as_sequence
|
|
0, // tp_as_mapping
|
|
0, // tp_hash
|
|
0, // tp_call
|
|
0, // tp_str
|
|
0, // tp_getattro
|
|
0, // tp_setattro
|
|
0, // tp_as_buffer
|
|
Py_TPFLAGS_DEFAULT, // tp_flags
|
|
0 // tp_doc
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// variable type declarations
|
|
//-----------------------------------------------------------------------------
|
|
static udt_VariableType vt_LongString = {
|
|
(InitializeProc) NULL,
|
|
(FinalizeProc) NULL,
|
|
(PreDefineProc) NULL,
|
|
(PostDefineProc) NULL,
|
|
(PreFetchProc) NULL,
|
|
(IsNullProc) NULL,
|
|
(SetValueProc) LongVar_SetValue,
|
|
(GetValueProc) LongVar_GetValue,
|
|
(GetBufferSizeProc) LongVar_GetBufferSize,
|
|
&g_LongStringVarType, // Python type
|
|
SQLT_LVC, // Oracle type
|
|
SQLCS_IMPLICIT, // charset form
|
|
128 * 1024, // element length (default)
|
|
1, // is character data
|
|
1, // is variable length
|
|
1, // can be copied
|
|
0 // can be in array
|
|
};
|
|
|
|
|
|
static udt_VariableType vt_LongBinary = {
|
|
(InitializeProc) NULL,
|
|
(FinalizeProc) NULL,
|
|
(PreDefineProc) NULL,
|
|
(PostDefineProc) NULL,
|
|
(PreFetchProc) NULL,
|
|
(IsNullProc) NULL,
|
|
(SetValueProc) LongVar_SetValue,
|
|
(GetValueProc) LongVar_GetValue,
|
|
(GetBufferSizeProc) LongVar_GetBufferSize,
|
|
&g_LongBinaryVarType, // Python type
|
|
SQLT_LVB, // Oracle type
|
|
SQLCS_IMPLICIT, // charset form
|
|
128 * 1024, // element length (default)
|
|
0, // is character data
|
|
1, // is variable length
|
|
1, // can be copied
|
|
0 // can be in array
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// LongVar_SetValue()
|
|
// Set the value of the variable.
|
|
//-----------------------------------------------------------------------------
|
|
static int LongVar_SetValue(
|
|
udt_LongVar *var, // variable to set value for
|
|
unsigned pos, // array position to set
|
|
PyObject *value) // value to set
|
|
{
|
|
udt_Buffer buffer;
|
|
char *ptr;
|
|
|
|
// get the buffer data and size for binding
|
|
if (cxBuffer_FromObject(&buffer, value, var->environment->encoding) < 0)
|
|
return -1;
|
|
|
|
// verify there is enough space to store the value
|
|
if (buffer.numCharacters > var->size) {
|
|
if (Variable_Resize((udt_Variable*) var, buffer.numCharacters) < 0) {
|
|
cxBuffer_Clear(&buffer);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// copy the string to the Oracle buffer
|
|
ptr = var->data + var->bufferSize * pos;
|
|
*((ub4 *) ptr) = (ub4) buffer.size;
|
|
if (buffer.size)
|
|
memcpy(ptr + sizeof(ub4), buffer.ptr, buffer.size);
|
|
cxBuffer_Clear(&buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// LongVar_GetValue()
|
|
// Returns the value stored at the given array position.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *LongVar_GetValue(
|
|
udt_LongVar *var, // variable to determine value for
|
|
unsigned pos) // array position
|
|
{
|
|
char *ptr;
|
|
ub4 size;
|
|
|
|
ptr = var->data + var->bufferSize * pos;
|
|
size = *((ub4 *) ptr);
|
|
ptr += sizeof(ub4);
|
|
if (var->type == &vt_LongBinary)
|
|
return PyBytes_FromStringAndSize(ptr, size);
|
|
return cxString_FromEncodedString(ptr, size, var->environment->encoding);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// LongVar_GetBufferSize()
|
|
// Returns the size of the buffer to use for data of the given size.
|
|
//-----------------------------------------------------------------------------
|
|
static ub4 LongVar_GetBufferSize(
|
|
udt_LongVar *self) // variable to get buffer size
|
|
{
|
|
if (!self->type->isCharacterData)
|
|
return self->size + sizeof(ub4);
|
|
return sizeof(ub4) + self->size * self->environment->maxBytesPerCharacter;
|
|
}
|
|
|