StringVar.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. //-----------------------------------------------------------------------------
  2. // StringVar.c
  3. // Defines the routines specific to the string type.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // String type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. Variable_HEAD
  10. char *data;
  11. } udt_StringVar;
  12. //-----------------------------------------------------------------------------
  13. // Declaration of string variable functions.
  14. //-----------------------------------------------------------------------------
  15. static int StringVar_Initialize(udt_StringVar*, udt_Cursor*);
  16. static int StringVar_SetValue(udt_StringVar*, unsigned, PyObject*);
  17. static PyObject *StringVar_GetValue(udt_StringVar*, unsigned);
  18. #if PY_MAJOR_VERSION < 3
  19. static int StringVar_PostDefine(udt_StringVar*);
  20. #endif
  21. static ub4 StringVar_GetBufferSize(udt_StringVar*);
  22. //-----------------------------------------------------------------------------
  23. // Python type declarations
  24. //-----------------------------------------------------------------------------
  25. static PyTypeObject g_StringVarType = {
  26. PyVarObject_HEAD_INIT(NULL, 0)
  27. "cx_Oracle.STRING", // tp_name
  28. sizeof(udt_StringVar), // tp_basicsize
  29. 0, // tp_itemsize
  30. 0, // tp_dealloc
  31. 0, // tp_print
  32. 0, // tp_getattr
  33. 0, // tp_setattr
  34. 0, // tp_compare
  35. 0, // tp_repr
  36. 0, // tp_as_number
  37. 0, // tp_as_sequence
  38. 0, // tp_as_mapping
  39. 0, // tp_hash
  40. 0, // tp_call
  41. 0, // tp_str
  42. 0, // tp_getattro
  43. 0, // tp_setattro
  44. 0, // tp_as_buffer
  45. Py_TPFLAGS_DEFAULT, // tp_flags
  46. 0 // tp_doc
  47. };
  48. #if PY_MAJOR_VERSION < 3
  49. static PyTypeObject g_UnicodeVarType = {
  50. PyVarObject_HEAD_INIT(NULL, 0)
  51. "cx_Oracle.UNICODE", // tp_name
  52. sizeof(udt_StringVar), // tp_basicsize
  53. 0, // tp_itemsize
  54. 0, // tp_dealloc
  55. 0, // tp_print
  56. 0, // tp_getattr
  57. 0, // tp_setattr
  58. 0, // tp_compare
  59. 0, // tp_repr
  60. 0, // tp_as_number
  61. 0, // tp_as_sequence
  62. 0, // tp_as_mapping
  63. 0, // tp_hash
  64. 0, // tp_call
  65. 0, // tp_str
  66. 0, // tp_getattro
  67. 0, // tp_setattro
  68. 0, // tp_as_buffer
  69. Py_TPFLAGS_DEFAULT, // tp_flags
  70. 0 // tp_doc
  71. };
  72. #endif
  73. static PyTypeObject g_FixedCharVarType = {
  74. PyVarObject_HEAD_INIT(NULL, 0)
  75. "cx_Oracle.FIXED_CHAR", // tp_name
  76. sizeof(udt_StringVar), // tp_basicsize
  77. 0, // tp_itemsize
  78. 0, // tp_dealloc
  79. 0, // tp_print
  80. 0, // tp_getattr
  81. 0, // tp_setattr
  82. 0, // tp_compare
  83. 0, // tp_repr
  84. 0, // tp_as_number
  85. 0, // tp_as_sequence
  86. 0, // tp_as_mapping
  87. 0, // tp_hash
  88. 0, // tp_call
  89. 0, // tp_str
  90. 0, // tp_getattro
  91. 0, // tp_setattro
  92. 0, // tp_as_buffer
  93. Py_TPFLAGS_DEFAULT, // tp_flags
  94. 0 // tp_doc
  95. };
  96. #if PY_MAJOR_VERSION < 3
  97. static PyTypeObject g_FixedUnicodeVarType = {
  98. PyVarObject_HEAD_INIT(NULL, 0)
  99. "cx_Oracle.FIXED_UNICODE", // tp_name
  100. sizeof(udt_StringVar), // tp_basicsize
  101. 0, // tp_itemsize
  102. 0, // tp_dealloc
  103. 0, // tp_print
  104. 0, // tp_getattr
  105. 0, // tp_setattr
  106. 0, // tp_compare
  107. 0, // tp_repr
  108. 0, // tp_as_number
  109. 0, // tp_as_sequence
  110. 0, // tp_as_mapping
  111. 0, // tp_hash
  112. 0, // tp_call
  113. 0, // tp_str
  114. 0, // tp_getattro
  115. 0, // tp_setattro
  116. 0, // tp_as_buffer
  117. Py_TPFLAGS_DEFAULT, // tp_flags
  118. 0 // tp_doc
  119. };
  120. #endif
  121. static PyTypeObject g_RowidVarType = {
  122. PyVarObject_HEAD_INIT(NULL, 0)
  123. "cx_Oracle.ROWID", // tp_name
  124. sizeof(udt_StringVar), // tp_basicsize
  125. 0, // tp_itemsize
  126. 0, // tp_dealloc
  127. 0, // tp_print
  128. 0, // tp_getattr
  129. 0, // tp_setattr
  130. 0, // tp_compare
  131. 0, // tp_repr
  132. 0, // tp_as_number
  133. 0, // tp_as_sequence
  134. 0, // tp_as_mapping
  135. 0, // tp_hash
  136. 0, // tp_call
  137. 0, // tp_str
  138. 0, // tp_getattro
  139. 0, // tp_setattro
  140. 0, // tp_as_buffer
  141. Py_TPFLAGS_DEFAULT, // tp_flags
  142. 0 // tp_doc
  143. };
  144. static PyTypeObject g_BinaryVarType = {
  145. PyVarObject_HEAD_INIT(NULL, 0)
  146. "cx_Oracle.BINARY", // tp_name
  147. sizeof(udt_StringVar), // tp_basicsize
  148. 0, // tp_itemsize
  149. 0, // tp_dealloc
  150. 0, // tp_print
  151. 0, // tp_getattr
  152. 0, // tp_setattr
  153. 0, // tp_compare
  154. 0, // tp_repr
  155. 0, // tp_as_number
  156. 0, // tp_as_sequence
  157. 0, // tp_as_mapping
  158. 0, // tp_hash
  159. 0, // tp_call
  160. 0, // tp_str
  161. 0, // tp_getattro
  162. 0, // tp_setattro
  163. 0, // tp_as_buffer
  164. Py_TPFLAGS_DEFAULT, // tp_flags
  165. 0 // tp_doc
  166. };
  167. //-----------------------------------------------------------------------------
  168. // variable type declarations
  169. //-----------------------------------------------------------------------------
  170. static udt_VariableType vt_String = {
  171. (InitializeProc) StringVar_Initialize,
  172. (FinalizeProc) NULL,
  173. (PreDefineProc) NULL,
  174. (PostDefineProc) NULL,
  175. (PreFetchProc) NULL,
  176. (IsNullProc) NULL,
  177. (SetValueProc) StringVar_SetValue,
  178. (GetValueProc) StringVar_GetValue,
  179. (GetBufferSizeProc) StringVar_GetBufferSize,
  180. &g_StringVarType, // Python type
  181. SQLT_CHR, // Oracle type
  182. SQLCS_IMPLICIT, // charset form
  183. MAX_STRING_CHARS, // element length (default)
  184. 1, // is character data
  185. 1, // is variable length
  186. 1, // can be copied
  187. 1 // can be in array
  188. };
  189. #if PY_MAJOR_VERSION < 3
  190. static udt_VariableType vt_NationalCharString = {
  191. (InitializeProc) StringVar_Initialize,
  192. (FinalizeProc) NULL,
  193. (PreDefineProc) NULL,
  194. (PostDefineProc) StringVar_PostDefine,
  195. (PreFetchProc) NULL,
  196. (IsNullProc) NULL,
  197. (SetValueProc) StringVar_SetValue,
  198. (GetValueProc) StringVar_GetValue,
  199. (GetBufferSizeProc) StringVar_GetBufferSize,
  200. &g_UnicodeVarType, // Python type
  201. SQLT_CHR, // Oracle type
  202. SQLCS_NCHAR, // charset form
  203. MAX_STRING_CHARS, // element length (default)
  204. 1, // is character data
  205. 1, // is variable length
  206. 1, // can be copied
  207. 1 // can be in array
  208. };
  209. #endif
  210. static udt_VariableType vt_FixedChar = {
  211. (InitializeProc) StringVar_Initialize,
  212. (FinalizeProc) NULL,
  213. (PreDefineProc) NULL,
  214. (PostDefineProc) NULL,
  215. (PreFetchProc) NULL,
  216. (IsNullProc) NULL,
  217. (SetValueProc) StringVar_SetValue,
  218. (GetValueProc) StringVar_GetValue,
  219. (GetBufferSizeProc) StringVar_GetBufferSize,
  220. &g_FixedCharVarType, // Python type
  221. SQLT_AFC, // Oracle type
  222. SQLCS_IMPLICIT, // charset form
  223. 2000, // element length (default)
  224. 1, // is character data
  225. 1, // is variable length
  226. 1, // can be copied
  227. 1 // can be in array
  228. };
  229. #if PY_MAJOR_VERSION < 3
  230. static udt_VariableType vt_FixedNationalChar = {
  231. (InitializeProc) StringVar_Initialize,
  232. (FinalizeProc) NULL,
  233. (PreDefineProc) NULL,
  234. (PostDefineProc) StringVar_PostDefine,
  235. (PreFetchProc) NULL,
  236. (IsNullProc) NULL,
  237. (SetValueProc) StringVar_SetValue,
  238. (GetValueProc) StringVar_GetValue,
  239. (GetBufferSizeProc) StringVar_GetBufferSize,
  240. &g_FixedUnicodeVarType, // Python type
  241. SQLT_AFC, // Oracle type
  242. SQLCS_NCHAR, // charset form
  243. 2000, // element length (default)
  244. 1, // is character data
  245. 1, // is variable length
  246. 1, // can be copied
  247. 1 // can be in array
  248. };
  249. #endif
  250. static udt_VariableType vt_Rowid = {
  251. (InitializeProc) StringVar_Initialize,
  252. (FinalizeProc) NULL,
  253. (PreDefineProc) NULL,
  254. (PostDefineProc) NULL,
  255. (PreFetchProc) NULL,
  256. (IsNullProc) NULL,
  257. (SetValueProc) StringVar_SetValue,
  258. (GetValueProc) StringVar_GetValue,
  259. (GetBufferSizeProc) StringVar_GetBufferSize,
  260. &g_RowidVarType, // Python type
  261. SQLT_CHR, // Oracle type
  262. SQLCS_IMPLICIT, // charset form
  263. 18, // element length (default)
  264. 1, // is character data
  265. 0, // is variable length
  266. 1, // can be copied
  267. 1 // can be in array
  268. };
  269. static udt_VariableType vt_Binary = {
  270. (InitializeProc) StringVar_Initialize,
  271. (FinalizeProc) NULL,
  272. (PreDefineProc) NULL,
  273. (PostDefineProc) NULL,
  274. (PreFetchProc) NULL,
  275. (IsNullProc) NULL,
  276. (SetValueProc) StringVar_SetValue,
  277. (GetValueProc) StringVar_GetValue,
  278. (GetBufferSizeProc) NULL,
  279. &g_BinaryVarType, // Python type
  280. SQLT_BIN, // Oracle type
  281. SQLCS_IMPLICIT, // charset form
  282. MAX_BINARY_BYTES, // element length (default)
  283. 0, // is character data
  284. 1, // is variable length
  285. 1, // can be copied
  286. 1 // can be in array
  287. };
  288. //-----------------------------------------------------------------------------
  289. // StringVar_Initialize()
  290. // Initialize the variable.
  291. //-----------------------------------------------------------------------------
  292. static int StringVar_Initialize(
  293. udt_StringVar *var, // variable to initialize
  294. udt_Cursor *cursor) // cursor to use
  295. {
  296. var->actualLength = (ub2*) PyMem_Malloc(var->allocatedElements *
  297. sizeof(ub2));
  298. if (!var->actualLength) {
  299. PyErr_NoMemory();
  300. return -1;
  301. }
  302. return 0;
  303. }
  304. //-----------------------------------------------------------------------------
  305. // StringVar_SetValue()
  306. // Set the value of the variable.
  307. //-----------------------------------------------------------------------------
  308. static int StringVar_SetValue(
  309. udt_StringVar *var, // variable to set value for
  310. unsigned pos, // array position to set
  311. PyObject *value) // value to set
  312. {
  313. udt_Buffer buffer;
  314. // populate the buffer and confirm the maximum size is not exceeded
  315. if (cxBuffer_FromObject(&buffer, value, var->environment->encoding) < 0)
  316. return -1;
  317. if (var->type->isCharacterData
  318. && buffer.numCharacters > MAX_STRING_CHARS) {
  319. cxBuffer_Clear(&buffer);
  320. PyErr_SetString(PyExc_ValueError, "string data too large");
  321. return -1;
  322. } else if (!var->type->isCharacterData
  323. && buffer.size > MAX_BINARY_BYTES) {
  324. cxBuffer_Clear(&buffer);
  325. PyErr_SetString(PyExc_ValueError, "binary data too large");
  326. return -1;
  327. }
  328. // ensure that the buffer is large enough
  329. if (buffer.size > var->bufferSize) {
  330. if (Variable_Resize( (udt_Variable*) var, buffer.numCharacters) < 0) {
  331. cxBuffer_Clear(&buffer);
  332. return -1;
  333. }
  334. }
  335. // keep a copy of the string
  336. var->actualLength[pos] = (ub2) buffer.size;
  337. if (buffer.size)
  338. memcpy(var->data + var->bufferSize * pos, buffer.ptr, buffer.size);
  339. cxBuffer_Clear(&buffer);
  340. return 0;
  341. }
  342. //-----------------------------------------------------------------------------
  343. // StringVar_GetValue()
  344. // Returns the value stored at the given array position.
  345. //-----------------------------------------------------------------------------
  346. static PyObject *StringVar_GetValue(
  347. udt_StringVar *var, // variable to determine value for
  348. unsigned pos) // array position
  349. {
  350. char *data;
  351. data = var->data + pos * var->bufferSize;
  352. if (var->type == &vt_Binary)
  353. return PyBytes_FromStringAndSize(data, var->actualLength[pos]);
  354. #if PY_MAJOR_VERSION < 3
  355. if (var->type == &vt_FixedNationalChar
  356. || var->type == &vt_NationalCharString)
  357. return PyUnicode_Decode(data, var->actualLength[pos],
  358. var->environment->nencoding, NULL);
  359. #endif
  360. return cxString_FromEncodedString(data, var->actualLength[pos],
  361. var->environment->encoding);
  362. }
  363. #if PY_MAJOR_VERSION < 3
  364. //-----------------------------------------------------------------------------
  365. // StringVar_PostDefine()
  366. // Set the character set information when values are fetched from this
  367. // variable.
  368. //-----------------------------------------------------------------------------
  369. static int StringVar_PostDefine(
  370. udt_StringVar *var) // variable to initialize
  371. {
  372. sword status;
  373. status = OCIAttrSet(var->defineHandle, OCI_HTYPE_DEFINE,
  374. &var->type->charsetForm, 0, OCI_ATTR_CHARSET_FORM,
  375. var->environment->errorHandle);
  376. if (Environment_CheckForError(var->environment, status,
  377. "StringVar_PostDefine(): setting charset form") < 0)
  378. return -1;
  379. return 0;
  380. }
  381. #endif
  382. //-----------------------------------------------------------------------------
  383. // StringVar_GetBufferSize()
  384. // Returns the buffer size to use for the variable.
  385. //-----------------------------------------------------------------------------
  386. static ub4 StringVar_GetBufferSize(
  387. udt_StringVar* self) // variable to get buffer size for
  388. {
  389. if (self->type->isCharacterData)
  390. return self->size * self->environment->maxBytesPerCharacter;
  391. return self->size;
  392. }