C:/Users/vincent/Data/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    +----------------------------------------------------------------------+
00009    |                      Website : http://www.ocilib.net                 |
00010    +----------------------------------------------------------------------+
00011    |               Copyright (c) 2007-2009 Vincent ROGIER                 |
00012    +----------------------------------------------------------------------+
00013    | This library is free software; you can redistribute it and/or        |
00014    | modify it under the terms of the GNU Lesser General Public           |
00015    | License as published by the Free Software Foundation; either         |
00016    | version 2 of the License, or (at your option) any later version.     |
00017    |                                                                      |
00018    | This library is distributed in the hope that it will be useful,      |
00019    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
00020    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
00021    | Lesser General Public License for more details.                      |
00022    |                                                                      |
00023    | You should have received a copy of the GNU Lesser General Public     |
00024    | License along with this library; if not, write to the Free           |
00025    | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
00026    +----------------------------------------------------------------------+
00027    |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
00028    +----------------------------------------------------------------------+ 
00029 */
00030 
00031 /* ------------------------------------------------------------------------ *
00032  * $Id: long.c, v 3.4.0 2009-07-30 17:40 Vince $
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(OCI_Statement *stmt, OCI_Long **plg,
00046                         OCI_Define *def, unsigned int type)
00047 {
00048     boolean res  = TRUE;
00049     OCI_Long *lg = NULL;
00050 
00051     OCI_CHECK(plg == NULL, NULL);
00052 
00053     if (*plg == NULL)
00054         *plg = (OCI_Long *) OCI_MemAlloc(OCI_IPC_LONG, sizeof(*lg), 1, TRUE);
00055 
00056     if (*plg != NULL)
00057     {
00058         lg = *plg;
00059 
00060         lg->size   = 0;
00061         lg->stmt   = stmt;
00062         lg->def    = def;
00063         lg->type   = type;
00064         lg->offset = 0;
00065 
00066         if (def != NULL)
00067             lg->hstate = OCI_OBJECT_FETCHED_CLEAN;
00068         else
00069             lg->hstate = OCI_OBJECT_ALLOCATED;
00070     }
00071     else
00072         res = FALSE;
00073 
00074     OCI_RESULT(res);
00075 
00076     return lg;
00077 }
00078 
00079 /* ************************************************************************ *
00080  *                            PUBLIC FUNCTIONS
00081  * ************************************************************************ */
00082 
00083 /* ------------------------------------------------------------------------ *
00084  * OCI_LongCreate
00085  * ------------------------------------------------------------------------ */
00086 
00087 OCI_Long * OCI_API OCI_LongCreate(OCI_Statement *stmt, unsigned int type)
00088 {
00089     OCI_Long *lg = NULL;
00090 
00091     OCI_CHECK_INITIALIZED(NULL);
00092 
00093     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
00094 
00095     lg = OCI_LongInit(stmt, &lg, NULL, type);
00096 
00097     OCI_RESULT(lg != NULL);
00098 
00099     return lg;
00100 }
00101 
00102 /* ------------------------------------------------------------------------ *
00103  * OCI_LongFree
00104  * ------------------------------------------------------------------------ */
00105 
00106 boolean OCI_API OCI_LongFree(OCI_Long *lg)
00107 {
00108     OCI_CHECK_PTR(OCI_IPC_LONG, lg, FALSE);
00109     
00110     OCI_CHECK_OBJECT_FETCHED(lg, FALSE);
00111 
00112     OCI_FREE(lg->buffer);
00113     OCI_FREE(lg);
00114 
00115     OCI_RESULT(TRUE);
00116 
00117     return TRUE;
00118 }
00119 
00120 /* ------------------------------------------------------------------------ *
00121  * OCI_LongGetType
00122  * ------------------------------------------------------------------------ */
00123 
00124 unsigned int OCI_API OCI_LongGetType(OCI_Long *lg)
00125 {
00126     OCI_CHECK_PTR(OCI_IPC_LONG, lg, OCI_UNKNOWN);
00127 
00128     OCI_RESULT(TRUE);
00129 
00130     return lg->type;
00131 }
00132 
00133 /* ------------------------------------------------------------------------ *
00134  * OCI_LongRead
00135  * ------------------------------------------------------------------------ */
00136 
00137 unsigned int OCI_API OCI_LongRead(OCI_Long *lg, void *buffer,
00138                                   unsigned int len)
00139 {
00140     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00141     OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0);
00142     
00143     OCI_CHECK_MIN(lg->stmt->con, lg->stmt, len, 1, 0);
00144 
00145     OCI_CHECK(lg->offset > lg->size, 0);
00146 
00147     if (lg->type == OCI_CLONG)
00148         len *= sizeof(dtext);
00149 
00150    /* check buffer size to read */
00151 
00152    if ((len + lg->offset) > lg->size)
00153         len = lg->size - lg->offset;
00154 
00155    /* copy buffer */
00156 
00157     memcpy(buffer, lg->buffer + lg->offset, len);
00158 
00159     lg->offset += len;
00160 
00161     if (lg->type == OCI_CLONG)
00162         len /= sizeof(dtext);
00163 
00164     OCI_RESULT(TRUE);
00165 
00166     return len;
00167 }
00168 
00169 /* ------------------------------------------------------------------------ *
00170  * OCI_LongWrite
00171  * ------------------------------------------------------------------------ */
00172 
00173 unsigned int OCI_API OCI_LongWrite(OCI_Long *lg, void *buffer,
00174                                    unsigned int len)
00175 {
00176     boolean res  = TRUE;
00177     sword code   = OCI_SUCCESS;
00178     void *obuf   = NULL;
00179     void *handle = NULL;
00180     ub1 in_out   = OCI_PARAM_IN;
00181     ub1 piece    = OCI_ONE_PIECE;
00182     ub4 type     = 0;
00183     ub4 iter     = 0;
00184     ub4 dx       = 0;
00185     ub4 count    = len;
00186 
00187     OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0);
00188     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00189     
00190     OCI_CHECK_MIN(lg->stmt->con, lg->stmt, len, 1, 0);
00191 
00192     if (lg->type == OCI_CLONG)
00193         len *= sizeof(odtext);
00194 
00195     if (lg->type == OCI_CLONG)
00196         obuf = OCI_GetInputDataString(buffer, (int *) &len);
00197     else
00198         obuf = buffer;
00199 
00200    /* get piece info */
00201 
00202     OCI_CALL1
00203     (
00204         res, lg->stmt->con, lg->stmt,
00205         
00206         OCIStmtGetPieceInfo(lg->stmt->stmt, lg->stmt->con->err, &handle,
00207                             &type, &in_out, &iter, &dx, &piece)
00208     )
00209 
00210     /* set up piece type */
00211 
00212     if (len > 0)
00213         piece = (ub1) ((lg->size > 0) ? OCI_NEXT_PIECE : OCI_FIRST_PIECE);
00214     else
00215         piece = (ub1) OCI_LAST_PIECE;
00216 
00217     /* correct size to read for last piece */
00218 
00219     if ((lg->size + len) >= lg->stmt->long_size)
00220     {
00221         piece = OCI_LAST_PIECE;
00222         count = lg->stmt->long_size - lg->size;
00223     }
00224 
00225     /* set up info for writing */
00226 
00227     OCI_CALL1
00228     (
00229         res, lg->stmt->con, lg->stmt,
00230         
00231         OCIStmtSetPieceInfo(handle, type, lg->stmt->con->err, (dvoid *) obuf, 
00232                             &count,  piece, (dvoid *) NULL, (ub2 *) NULL)
00233     )
00234 
00235     /* perform write call */
00236 
00237     if (res == TRUE)
00238     {     
00239         code = OCIStmtExecute(lg->stmt->con->cxt, lg->stmt->stmt,
00240                               lg->stmt->con->err, (ub4) 1, (ub4) 0, 
00241                               (OCISnapshot *) NULL, (OCISnapshot *) NULL,
00242                               (ub4) 0);
00243     }
00244      
00245     if ((code != OCI_SUCCESS) && (code != OCI_NEED_DATA))
00246     {
00247         OCI_ExceptionOCI(lg->stmt->con->err, lg->stmt->con, lg->stmt);
00248     }
00249 
00250     if (lg->type == OCI_CLONG)
00251         OCI_ReleaseDataString(obuf);
00252 
00253     /* update size */
00254 
00255     if (res == TRUE)
00256     {
00257         lg->size += count;
00258 
00259         if (lg->type == OCI_CLONG)
00260             count /= sizeof(odtext);
00261     }
00262 
00263     OCI_RESULT(res);
00264 
00265     return count;
00266 }
00267 
00268 /* ------------------------------------------------------------------------ *
00269  * OCI_LongGetSize
00270  * ------------------------------------------------------------------------ */
00271 
00272 unsigned int OCI_API OCI_LongGetSize(OCI_Long *lg)
00273 {
00274     unsigned int size = 0;
00275 
00276     OCI_CHECK_PTR(OCI_IPC_LONG, lg, 0);
00277 
00278     size = lg->size;
00279 
00280     if (lg->type == OCI_CLONG)
00281         size /= sizeof(dtext);
00282 
00283     OCI_RESULT(TRUE);
00284 
00285     return size;
00286 }
00287 
00288 /* ------------------------------------------------------------------------ *
00289  * OCI_LongGetBuffer
00290  * ------------------------------------------------------------------------ */
00291 
00292 void * OCI_API OCI_LongGetBuffer(OCI_Long *lg)
00293 {
00294     OCI_CHECK_PTR(OCI_IPC_LONG, lg, NULL);
00295 
00296     OCI_RESULT(TRUE);
00297 
00298     return (void *) lg->buffer;
00299 }

Generated on Thu Jul 30 17:41:52 2009 for OCILIB (C Driver for Oracle) by  doxygen 1.5.4