OCILIB (C Driver for Oracle) 3.9.1
D:/Perso/dev/ocilib/ocilib/src/lob.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: lob.c, v 3.9.1 2011-07-08 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_LobInit
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Lob * OCI_LobInit
00046 (
00047     OCI_Connection *con,
00048     OCI_Lob       **plob,
00049     OCILobLocator  *handle,
00050     ub4             type
00051 )
00052 {
00053     ub2 csid      = OCI_DEFAULT;
00054     ub1 csfrm     = OCI_DEFAULT;
00055     OCI_Lob * lob = NULL;
00056     boolean res   = TRUE;
00057     ub1 lobtype   = 0;
00058 
00059     OCI_CHECK(plob == NULL, NULL);
00060 
00061     if (*plob == NULL)
00062     {
00063         *plob = (OCI_Lob *) OCI_MemAlloc(OCI_IPC_LOB, sizeof(*lob), (size_t) 1, TRUE);
00064     }
00065 
00066     if (*plob != NULL)
00067     {
00068         lob = *plob;
00069 
00070         lob->type   = type;
00071         lob->con    = con;
00072         lob->handle = handle;
00073         lob->offset = 1;
00074 
00075         if ((lob->handle == NULL) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY))
00076         {
00077             ub4 empty = 0;
00078 
00079             if (lob->type == OCI_NCLOB)
00080             {
00081                 csfrm   = SQLCS_NCHAR;
00082                 lobtype = OCI_TEMP_CLOB;
00083             }
00084             else if (lob->type == OCI_CLOB)
00085             {
00086                 csfrm   = SQLCS_IMPLICIT;
00087                 lobtype = OCI_TEMP_CLOB;
00088             }
00089             else
00090             {
00091                 lobtype = OCI_TEMP_BLOB;
00092             }
00093 
00094             /* allocate handle for non fetched lob (temporary lob) */
00095 
00096             if (lob->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00097             {
00098                 lob->hstate = OCI_OBJECT_ALLOCATED;
00099 
00100                 res = (OCI_SUCCESS == OCI_DescriptorAlloc((dvoid  *) lob->con->env,
00101                                                           (dvoid **) (void *) &lob->handle,
00102                                                           (ub4) OCI_DTYPE_LOB,
00103                                                           (size_t) 0, (dvoid **) NULL));
00104             }
00105 
00106             OCI_CALL2
00107             (
00108                 res, lob->con,
00109 
00110                 OCIAttrSet((dvoid *) lob->handle, (ub4) OCI_DTYPE_LOB,
00111                            (dvoid *) &empty, (ub4) sizeof(empty),
00112                            (ub4) OCI_ATTR_LOBEMPTY, lob->con->err)
00113             )
00114 
00115             OCI_CALL2
00116             (
00117                 res, lob->con,
00118 
00119                 OCILobCreateTemporary(lob->con->cxt, lob->con->err,
00120                                       lob->handle, csid, csfrm, lobtype,
00121                                       FALSE, OCI_DURATION_SESSION)
00122             )
00123 
00124         }
00125         else
00126         {
00127             lob->hstate = OCI_OBJECT_FETCHED_CLEAN;
00128         }
00129     }
00130     else
00131     {
00132         res = FALSE;
00133     }
00134 
00135     /* check for failure */
00136 
00137     if (res == FALSE)
00138     {
00139         OCI_LobFree(lob);
00140         lob = NULL;
00141     }
00142 
00143     return lob;
00144 }
00145 
00146 /* ********************************************************************************************* *
00147  *                            PUBLIC FUNCTIONS
00148  * ********************************************************************************************* */
00149 
00150 /* --------------------------------------------------------------------------------------------- *
00151  * OCI_LobCreate
00152  * --------------------------------------------------------------------------------------------- */
00153 
00154 OCI_Lob * OCI_API OCI_LobCreate
00155 (
00156     OCI_Connection *con,
00157     unsigned int    type
00158 )
00159 {
00160     OCI_Lob *lob = NULL;
00161 
00162     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00163 
00164     lob = OCI_LobInit(con, &lob, NULL, type);
00165 
00166     OCI_RESULT(lob != NULL);
00167 
00168     return lob;
00169 }
00170 
00171 /* --------------------------------------------------------------------------------------------- *
00172  * OCI_LobFree
00173  * --------------------------------------------------------------------------------------------- */
00174 
00175 boolean OCI_API OCI_LobFree
00176 (
00177     OCI_Lob *lob
00178 )
00179 {
00180     boolean res = TRUE;
00181 
00182     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
00183 
00184     OCI_CHECK_OBJECT_FETCHED(lob, FALSE);
00185 
00186     if (OCI_LobIsTemporary(lob) == TRUE)
00187     {
00188         OCI_CALL2
00189         (
00190             res, lob->con,
00191 
00192             OCILobFreeTemporary(lob->con->cxt, lob->con->err, lob->handle)
00193         )
00194     }
00195 
00196     if (lob->hstate == OCI_OBJECT_ALLOCATED)
00197     {
00198         OCI_DescriptorFree((dvoid *) lob->handle, (ub4) OCI_DTYPE_LOB);
00199     }
00200 
00201     if (lob->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00202     {
00203         OCI_FREE(lob);
00204     }
00205 
00206     OCI_RESULT(res);
00207 
00208     return res;
00209 }
00210 
00211 /* --------------------------------------------------------------------------------------------- *
00212  * OCI_LobArrayCreate
00213  * --------------------------------------------------------------------------------------------- */
00214 
00215 OCI_Lob ** OCI_API OCI_LobArrayCreate
00216 (
00217     OCI_Connection *con,
00218     unsigned int    type,
00219     unsigned int    nbelem
00220 )
00221 {
00222     OCI_Array *arr = NULL;
00223     OCI_Lob **lobs = NULL;
00224 
00225     arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_LOB, type, sizeof(OCILobLocator *),
00226                           sizeof(OCI_Lob), OCI_DTYPE_LOB, NULL);
00227 
00228     if (arr != NULL)
00229     {
00230         lobs = (OCI_Lob **) arr->tab_obj;
00231     }
00232 
00233     return lobs;
00234 }
00235 
00236 /* --------------------------------------------------------------------------------------------- *
00237  * OCI_LobArrayFree
00238  * --------------------------------------------------------------------------------------------- */
00239 
00240 boolean OCI_API OCI_LobArrayFree
00241 (
00242     OCI_Lob **lobs
00243 )
00244 {
00245     return OCI_ArrayFreeFromHandles((void **) lobs);
00246 }
00247 
00248 /* --------------------------------------------------------------------------------------------- *
00249  * OCI_LobGetType
00250  * --------------------------------------------------------------------------------------------- */
00251 
00252 unsigned int OCI_API OCI_LobGetType
00253 (
00254     OCI_Lob *lob
00255 )
00256 {
00257     OCI_CHECK_PTR(OCI_IPC_LOB, lob, OCI_UNKNOWN);
00258 
00259     OCI_RESULT(TRUE);
00260 
00261     return lob->type;
00262 }
00263 
00264 /* --------------------------------------------------------------------------------------------- *
00265  * OCI_LobSeek
00266  * --------------------------------------------------------------------------------------------- */
00267 
00268 boolean OCI_API OCI_LobSeek
00269 (
00270     OCI_Lob     *lob,
00271     big_uint     offset,
00272     unsigned int mode
00273 )
00274 {
00275     boolean res   = TRUE;
00276     big_uint size = 0;
00277 
00278     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
00279 
00280     size = OCI_LobGetLength(lob);
00281 
00282     if ((mode == OCI_SEEK_CUR && (offset + lob->offset-1) > size))
00283     {
00284         res = FALSE;
00285     }
00286     else if (mode == OCI_SEEK_SET)
00287     {
00288         lob->offset = offset + 1;
00289     }
00290     else if (mode == OCI_SEEK_END)
00291     {
00292         lob->offset = size-offset + 1;
00293     }
00294     else if (mode == OCI_SEEK_CUR)
00295     {
00296         lob->offset += offset;
00297     }
00298     else
00299     {
00300         res = FALSE;
00301     }
00302 
00303     OCI_RESULT(res);
00304 
00305     return res;
00306 }
00307 
00308 /* --------------------------------------------------------------------------------------------- *
00309  * OCI_LobGetOffset
00310  * --------------------------------------------------------------------------------------------- */
00311 
00312 big_uint OCI_API OCI_LobGetOffset
00313 (
00314     OCI_Lob *lob
00315 )
00316 {
00317     OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0);
00318 
00319     OCI_RESULT(TRUE);
00320 
00321     return lob->offset - 1;
00322 }
00323 
00324 /* --------------------------------------------------------------------------------------------- *
00325  * OCI_LobRead2
00326  * --------------------------------------------------------------------------------------------- */
00327 
00328 boolean OCI_API OCI_LobRead2
00329 (
00330     OCI_Lob      *lob,
00331     void         *buffer,
00332     unsigned int *char_count,
00333     unsigned int *byte_count
00334 )
00335 {
00336     boolean res = TRUE;
00337     ub2 csid    = 0;
00338     ub1 csfrm   = 0;
00339 
00340     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
00341     OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE);
00342     OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE);
00343 
00344     if (lob->type != OCI_BLOB)
00345     {
00346 
00347     #ifdef OCI_USERDATA_WIDE
00348 
00349         csid = OCI_UTF16ID;
00350 
00351     #endif
00352 
00353         if (((*byte_count) == 0) && ((*char_count) > 0))
00354         {
00355             if (OCILib.nls_utf8 == TRUE)
00356             {
00357                 (*byte_count) = (*char_count) * (ub4) UTF8_BYTES_PER_CHAR;
00358             }
00359             else
00360             {
00361                 (*byte_count) = (*char_count) * (ub4) sizeof(odtext);
00362             }
00363         }
00364     }
00365 
00366     if (lob->type == OCI_NCLOB)
00367     {
00368         csfrm = SQLCS_NCHAR;
00369     }
00370     else
00371     {
00372         csfrm = SQLCS_IMPLICIT;
00373     }
00374 
00375     OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE);
00376 
00377 #ifdef OCI_LOB2_API_ENABLED
00378 
00379     if (OCILib.use_lob_ub8)
00380     {
00381         ub8 size_in_out_char = (ub8) (*char_count);
00382         ub8 size_in_out_byte = (ub8) (*byte_count);
00383 
00384         OCI_CALL2
00385         (
00386             res, lob->con,
00387 
00388             OCILobRead2(lob->con->cxt, lob->con->err, lob->handle,
00389                         &size_in_out_byte, &size_in_out_char,
00390                         (ub8) lob->offset, buffer,(ub8) (*byte_count),
00391                         (ub1) OCI_ONE_PIECE, (void *) NULL,
00392                         NULL, csid, csfrm)
00393         )
00394 
00395         (*char_count) = (ub4) size_in_out_char;
00396         (*byte_count) = (ub4) size_in_out_byte;
00397     }
00398 
00399     else
00400 
00401 #endif
00402 
00403     {
00404         ub4 size_in_out_char_byte = 0;
00405 
00406         if (lob->type == OCI_BLOB)
00407         {
00408             size_in_out_char_byte = (*byte_count);
00409         }
00410         else
00411         {
00412             size_in_out_char_byte = (*char_count);
00413         }
00414 
00415         OCI_CALL2
00416         (
00417             res, lob->con,
00418 
00419             OCILobRead(lob->con->cxt, lob->con->err, lob->handle,
00420                        &size_in_out_char_byte, (ub4) lob->offset,
00421                        buffer, (ub4) (*byte_count), (void *) NULL,
00422                        NULL, csid, csfrm)
00423         )
00424 
00425         (*char_count) = (ub4) size_in_out_char_byte;
00426         (*byte_count) = (ub4) size_in_out_char_byte;
00427     }
00428 
00429     if (lob->type != OCI_BLOB)
00430     {
00431         unsigned int byte_offset = (ub4) (*byte_count);
00432 
00433         if (OCILib.nls_utf8 == FALSE)
00434         {
00435             byte_offset *= sizeof(odtext);
00436         }
00437 
00438         memset(((char *) buffer) + byte_offset, 0, sizeof(odtext));
00439 
00440     #ifndef OCI_LOB2_API_ENABLED
00441 
00442         if (OCILib.nls_utf8 == TRUE)
00443         {
00444             (*char_count) = OCI_StringUTF8Length((const char *) buffer);
00445         }
00446 
00447     #endif
00448 
00449     }
00450 
00451     if (res == TRUE)
00452     {
00453         if (lob->type == OCI_BLOB)
00454         {
00455             lob->offset += (big_uint) (*byte_count);
00456         }
00457         else
00458         {
00459             lob->offset += (big_uint) (*char_count);
00460 
00461             if (OCILib.nls_utf8 == FALSE)
00462             {
00463                 OCI_ConvertString(buffer, (int) (*char_count), sizeof(odtext), sizeof(dtext));
00464             }
00465         }
00466     }
00467 
00468     OCI_RESULT(res);
00469 
00470     return res;
00471 }
00472 
00473 /* --------------------------------------------------------------------------------------------- *
00474  * OCI_LobRead
00475  * --------------------------------------------------------------------------------------------- */
00476 
00477 unsigned int OCI_API OCI_LobRead
00478 (
00479     OCI_Lob     *lob,
00480     void        *buffer,
00481     unsigned int len
00482 )
00483 {
00484     unsigned int char_count = 0;
00485     unsigned int byte_count = 0;
00486     unsigned int *ptr_count = NULL;
00487 
00488     if (lob != NULL)
00489     {
00490         if(lob->type == OCI_BLOB)
00491         {
00492             byte_count = len;
00493             ptr_count  = &byte_count;
00494         }
00495         else
00496         {
00497             char_count = len;
00498             ptr_count  = &char_count;
00499         }
00500     }
00501 
00502     OCI_LobRead2(lob, buffer, &char_count, &byte_count);
00503 
00504     return (ptr_count ? *ptr_count : 0);
00505 }
00506 
00507 /* --------------------------------------------------------------------------------------------- *
00508  * OCI_LobWrite
00509  * --------------------------------------------------------------------------------------------- */
00510 
00511 boolean OCI_API OCI_LobWrite2
00512 (
00513     OCI_Lob      *lob,
00514     void         *buffer,
00515     unsigned int *char_count,
00516     unsigned int *byte_count
00517 )
00518 {
00519     boolean res = TRUE;
00520     ub2 csid    = 0;
00521     ub1 csfrm   = 0;
00522     void *obuf  = NULL;
00523 
00524     OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE);
00525     OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE);
00526 
00527     if (lob->type != OCI_BLOB)
00528     {
00529 
00530     #ifdef OCI_USERDATA_WIDE
00531 
00532         csid = OCI_UTF16ID;
00533 
00534     #endif
00535 
00536         if (((*byte_count) == 0) && ((*char_count) > 0))
00537         {
00538             if (OCILib.nls_utf8 == TRUE)
00539             {
00540                 (*byte_count) = (unsigned int) strlen(buffer);
00541             }
00542             else
00543             {
00544                 (*byte_count) = (*char_count) * (ub4) sizeof(dtext);
00545             }
00546         }
00547 
00548         if (((*char_count) == 0) && ((*byte_count) > 0))
00549         {
00550             if (OCILib.nls_utf8 == TRUE)
00551             {
00552 
00553         #ifndef OCI_LOB2_API_ENABLED
00554 
00555                 (*char_count) = OCI_StringUTF8Length((const char *) buffer);
00556 
00557         #endif
00558 
00559             }
00560             else
00561             {
00562                 (*char_count) = (*byte_count) / (ub4) sizeof(dtext);
00563             }
00564         }
00565 
00566         obuf = OCI_GetInputDataString(buffer, (int *) byte_count);
00567 
00568         (*byte_count) *= sizeof(odtext);
00569     }
00570     else
00571     {
00572         obuf = buffer;
00573     }
00574 
00575     if (lob->type == OCI_NCLOB)
00576     {
00577         csfrm = SQLCS_NCHAR;
00578     }
00579     else
00580     {
00581         csfrm = SQLCS_IMPLICIT;
00582     }
00583 
00584     OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE);
00585 
00586 #ifdef OCI_LOB2_API_ENABLED
00587 
00588     if (OCILib.use_lob_ub8)
00589     {
00590         ub8 size_in_out_char = (ub8) (*char_count);
00591         ub8 size_in_out_byte = (ub8) (*byte_count);
00592 
00593         OCI_CALL2
00594         (
00595             res, lob->con,
00596 
00597             OCILobWrite2(lob->con->cxt, lob->con->err, lob->handle,
00598                          &size_in_out_byte, &size_in_out_char,
00599                          (ub8) lob->offset, obuf, (ub8) (*byte_count),
00600                          (ub1) OCI_ONE_PIECE, (void *) NULL,
00601                          NULL, csid, csfrm)
00602         )
00603 
00604         (*char_count) = (ub4) size_in_out_char;
00605         (*byte_count) = (ub4) size_in_out_byte;
00606     }
00607 
00608     else
00609 
00610 #endif
00611 
00612     {
00613         ub4 size_in_out_char_byte = 0;
00614 
00615         if ((lob->type == OCI_BLOB) || (OCILib.nls_utf8 == TRUE))
00616         {
00617             size_in_out_char_byte = (*byte_count);
00618         }
00619         else
00620         {
00621             size_in_out_char_byte = (*char_count);
00622         }
00623 
00624         OCI_CALL2
00625         (
00626             res, lob->con,
00627 
00628             OCILobWrite(lob->con->cxt, lob->con->err, lob->handle,
00629                         &size_in_out_char_byte, (ub4) lob->offset,
00630                         obuf, (ub4) (*byte_count), (ub1) OCI_ONE_PIECE,
00631                         (void *) NULL, NULL, csid, csfrm)
00632         )
00633 
00634         if (lob->type == OCI_BLOB)
00635         {
00636             (*byte_count) = (ub4) size_in_out_char_byte;
00637         }
00638         else
00639         {
00640             (*char_count) = (ub4) size_in_out_char_byte;
00641         }
00642     }
00643 
00644     if (res == TRUE)
00645     {
00646         if (lob->type == OCI_BLOB)
00647         {
00648             lob->offset += (big_uint) (*byte_count);
00649         }
00650         else
00651         {
00652             lob->offset += (big_uint) (*char_count);
00653 
00654             if (OCILib.nls_utf8 == FALSE)
00655             {
00656                 OCI_ReleaseDataString(obuf);
00657             }
00658         }
00659     }
00660 
00661     OCI_RESULT(res);
00662 
00663     return res;
00664 }
00665 
00666 /* --------------------------------------------------------------------------------------------- *
00667  * OCI_LobWrite
00668  * --------------------------------------------------------------------------------------------- */
00669 
00670 unsigned int OCI_API OCI_LobWrite
00671 (
00672     OCI_Lob     *lob,
00673     void        *buffer,
00674     unsigned int len
00675 )
00676 {
00677     unsigned int char_count = 0;
00678     unsigned int byte_count = 0;
00679     unsigned int *ptr_count = NULL;
00680 
00681     if (lob != NULL)
00682     {
00683         if(lob->type == OCI_BLOB)
00684         {
00685             byte_count = len;
00686             ptr_count  = &byte_count;
00687         }
00688         else
00689         {
00690             char_count = len;
00691             ptr_count  = &char_count;
00692         }
00693     }
00694 
00695     OCI_LobWrite2(lob, buffer, &char_count, &byte_count);
00696 
00697     return (ptr_count ? *ptr_count : 0);
00698 }
00699 
00700 /* --------------------------------------------------------------------------------------------- *
00701  * OCI_LobTruncate
00702  * --------------------------------------------------------------------------------------------- */
00703 
00704 boolean OCI_API OCI_LobTruncate
00705 (
00706     OCI_Lob *lob,
00707     big_uint size
00708 )
00709 {
00710     boolean res = TRUE;
00711 
00712     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
00713 
00714 #ifdef OCI_LOB2_API_ENABLED
00715 
00716     if (OCILib.use_lob_ub8)
00717     {
00718         OCI_CALL2
00719         (
00720             res, lob->con,
00721 
00722             OCILobTrim2(lob->con->cxt, lob->con->err, lob->handle, (ub8) size)
00723         )
00724     }
00725     else
00726 
00727 #endif
00728 
00729     {
00730         OCI_CALL2
00731         (
00732             res, lob->con,
00733 
00734             OCILobTrim(lob->con->cxt, lob->con->err, lob->handle, (ub4) size)
00735         )
00736     }
00737 
00738     OCI_RESULT(res);
00739 
00740     return res;
00741 }
00742 
00743 /* --------------------------------------------------------------------------------------------- *
00744  * OCI_LobErase
00745  * --------------------------------------------------------------------------------------------- */
00746 
00747 big_uint OCI_API OCI_LobErase
00748 (
00749     OCI_Lob *lob,
00750     big_uint offset,
00751     big_uint size
00752 )
00753 {
00754     boolean res = TRUE;
00755 
00756     OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0);
00757     OCI_CHECK_MIN(lob->con, NULL, size, 1, 0);
00758 
00759 #ifdef OCI_LOB2_API_ENABLED
00760 
00761     if (OCILib.use_lob_ub8)
00762     {
00763         ub8 lob_size = (ub8) size;
00764 
00765         OCI_CALL2
00766         (
00767             res, lob->con,
00768 
00769             OCILobErase2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size, (ub8) (offset + 1))
00770         )
00771 
00772         size = (big_uint) lob_size;
00773     }
00774     else
00775 
00776 #endif
00777 
00778     {
00779         ub4 lob_size = (ub4) size;
00780 
00781         OCI_CALL2
00782         (
00783             res, lob->con,
00784 
00785             OCILobErase(lob->con->cxt, lob->con->err, lob->handle,  &lob_size, (ub4) offset + 1)
00786         )
00787 
00788         size = (big_uint) lob_size;
00789     }
00790 
00791     OCI_RESULT(res);
00792 
00793     return size;
00794 }
00795 
00796 /* --------------------------------------------------------------------------------------------- *
00797  * OCI_LobGetLength
00798  * --------------------------------------------------------------------------------------------- */
00799 
00800 big_uint OCI_API OCI_LobGetLength
00801 (
00802     OCI_Lob *lob
00803 )
00804 {
00805     boolean res   = TRUE;
00806     big_uint size = 0;
00807 
00808     OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0);
00809 
00810 #ifdef OCI_LOB2_API_ENABLED
00811 
00812     if (OCILib.use_lob_ub8)
00813     {
00814         ub8 lob_size = 0;
00815 
00816         OCI_CALL2
00817         (
00818             res, lob->con,
00819 
00820             OCILobGetLength2(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &lob_size)
00821         )
00822 
00823         size = (big_uint) lob_size;
00824     }
00825     else
00826 
00827 #endif
00828 
00829     {
00830         ub4 lob_size = 0;
00831 
00832         OCI_CALL2
00833         (
00834             res, lob->con,
00835 
00836             OCILobGetLength(lob->con->cxt, lob->con->err, lob->handle, &lob_size)
00837         )
00838 
00839         size = (big_uint) lob_size;
00840     }
00841 
00842     OCI_RESULT(res);
00843 
00844     return size;
00845 }
00846 
00847 /* --------------------------------------------------------------------------------------------- *
00848  * OCI_LobGetChunkSize
00849  * --------------------------------------------------------------------------------------------- */
00850 
00851 unsigned int OCI_API OCI_LobGetChunkSize
00852 (
00853     OCI_Lob *lob
00854 )
00855 {
00856     boolean res = TRUE;
00857     ub4 size    = 0;
00858 
00859     OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0);
00860 
00861     OCI_CALL2
00862     (
00863         res, lob->con,
00864 
00865         OCILobGetChunkSize(lob->con->cxt, lob->con->err, lob->handle, &size)
00866     )
00867 
00868     OCI_RESULT(res);
00869 
00870     return (unsigned int) size;
00871 }
00872 
00873 /* --------------------------------------------------------------------------------------------- *
00874  * OCI_LobCopy
00875  * --------------------------------------------------------------------------------------------- */
00876 
00877 boolean OCI_API OCI_LobCopy
00878 (
00879     OCI_Lob *lob,
00880     OCI_Lob *lob_src,
00881     big_uint offset_dst,
00882     big_uint offset_src,
00883     big_uint count
00884 )
00885 {
00886     boolean res = TRUE;
00887 
00888     OCI_CHECK_PTR(OCI_IPC_LOB, lob,     FALSE);
00889     OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE);
00890 
00891 #ifdef OCI_LOB2_API_ENABLED
00892 
00893     if (OCILib.use_lob_ub8)
00894     {
00895 
00896         OCI_CALL2
00897         (
00898             res, lob->con,
00899 
00900             OCILobCopy2(lob->con->cxt, lob->con->err, lob->handle,
00901                         lob_src->handle, (ub8) count,
00902                         (ub8) (offset_dst + 1),
00903                         (ub8) (offset_src + 1))
00904         )
00905     }
00906     else
00907 
00908 #endif
00909 
00910 {
00911         OCI_CALL2
00912         (
00913             res, lob->con,
00914 
00915             OCILobCopy(lob->con->cxt, lob->con->err, lob->handle,
00916                        lob_src->handle, (ub4) count,
00917                        (ub4) (offset_dst + 1),
00918                        (ub4) (offset_src + 1))
00919         )
00920     }
00921 
00922     OCI_RESULT(res);
00923 
00924     return res;
00925 }
00926 
00927 /* --------------------------------------------------------------------------------------------- *
00928  * OCI_LobCopyFromFile
00929  * --------------------------------------------------------------------------------------------- */
00930 
00931 boolean OCI_API OCI_LobCopyFromFile
00932 (
00933     OCI_Lob  *lob,
00934     OCI_File *file,
00935     big_uint  offset_dst,
00936     big_uint  offset_src,
00937     big_uint  count
00938 )
00939 {
00940     boolean res = TRUE;
00941 
00942     OCI_CHECK_PTR(OCI_IPC_LOB, lob,   FALSE);
00943     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00944 
00945 #ifdef OCI_LOB2_API_ENABLED
00946 
00947     if (OCILib.use_lob_ub8)
00948     {
00949         OCI_CALL2
00950         (
00951             res, lob->con,
00952 
00953             OCILobLoadFromFile2(lob->con->cxt, lob->con->err,
00954                                 lob->handle, file->handle,
00955                                 (ub8) count,
00956                                 (ub8) (offset_dst + 1),
00957                                 (ub8) (offset_src + 1))
00958         )
00959     }
00960     else
00961 
00962 #endif
00963 
00964     {
00965         OCI_CALL2
00966         (
00967             res, lob->con,
00968 
00969             OCILobLoadFromFile(lob->con->cxt, lob->con->err,
00970                                lob->handle, file->handle,
00971                                (ub4) count,
00972                                (ub4) (offset_dst + 1),
00973                                (ub4) (offset_src + 1))
00974         )
00975     }
00976 
00977     OCI_RESULT(res);
00978 
00979     return res;
00980 }
00981 
00982 /* --------------------------------------------------------------------------------------------- *
00983  * OCI_LobAppend2
00984  * --------------------------------------------------------------------------------------------- */
00985 
00986 boolean OCI_API OCI_LobAppend2
00987 (
00988     OCI_Lob      *lob,
00989     void         *buffer,
00990     unsigned int *char_count,
00991     unsigned int *byte_count
00992 )
00993 {
00994     boolean res = TRUE;
00995     ub2 csid    = 0;
00996     ub1 csfrm   = 0;
00997     void *obuf  = NULL;
00998 
00999     OCI_CHECK_PTR(OCI_IPC_LOB, char_count, FALSE);
01000     OCI_CHECK_PTR(OCI_IPC_LOB, byte_count, FALSE);
01001 
01002     /* OCILobWriteAppend() seems to cause problems on Oracle client 8.1 and 9.0
01003        It's an Oracle known bug #886191
01004        So we use OCI_LobSeek() + OCI_LobWrite() instead */
01005 
01006     if (OCILib.version_runtime < OCI_10_1)
01007     {
01008         return OCI_LobSeek(lob, OCI_LobGetLength(lob), OCI_SEEK_SET) &&
01009                OCI_LobWrite2(lob, buffer, char_count, byte_count);
01010     }
01011 
01012     if (lob->type != OCI_BLOB)
01013     {
01014 
01015     #ifdef OCI_USERDATA_WIDE
01016 
01017         csid = OCI_UTF16ID;
01018 
01019     #endif
01020 
01021         if (((*byte_count) == 0) && ((*char_count) > 0))
01022         {
01023             if (OCILib.nls_utf8 == TRUE)
01024             {
01025                 (*byte_count) = (unsigned int) strlen(buffer);
01026             }
01027             else
01028             {
01029                 (*byte_count) = (*char_count) * (ub4) sizeof(dtext);
01030             }
01031         }
01032 
01033         if (((*char_count) == 0) && ((*byte_count) > 0))
01034         {
01035             if (OCILib.nls_utf8 == TRUE)
01036             {
01037 
01038             #ifndef OCI_LOB2_API_ENABLED
01039 
01040                 (*char_count) = OCI_StringUTF8Length((const char *) buffer);
01041 
01042             #endif
01043 
01044             }
01045             else
01046             {
01047                 (*char_count) = (*byte_count) / (ub4) sizeof(dtext);
01048             }
01049         }
01050 
01051         obuf = OCI_GetInputDataString(buffer, (int *) byte_count);
01052 
01053         (*byte_count) *= sizeof(odtext);
01054     }
01055     else
01056     {
01057         obuf = buffer;
01058     }
01059 
01060     if (lob->type == OCI_NCLOB)
01061     {
01062         csfrm = SQLCS_NCHAR;
01063     }
01064     else
01065     {
01066         csfrm = SQLCS_IMPLICIT;
01067     }
01068 
01069     OCI_CHECK_MIN(lob->con, NULL, (*byte_count), 1, FALSE);
01070 
01071 #ifdef OCI_LOB2_API_ENABLED
01072 
01073     if (OCILib.use_lob_ub8)
01074     {
01075         ub8 size_in_out_char = (ub8) (*char_count);
01076         ub8 size_in_out_byte = (ub8) (*byte_count);
01077 
01078         OCI_CALL2
01079         (
01080             res, lob->con,
01081 
01082             OCILobWriteAppend2(lob->con->cxt, lob->con->err, lob->handle,
01083                                &size_in_out_byte, &size_in_out_char,
01084                                obuf, (ub8)  (*byte_count), (ub1) OCI_ONE_PIECE,
01085                                (dvoid *) NULL, NULL, csid, csfrm)
01086         )
01087 
01088         (*char_count) = (ub4) size_in_out_char;
01089         (*byte_count) = (ub4) size_in_out_byte;
01090     }
01091 
01092     else
01093 
01094 #endif
01095 
01096     {
01097         ub4 size_in_out_char_byte = 0;
01098 
01099         if ((lob->type == OCI_BLOB) || (OCILib.nls_utf8 == TRUE))
01100         {
01101             size_in_out_char_byte = (*byte_count);
01102         }
01103         else
01104         {
01105             size_in_out_char_byte = (*char_count);
01106         }
01107 
01108         OCI_CALL2
01109         (
01110             res, lob->con,
01111 
01112             OCILobWriteAppend(lob->con->cxt, lob->con->err, lob->handle,
01113                               &size_in_out_char_byte, obuf,  (*byte_count),
01114                               (ub1) OCI_ONE_PIECE, (dvoid *) NULL, NULL, csid, csfrm)
01115         )
01116 
01117         if (lob->type == OCI_BLOB)
01118         {
01119             (*byte_count) = (ub4) size_in_out_char_byte;
01120         }
01121         else
01122         {
01123             (*char_count) = (ub4) size_in_out_char_byte;
01124         }
01125     }
01126 
01127     if (res == TRUE)
01128     {
01129         if (lob->type == OCI_BLOB)
01130         {
01131             lob->offset += (big_uint) (*byte_count);
01132         }
01133         else
01134         {
01135             lob->offset += (big_uint) (*char_count);
01136 
01137             if (OCILib.nls_utf8 == FALSE)
01138             {
01139                 OCI_ReleaseDataString(obuf);
01140             }
01141         }
01142     }
01143 
01144     OCI_RESULT(res);
01145 
01146     return res;
01147 }
01148 
01149 /* --------------------------------------------------------------------------------------------- *
01150  * OCI_LobAppend
01151  * --------------------------------------------------------------------------------------------- */
01152 
01153 unsigned int OCI_API OCI_LobAppend
01154 (
01155     OCI_Lob     *lob,
01156     void        *buffer,
01157     unsigned int len
01158 )
01159 {
01160     unsigned int char_count = 0;
01161     unsigned int byte_count = 0;
01162     unsigned int *ptr_count = NULL;
01163 
01164     if (lob != NULL)
01165     {
01166         if(lob->type == OCI_BLOB)
01167         {
01168             byte_count = len;
01169             ptr_count  = &byte_count;
01170         }
01171         else
01172         {
01173             char_count = len;
01174             ptr_count  = &char_count;
01175         }
01176     }
01177 
01178     OCI_LobAppend2(lob, buffer, &char_count, &byte_count);
01179 
01180     return (ptr_count ? *ptr_count : 0);
01181 }
01182 
01183 /* --------------------------------------------------------------------------------------------- *
01184  * OCI_LobAppendLob
01185  * --------------------------------------------------------------------------------------------- */
01186 
01187 boolean OCI_API OCI_LobAppendLob
01188 (
01189     OCI_Lob *lob,
01190     OCI_Lob *lob_src
01191 )
01192 {
01193     boolean res     = TRUE;
01194     big_uint length = 0;
01195 
01196     OCI_CHECK_PTR(OCI_IPC_LOB, lob,     FALSE);
01197     OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE);
01198 
01199     /*
01200        this might cause an ORA-24805 on Oracle 8.1.x only !
01201        I couldn’t find a bug ID on Metalink, but Oracle 9i had many fixes for
01202        lobs !
01203     */
01204 
01205     OCI_CALL2
01206     (
01207         res, lob->con,
01208 
01209         OCILobAppend(lob->con->cxt, lob->con->err, lob->handle, lob_src->handle)
01210     )
01211 
01212     if (res == TRUE)
01213     {
01214         length = OCI_LobGetLength(lob);
01215 
01216         lob->offset += length;
01217     }
01218 
01219     OCI_RESULT(res);
01220 
01221     return res;
01222 }
01223 
01224 /* --------------------------------------------------------------------------------------------- *
01225  * OCI_LobIsTemporary
01226  * --------------------------------------------------------------------------------------------- */
01227 
01228 boolean OCI_API OCI_LobIsTemporary
01229 (
01230     OCI_Lob *lob
01231 )
01232 {
01233     boolean value = FALSE;
01234     boolean res   = TRUE;
01235 
01236     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
01237 
01238     OCI_CALL2
01239     (
01240         res, lob->con,
01241 
01242         OCILobIsTemporary(lob->con->env, lob->con->err, lob->handle, &value)
01243     )
01244 
01245     OCI_RESULT(res);
01246 
01247     return value;
01248 }
01249 
01250 /* --------------------------------------------------------------------------------------------- *
01251  * OCI_LobOpen
01252  * --------------------------------------------------------------------------------------------- */
01253 
01254 boolean OCI_API OCI_LobOpen
01255 (
01256     OCI_Lob     *lob,
01257     unsigned int mode
01258 )
01259 {
01260     boolean res = TRUE;
01261 
01262     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
01263 
01264     OCI_CALL2
01265     (
01266         res, lob->con,
01267 
01268         OCILobOpen(lob->con->cxt, lob->con->err, lob->handle, (ub1) mode)
01269     )
01270 
01271     OCI_RESULT(res);
01272 
01273     return res;
01274 }
01275 
01276 /* --------------------------------------------------------------------------------------------- *
01277  * OCI_LobClose
01278  * --------------------------------------------------------------------------------------------- */
01279 
01280 boolean OCI_API OCI_LobClose
01281 (
01282     OCI_Lob *lob
01283 )
01284 {
01285     boolean res = TRUE;
01286 
01287     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
01288 
01289     OCI_CALL2
01290     (
01291         res, lob->con,
01292 
01293         OCILobClose(lob->con->cxt, lob->con->err, lob->handle)
01294     )
01295 
01296     OCI_RESULT(res);
01297 
01298     return res;
01299 }
01300 
01301 /* --------------------------------------------------------------------------------------------- *
01302  * OCI_LobIsEqual
01303  * --------------------------------------------------------------------------------------------- */
01304 
01305 boolean OCI_API OCI_LobIsEqual
01306 (
01307     OCI_Lob *lob,
01308     OCI_Lob *lob2
01309 )
01310 {
01311     boolean value = FALSE;
01312     boolean res   = TRUE;
01313 
01314     OCI_CHECK_PTR(OCI_IPC_LOB, lob,FALSE);
01315     OCI_CHECK_PTR(OCI_IPC_LOB, lob2, FALSE);
01316 
01317     OCI_CALL2
01318     (
01319         res, lob->con,
01320 
01321         OCILobIsEqual(lob->con->env, lob->handle, lob2->handle, &value)
01322     )
01323 
01324     OCI_RESULT(res);
01325 
01326     return value;
01327 }
01328 
01329 /* --------------------------------------------------------------------------------------------- *
01330  * OCI_LobAssign
01331  * --------------------------------------------------------------------------------------------- */
01332 
01333 boolean OCI_API OCI_LobAssign
01334 (
01335     OCI_Lob *lob,
01336     OCI_Lob *lob_src
01337 )
01338 {
01339     boolean res = TRUE;
01340 
01341     OCI_CHECK_PTR(OCI_IPC_LOB, lob,     FALSE);
01342     OCI_CHECK_PTR(OCI_IPC_LOB, lob_src, FALSE);
01343 
01344     if ((lob->hstate == OCI_OBJECT_ALLOCATED) || (lob->hstate == OCI_OBJECT_ALLOCATED_ARRAY))
01345     {
01346         OCI_CALL2
01347         (
01348             res, lob->con,
01349 
01350             OCILobLocatorAssign(lob->con->cxt, lob->con->err, lob_src->handle, &lob->handle)
01351         )
01352     }
01353     else
01354     {
01355         OCI_CALL2
01356         (
01357             res, lob->con,
01358 
01359             OCILobAssign(lob->con->env, lob->con->err, lob_src->handle, &lob->handle)
01360         )
01361     }
01362 
01363     OCI_RESULT(res);
01364 
01365     return res;
01366 }
01367 
01368 /* --------------------------------------------------------------------------------------------- *
01369  * OCI_LobGetMaxSize
01370  * --------------------------------------------------------------------------------------------- */
01371 
01372 big_uint OCI_API OCI_LobGetMaxSize
01373 (
01374     OCI_Lob *lob
01375 )
01376 {
01377     boolean res   = TRUE;
01378     big_uint size = 0;
01379 
01380     OCI_CHECK_PTR(OCI_IPC_LOB, lob, 0);
01381 
01382 #ifdef OCI_LOB2_API_ENABLED
01383 
01384     if (OCILib.use_lob_ub8)
01385     {
01386         OCI_CALL2
01387         (
01388             res, lob->con,
01389 
01390             OCILobGetStorageLimit(lob->con->cxt, lob->con->err, lob->handle, (ub8 *) &size)
01391         )
01392     }
01393 
01394 #endif
01395 
01396     OCI_RESULT(res);
01397 
01398     return size;
01399 }
01400 
01401 /* --------------------------------------------------------------------------------------------- *
01402  * OCI_LobFlush
01403  * --------------------------------------------------------------------------------------------- */
01404 
01405 boolean OCI_API OCI_LobFlush
01406 (
01407     OCI_Lob *lob
01408 )
01409 {
01410     boolean res = TRUE;
01411 
01412     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
01413 
01414     OCI_CALL2
01415     (
01416         res, lob->con,
01417 
01418         OCILobFlushBuffer(lob->con->cxt, lob->con->err, lob->handle, (ub4) OCI_DEFAULT)
01419     )
01420 
01421     OCI_RESULT(res);
01422 
01423     return res;
01424 }
01425 
01426 /* --------------------------------------------------------------------------------------------- *
01427  * OCI_LobEnableBuffering
01428  * --------------------------------------------------------------------------------------------- */
01429 
01430 boolean OCI_API OCI_LobEnableBuffering
01431 (
01432     OCI_Lob *lob,
01433     boolean  value
01434 )
01435 {
01436     boolean res = TRUE;
01437 
01438     OCI_CHECK_PTR(OCI_IPC_LOB, lob, FALSE);
01439 
01440     if (value == TRUE)
01441     {
01442         OCI_CALL2
01443         (
01444             res, lob->con,
01445 
01446             OCILobEnableBuffering(lob->con->cxt, lob->con->err, lob->handle)
01447         )
01448     }
01449     else
01450     {
01451         OCI_CALL2
01452         (
01453             res, lob->con,
01454 
01455             OCILobDisableBuffering(lob->con->cxt, lob->con->err, lob->handle)
01456         )
01457     }
01458 
01459     OCI_RESULT(res);
01460 
01461     return res;
01462 }
01463