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