LongVar.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //-----------------------------------------------------------------------------
  2. // LongVar.c
  3. // Defines the routines specific to the long type.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // long type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. Variable_HEAD
  10. char *data;
  11. } udt_LongVar;
  12. //-----------------------------------------------------------------------------
  13. // declaration of long variable functions.
  14. //-----------------------------------------------------------------------------
  15. static int LongVar_SetValue(udt_LongVar*, unsigned, PyObject*);
  16. static PyObject *LongVar_GetValue(udt_LongVar*, unsigned);
  17. static ub4 LongVar_GetBufferSize(udt_LongVar*);
  18. //-----------------------------------------------------------------------------
  19. // Python type declarations
  20. //-----------------------------------------------------------------------------
  21. static PyTypeObject g_LongStringVarType = {
  22. PyVarObject_HEAD_INIT(NULL, 0)
  23. "cx_Oracle.LONG_STRING", // tp_name
  24. sizeof(udt_LongVar), // tp_basicsize
  25. 0, // tp_itemsize
  26. 0, // tp_dealloc
  27. 0, // tp_print
  28. 0, // tp_getattr
  29. 0, // tp_setattr
  30. 0, // tp_compare
  31. 0, // tp_repr
  32. 0, // tp_as_number
  33. 0, // tp_as_sequence
  34. 0, // tp_as_mapping
  35. 0, // tp_hash
  36. 0, // tp_call
  37. 0, // tp_str
  38. 0, // tp_getattro
  39. 0, // tp_setattro
  40. 0, // tp_as_buffer
  41. Py_TPFLAGS_DEFAULT, // tp_flags
  42. 0 // tp_doc
  43. };
  44. static PyTypeObject g_LongNCharVarType = {
  45. PyVarObject_HEAD_INIT(NULL, 0)
  46. "cx_Oracle.LONG_NCHAR", // tp_name
  47. sizeof(udt_LongVar), // tp_basicsize
  48. 0, // tp_itemsize
  49. 0, // tp_dealloc
  50. 0, // tp_print
  51. 0, // tp_getattr
  52. 0, // tp_setattr
  53. 0, // tp_compare
  54. 0, // tp_repr
  55. 0, // tp_as_number
  56. 0, // tp_as_sequence
  57. 0, // tp_as_mapping
  58. 0, // tp_hash
  59. 0, // tp_call
  60. 0, // tp_str
  61. 0, // tp_getattro
  62. 0, // tp_setattro
  63. 0, // tp_as_buffer
  64. Py_TPFLAGS_DEFAULT, // tp_flags
  65. 0 // tp_doc
  66. };
  67. static PyTypeObject g_LongBinaryVarType = {
  68. PyVarObject_HEAD_INIT(NULL, 0)
  69. "cx_Oracle.LONG_BINARY", // tp_name
  70. sizeof(udt_LongVar), // tp_basicsize
  71. 0, // tp_itemsize
  72. 0, // tp_dealloc
  73. 0, // tp_print
  74. 0, // tp_getattr
  75. 0, // tp_setattr
  76. 0, // tp_compare
  77. 0, // tp_repr
  78. 0, // tp_as_number
  79. 0, // tp_as_sequence
  80. 0, // tp_as_mapping
  81. 0, // tp_hash
  82. 0, // tp_call
  83. 0, // tp_str
  84. 0, // tp_getattro
  85. 0, // tp_setattro
  86. 0, // tp_as_buffer
  87. Py_TPFLAGS_DEFAULT, // tp_flags
  88. 0 // tp_doc
  89. };
  90. //-----------------------------------------------------------------------------
  91. // variable type declarations
  92. //-----------------------------------------------------------------------------
  93. static udt_VariableType vt_LongString = {
  94. (InitializeProc) NULL,
  95. (FinalizeProc) NULL,
  96. (PreDefineProc) NULL,
  97. (PostDefineProc) NULL,
  98. (PreFetchProc) NULL,
  99. (IsNullProc) NULL,
  100. (SetValueProc) LongVar_SetValue,
  101. (GetValueProc) LongVar_GetValue,
  102. (GetBufferSizeProc) LongVar_GetBufferSize,
  103. &g_LongStringVarType, // Python type
  104. SQLT_LVC, // Oracle type
  105. SQLCS_IMPLICIT, // charset form
  106. 128 * 1024, // element length (default)
  107. 1, // is character data
  108. 1, // is variable length
  109. 1, // can be copied
  110. 0 // can be in array
  111. };
  112. static udt_VariableType vt_LongNationalCharString = {
  113. (InitializeProc) NULL,
  114. (FinalizeProc) NULL,
  115. (PreDefineProc) NULL,
  116. (PostDefineProc) NULL,
  117. (PreFetchProc) NULL,
  118. (IsNullProc) NULL,
  119. (SetValueProc) LongVar_SetValue,
  120. (GetValueProc) LongVar_GetValue,
  121. (GetBufferSizeProc) LongVar_GetBufferSize,
  122. &g_LongNCharVarType, // Python type
  123. SQLT_LVC, // Oracle type
  124. SQLCS_NCHAR, // charset form
  125. 128 * 1024, // element length (default)
  126. 1, // is character data
  127. 1, // is variable length
  128. 1, // can be copied
  129. 0 // can be in array
  130. };
  131. static udt_VariableType vt_LongBinary = {
  132. (InitializeProc) NULL,
  133. (FinalizeProc) NULL,
  134. (PreDefineProc) NULL,
  135. (PostDefineProc) NULL,
  136. (PreFetchProc) NULL,
  137. (IsNullProc) NULL,
  138. (SetValueProc) LongVar_SetValue,
  139. (GetValueProc) LongVar_GetValue,
  140. (GetBufferSizeProc) LongVar_GetBufferSize,
  141. &g_LongBinaryVarType, // Python type
  142. SQLT_LVB, // Oracle type
  143. SQLCS_IMPLICIT, // charset form
  144. 128 * 1024, // element length (default)
  145. 0, // is character data
  146. 1, // is variable length
  147. 1, // can be copied
  148. 0 // can be in array
  149. };
  150. //-----------------------------------------------------------------------------
  151. // LongVar_SetValue()
  152. // Set the value of the variable.
  153. //-----------------------------------------------------------------------------
  154. static int LongVar_SetValue(
  155. udt_LongVar *var, // variable to set value for
  156. unsigned pos, // array position to set
  157. PyObject *value) // value to set
  158. {
  159. udt_Buffer buffer;
  160. char *ptr;
  161. // get the buffer data and size for binding
  162. if (cxBuffer_FromObject(&buffer, value, var->environment->encoding) < 0)
  163. return -1;
  164. // verify there is enough space to store the value
  165. if (buffer.numCharacters > var->size) {
  166. if (Variable_Resize((udt_Variable*) var, buffer.numCharacters) < 0) {
  167. cxBuffer_Clear(&buffer);
  168. return -1;
  169. }
  170. }
  171. // copy the string to the Oracle buffer
  172. ptr = var->data + var->bufferSize * pos;
  173. *((ub4 *) ptr) = (ub4) buffer.size;
  174. if (buffer.size)
  175. memcpy(ptr + sizeof(ub4), buffer.ptr, buffer.size);
  176. cxBuffer_Clear(&buffer);
  177. return 0;
  178. }
  179. //-----------------------------------------------------------------------------
  180. // LongVar_GetValue()
  181. // Returns the value stored at the given array position.
  182. //-----------------------------------------------------------------------------
  183. static PyObject *LongVar_GetValue(
  184. udt_LongVar *var, // variable to determine value for
  185. unsigned pos) // array position
  186. {
  187. char *ptr;
  188. ub4 size;
  189. ptr = var->data + var->bufferSize * pos;
  190. size = *((ub4 *) ptr);
  191. ptr += sizeof(ub4);
  192. if (var->type == &vt_LongBinary)
  193. return PyBytes_FromStringAndSize(ptr, size);
  194. return cxString_FromEncodedString(ptr, size, var->environment->encoding);
  195. }
  196. //-----------------------------------------------------------------------------
  197. // LongVar_GetBufferSize()
  198. // Returns the size of the buffer to use for data of the given size.
  199. //-----------------------------------------------------------------------------
  200. static ub4 LongVar_GetBufferSize(
  201. udt_LongVar *self) // variable to get buffer size
  202. {
  203. if (!self->type->isCharacterData)
  204. return self->size + sizeof(ub4);
  205. return sizeof(ub4) + self->size * self->environment->maxBytesPerCharacter;
  206. }