| timbo@cvs.perl.org 2005-06-03, 8:27 pm |
| Author: timbo
Date: Mon Oct 18 16:03:24 2004
New Revision: 498
Modified:
dbd-oracle/trunk/oci8.c
Log:
Fix ora_blob_read_piece to grow buffer more to allow for char->byte growth.
[Still leaves ora_blob_read_piece ununified with ora_blob_mb_read_pie
ce,
which needs to be fixed one day.]
Modified: dbd-oracle/trunk/oci8.c
====================
====================
====================
==================
--- dbd-oracle/trunk/oci8.c (original)
+++ dbd-oracle/trunk/oci8.c Mon Oct 18 16:03:24 2004
@@ -747,11 +747,17 @@
ub4 loblen = 0;
ub4 buflen;
ub4 amtp = 0;
+ ub1 csform = 0;
OCILobLocator *lobl = (OCILobLocator*)fbh->desc_h;
sword ftype = fbh->ftype;
sword status;
+ char *typename;
- if (ftype != 112 && ftype != 113) {
+ if (ftype == 112)
+ typename = "CLOB";
+ else if (ftype == 113)
+ typename = "BLOB";
+ else {
oci_error(sth, imp_sth->errhp, OCI_ERROR,
"blob_read not currently supported for non-LOB types with OCI 8 "
"(but with OCI 8 you can set $dbh->{LongReadLen} to the length you need,"
@@ -767,8 +773,14 @@
return 0;
}
- amtp = (loblen > len) ? len : loblen;
- buflen = amtp; /* set right semantics for OCILobRead */
+ OCILobCharSetForm_lo
g_stat( imp_sth->envhp, imp_sth->errhp, lobl, &csform, status );
+ if (status != OCI_SUCCESS) {
+ oci_error(sth, imp_sth->errhp, status, "OCILobCharSetForm");
+ sv_set_undef(dest_
sv); /* signal error */
+ return 0;
+ }
+ if (ftype == 112 && csform == SQLCS_NCHAR)
+ typename = "NCLOB";
/*
* We assume our caller has already done the
@@ -777,26 +789,51 @@
* SvGROW(dest_sv, buflen+destoffset+1)
;
*/
+ /* amtp is: LOB/BFILE CLOB/NCLOB
+ Input bytes characters
+ Output FW bytes characters (FW=Fixed Width charset, VW=Variable)
+ Output VW bytes characters(in), bytes returned (afterwards)
+ */
+ amtp = (loblen > len) ? len : loblen;
+
+ /* buflen: length of buffer in bytes */
+ /* so for CLOBs that'll be returned as UTF8 we need more bytes that chars */
+ /* XXX the x4 here isn't perfect - really the code should be changed to loop */
+ if (ftype == 112 && CSFORM_IMPLIES_UTF8(
csform)) {
+ buflen = amtp * 4;
+ /* XXX destoffset would be counting chars here as well */
+ SvGROW(dest_sv, (destoffset*4) + buflen + 1);
+ if (destoffset) {
+ oci_error(sth, imp_sth->errhp, OCI_ERROR,
+ "blob_read with non-zero destoffset not currently supported for UTF8 values");
+ sv_set_undef(dest_sv
); /* signal error */
+ return 0;
+ }
+ }
+ else {
+ buflen = amtp;
+ }
+
+ if (DBIS->debug >= 3)
+ PerlIO_printf(DBIL
OGFP,
+ " blob_read field %d: ftype %d %s, offset %ld, len %lu."
+ "LOB csform %d, len %lu, amtp %lu, (destoffset=%ld)\n",
+ fbh->field_num+1, ftype, typename, offset, ul_t(len),
+ csform, loblen, ul_t(amtp), destoffset);
+
if (loblen > 0) {
- ub1 csform = 0;
ub1 * bufp = (ub1 *)(SvPVX(dest_sv));
bufp += destoffset;
- OCILobCharSetForm_lo
g_stat( imp_sth->envhp, imp_sth->errhp, lobl, &csform, status );
- if (status != OCI_SUCCESS) {
- oci_error(sth, imp_sth->errhp, status, "OCILobCharSetForm");
- sv_set_undef(dest_sv
); /* signal error */
- return 0;
- }
-
OCILobRead_log_stat(
imp_sth->svchp, imp_sth->errhp, lobl,
&amtp, (ub4)1 + offset, bufp, buflen,
0, 0, (ub2)0 , csform, status);
+
if (DBIS->debug >= 3)
PerlIO_printf(DBILOG
FP,
- " OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu (csform=%d)\n",
+ " OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, amtp %lu\n",
fbh->field_num+1, oci_status_name(stat
us), ul_t(loblen),
- ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp), csform);
+ ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
if (status != OCI_SUCCESS) {
oci_error(sth, imp_sth->errhp, status, "OCILobRead");
sv_set_undef(dest_sv
); /* signal error */
|