LongVar.c 9.3 KB

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