OCILIB (C Driver for Oracle) 3.9.2
D:/Perso/dev/ocilib/ocilib/src/long.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: long.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_LongInit
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Long * OCI_LongInit
00046 (
00047     OCI_Statement *stmt,
00048     OCI_Long     **plg,
00049     OCI_Define    *def,
00050     unsigned int   type
00051 )
00052 {
00053     boolean res  = TRUE;
00054     OCI_Long *lg = NULL;
00055 
00056     OCI_CHECK(plg == NULL, NULL);
00057 
00058     if (*plg == NULL)
00059     {
00060         *plg = (OCI_Long *) OCI_MemAlloc(OCI_IPC_LONG, sizeof(*lg), (size_t) 1, TRUE);
00061     }
00062 
00063     if (*plg != NULL)
00064     {
00065         lg = *plg;
00066 
00067         lg->size   = 0;
00068         lg->stmt   = stmt;
00069         lg->def    = def;
00070         lg->type   = type;
00071         lg->offset = 0;
00072 
00073         if (def != NULL)
00074         {
00075             lg->hstate = OCI_OBJECT_FETCHED_CLEAN;
00076         }
00077         else if (lg->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00078         {
00079             lg->hstate = OCI_OBJECT_ALLOCATED;
00080         }
00081     }
00082     else
00083     {
00084         res = FALSE;
00085     }
00086 
00087     OCI_RESULT(res);
00088 
00089     return lg;
00090 }
00091 
00092 /* ********************************************************************************************* *
00093  *                            PUBLIC FUNCTIONS
00094  * ********************************************************************************************* */
00095 
00096 /* --------------------------------------------------------------------------------------------- *
00097  * OCI_LongCreate
00098  * --------------------------------------------------------------------------------------------- */
00099 
00100 OCI_Long * OCI_API OCI_LongCreate
00101 (
00102     OCI_Statement *stmt,
00103     unsigned int   type
00104 )
00105 {
00106     OCI_Long *lg = NULL;
00107 
00108     OCI_CHECK_INITIALIZED(NULL);
00109 
00110     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
00111 
00112     lg = OCI_LongInit(stmt, &lg, NULL, type);
00113 
00114     OCI_RESULT(lg != NULL);
00115 
00116     return lg;
00117 }
00118 
00119 /* --------------------------------------------------------------------------------------------- *
00120  * OCI_LongFree
00121  * --------------------------------------------------------------------------------------------- */
00122 
00123 boolean OCI_API OCI_LongFree
00124 (
00125     OCI_Long *lg
00126 )
00127 {
00128     OCI_CHECK_PTR(OCI_IPC_LONG, lg, FALSE);
00129 
00130     OCI_CHECK_OBJECT_FETCHED(lg, FALSE);
00131 
00132     OCI_FREE(lg->buffer);
00133     OCI_FREE(lg);
00134 
00135     OCI_RESULT(TRUE);
00136 
00137     return TRUE;
00138 }
00139 
00140 /* --------------------------------------------------------------------------------------------- *
00141  * OCI_LongGetType
00142  * --------------------------------------------------------------------------------------------- */
00143 
00144 unsigned int OCI_API OCI_LongGetType
00145 (
00146     OCI_Long *lg
00147 )
00148 {
00149     OCI_CHECK_PTR(OCI_IPC_LONG, lg, OCI_UNKNOWN);
00150 
00151     OCI_RESULT(TRUE);
00152 
00153     return lg->type;
00154 }
00155 
00156 /* --------------------------------------------------------------------------------------------- *
00157  * OCI_LongRead
00158  * --------------------------------------------------------------------------------------------- */
00159 
00160 unsigned int OCI_API OCI_LongRead
00161 (
00162     OCI_Long    *lg,
00163     void        *buffer,
00164     unsigned int len
00165 )
00166 {
00167     unsigned int size = len;
00168     unsigned int fact = 1;
00169 
00170     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00171     OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0);
00172 
00173     OCI_CHECK_MIN(lg->stmt->con, lg->stmt, size, 1, 0);
00174 
00175     OCI_CHECK(lg->offset >= lg->size, 0);
00176 
00177     /* lg->size and lg offset are still expressed in odtext units even
00178        if the buffer had already been expanded to dtext *
00179     */
00180 
00181     if (lg->type == OCI_CLONG)
00182     {
00183         len *= (unsigned int) sizeof(odtext);
00184     }
00185 
00186     /* check buffer size to read */
00187 
00188     if ((size + lg->offset) > lg->size)
00189     {
00190         size = lg->size - lg->offset;
00191     }
00192 
00193     /* copy buffer */
00194 
00195     memcpy(buffer, lg->buffer + (size_t) lg->offset*fact, (size_t) (size*fact));
00196 
00197     lg->offset += size;
00198 
00199     if (lg->type == OCI_CLONG)
00200     {
00201         ((dtext *) buffer)[size] = 0;
00202 
00203         size /= (unsigned int) sizeof(dtext);
00204     }
00205 
00206     OCI_RESULT(TRUE);
00207 
00208     return size;
00209 }
00210 
00211 /* --------------------------------------------------------------------------------------------- *
00212  * OCI_LongWrite
00213  * --------------------------------------------------------------------------------------------- */
00214 
00215 unsigned int OCI_API OCI_LongWrite
00216 (
00217     OCI_Long    *lg,
00218     void        *buffer,
00219     unsigned int len
00220 )
00221 {
00222     boolean res  = TRUE;
00223     sword code   = OCI_SUCCESS;
00224     void *obuf   = NULL;
00225     void *handle = NULL;
00226     ub1 in_out   = OCI_PARAM_IN;
00227     ub1 piece    = OCI_ONE_PIECE;
00228     ub4 type     = 0;
00229     ub4 iter     = 0;
00230     ub4 dx       = 0;
00231     ub4 count    = 0;
00232 
00233     OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0);
00234     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00235 
00236     OCI_CHECK_MIN(lg->stmt->con, lg->stmt, len, 1, 0);
00237 
00238     if (lg->type == OCI_CLONG)
00239     {
00240         len *= (unsigned int) sizeof(dtext);
00241     }
00242 
00243     if (lg->type == OCI_CLONG)
00244     {
00245         obuf = OCI_GetInputDataString(buffer, (int *) &len);
00246     }
00247     else
00248     {
00249         obuf = buffer;
00250     }
00251 
00252     /* get piece info */
00253 
00254     OCI_CALL1
00255     (
00256         res, lg->stmt->con, lg->stmt,
00257 
00258         OCIStmtGetPieceInfo(lg->stmt->stmt, lg->stmt->con->err, &handle,
00259                             &type, &in_out, &iter, &dx, &piece)
00260     )
00261 
00262     /* set up piece type */
00263 
00264     if (len > 0)
00265     {
00266         piece = (ub1) ((lg->size > 0) ? OCI_NEXT_PIECE : OCI_FIRST_PIECE);
00267     }
00268     else
00269     {
00270         piece = (ub1) OCI_LAST_PIECE;
00271     }
00272 
00273     /* correct size to read for last piece */
00274 
00275     if ((lg->size + len) >= lg->stmt->long_size)
00276     {
00277         piece = OCI_LAST_PIECE;
00278         count = lg->stmt->long_size - lg->size;
00279     }
00280     else
00281     {
00282         count = len;
00283     }
00284 
00285     /* set up info for writing */
00286 
00287     OCI_CALL1
00288     (
00289         res, lg->stmt->con, lg->stmt,
00290 
00291         OCIStmtSetPieceInfo(handle, type, lg->stmt->con->err, (dvoid *) obuf,
00292                             &count,  piece, (dvoid *) NULL, (ub2 *) NULL)
00293     )
00294 
00295     /* perform write call */
00296 
00297     if (res == TRUE)
00298     {
00299         code = OCIStmtExecute(lg->stmt->con->cxt, lg->stmt->stmt,
00300                               lg->stmt->con->err, (ub4) 1, (ub4) 0,
00301                               (OCISnapshot *) NULL, (OCISnapshot *) NULL,
00302                               (ub4) 0);
00303     }
00304 
00305     if ((code != OCI_SUCCESS) && (code != OCI_NEED_DATA))
00306     {
00307         if (code == OCI_SUCCESS_WITH_INFO)
00308         {
00309             OCI_ExceptionOCI(lg->stmt->con->err, lg->stmt->con, lg->stmt, TRUE);
00310         }
00311         else
00312         {
00313             OCI_ExceptionOCI(lg->stmt->con->err, lg->stmt->con, lg->stmt, FALSE);
00314             res = FALSE;
00315         }
00316     }
00317 
00318     if (lg->type == OCI_CLONG)
00319     {
00320         OCI_ReleaseDataString(obuf);
00321     }
00322 
00323     /* update size */
00324 
00325     if (res == TRUE)
00326     {
00327         lg->size += count;
00328 
00329         /* at this point, count is expressed in odtext bytes for character LONGs
00330          **/
00331 
00332         if (lg->type == OCI_CLONG)
00333         {
00334             count /= (unsigned int) sizeof(odtext);
00335         }
00336 
00337     }
00338 
00339     OCI_RESULT(res);
00340 
00341     return count;
00342 }
00343 
00344 /* --------------------------------------------------------------------------------------------- *
00345  * OCI_LongGetSize
00346  * --------------------------------------------------------------------------------------------- */
00347 
00348 unsigned int OCI_API OCI_LongGetSize
00349 (
00350     OCI_Long *lg
00351 )
00352 {
00353     unsigned int size = 0;
00354 
00355     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00356 
00357     size = lg->size;
00358 
00359     if (lg->type == OCI_CLONG)
00360     {
00361         size /= (unsigned int) sizeof(odtext);
00362     }
00363 
00364     OCI_RESULT(TRUE);
00365 
00366     return size;
00367 }
00368 
00369 /* --------------------------------------------------------------------------------------------- *
00370  * OCI_LongGetBuffer
00371  * --------------------------------------------------------------------------------------------- */
00372 
00373 void * OCI_API OCI_LongGetBuffer
00374 (
00375     OCI_Long *lg
00376 )
00377 {
00378     OCI_CHECK_PTR(OCI_IPC_LONG, lg, NULL);
00379 
00380     OCI_RESULT(TRUE);
00381 
00382     return (void *) lg->buffer;
00383 }