OCILIB (C Driver for Oracle) 3.12.1
file.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: file.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_FileInit
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_File * OCI_FileInit
00046 (
00047     OCI_Connection *con,
00048     OCI_File      **pfile,
00049     OCILobLocator  *handle,
00050     ub4             type
00051 )
00052 {
00053     OCI_File *file = NULL;
00054     boolean res    = TRUE;
00055 
00056     OCI_CHECK(pfile == NULL, NULL);
00057 
00058     if (*pfile == NULL)
00059     {
00060         *pfile = (OCI_File *) OCI_MemAlloc(OCI_IPC_FILE, sizeof(*file), (size_t) 1, TRUE);
00061     }
00062 
00063     if (*pfile != NULL)
00064     {
00065         file = *pfile;
00066 
00067         file->type   = type;
00068         file->con    = con;
00069         file->handle = handle;
00070         file->offset = 1;
00071 
00072         /* reset file info */
00073 
00074         if (file->dir != NULL)
00075         {
00076             file->dir[0] = 0;
00077         }
00078 
00079         if (file->name != NULL)
00080         {
00081             file->name[0] = 0;
00082         }
00083 
00084         if (file->handle == NULL)
00085         {
00086             /* allocate handle for non fetched file (local file object) */
00087 
00088             file->hstate = OCI_OBJECT_ALLOCATED;
00089 
00090             res = (OCI_SUCCESS == OCI_DescriptorAlloc((dvoid *) file->con->env,
00091                                                       (dvoid **) (void *) &file->handle,
00092                                                       (ub4) OCI_DTYPE_LOB,
00093                                                       (size_t) 0, (dvoid **) NULL));
00094         }
00095         else if (file->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00096         {
00097             file->hstate = OCI_OBJECT_FETCHED_CLEAN;
00098         }
00099     }
00100     else
00101     {
00102         res = FALSE;
00103     }
00104 
00105     /* check for failure */
00106 
00107     if (res == FALSE)
00108     {
00109         OCI_FileFree(file);
00110         file = NULL;
00111     }
00112 
00113     return file;
00114 }
00115 
00116 /* --------------------------------------------------------------------------------------------- *
00117  * OCI_FileGetInfo
00118  * --------------------------------------------------------------------------------------------- */
00119 
00120 boolean OCI_FileGetInfo
00121 (
00122     OCI_File *file
00123 )
00124 {
00125     boolean res = TRUE;
00126 
00127     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00128 
00129     /* directory name */
00130 
00131     if (file->dir == NULL)
00132     {
00133         if (res == TRUE)
00134         {
00135             file->dir = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00136                                                (size_t) (OCI_SIZE_DIRECTORY + 1), TRUE);
00137 
00138             res = (file->dir != NULL);
00139         }
00140     }
00141     else
00142     {
00143         file->dir[0] = 0;
00144     }
00145 
00146     /* file name */
00147 
00148     if (file->name == NULL)
00149     {
00150         if (res == TRUE)
00151         {
00152             file->name = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00153                                                 (size_t)( OCI_SIZE_FILENAME + 1),
00154                                                 TRUE);
00155 
00156             res = (file->name != NULL);
00157         }
00158     }
00159     else
00160     {
00161         file->name[0] = 0;
00162     }
00163 
00164     /* retrieve name */
00165 
00166     if (res == TRUE)
00167     {
00168         void *ostr1 = NULL;
00169         void *ostr2 = NULL;
00170         int osize1  = 0;
00171         int osize2  = 0;
00172         ub2 usize1  = 0;
00173         ub2 usize2  = 0;
00174 
00175         osize1 = (int   ) OCI_SIZE_DIRECTORY  * (int) sizeof(mtext);
00176         ostr1  = (void *) OCI_GetInputMetaString(file->dir, &osize1);
00177 
00178         osize2 = (int   ) OCI_SIZE_FILENAME  * (int) sizeof(mtext);
00179         ostr2  = (void *) OCI_GetInputMetaString(file->name, &osize1);
00180 
00181         usize1 = (ub2) osize1;
00182         usize2 = (ub2) osize2;
00183 
00184         OCI_CALL2
00185         (
00186             res, file->con,
00187 
00188             OCILobFileGetName(file->con->env, file->con->err, file->handle,
00189                               (OraText *) ostr1, (ub2*) &usize1,
00190                               (OraText *) ostr2, (ub2*) &usize2)
00191         )
00192 
00193         osize1 = (int) usize1;
00194         osize2 = (int) usize2;
00195 
00196         OCI_GetOutputMetaString(ostr1, file->dir,  &osize1);
00197         OCI_GetOutputMetaString(ostr2, file->name, &osize2);
00198 
00199         OCI_ReleaseMetaString(ostr1);
00200         OCI_ReleaseMetaString(ostr2);
00201     }
00202 
00203     return res;
00204 }
00205 
00206 /* ********************************************************************************************* *
00207  *                            PUBLIC FUNCTIONS
00208  * ********************************************************************************************* */
00209 
00210 /* --------------------------------------------------------------------------------------------- *
00211  * OCI_FileCreate
00212  * --------------------------------------------------------------------------------------------- */
00213 
00214 OCI_File * OCI_API OCI_FileCreate
00215 (
00216     OCI_Connection *con,
00217     unsigned int    type
00218 )
00219 {
00220     OCI_File *file = NULL;
00221 
00222     OCI_CHECK_INITIALIZED(NULL);
00223 
00224     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00225 
00226     file = OCI_FileInit(con, &file, NULL, type);
00227 
00228     OCI_RESULT(file != NULL);
00229 
00230     return file;
00231 }
00232 
00233 /* --------------------------------------------------------------------------------------------- *
00234  * OCI_FileFree
00235  * --------------------------------------------------------------------------------------------- */
00236 
00237 boolean OCI_API OCI_FileFree
00238 (
00239     OCI_File *file
00240 )
00241 {
00242     boolean res = TRUE;
00243 
00244     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00245     OCI_CHECK_OBJECT_FETCHED(file, FALSE);
00246 
00247     OCI_FREE(file->dir);
00248     OCI_FREE(file->name);
00249 
00250     if (file->hstate == OCI_OBJECT_ALLOCATED)
00251     {
00252         OCI_DescriptorFree((dvoid *) file->handle, (ub4) OCI_DTYPE_LOB);
00253     }
00254 
00255     if (file->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00256     {
00257         OCI_FREE(file);
00258     }
00259 
00260     OCI_RESULT(res);
00261 
00262     return res;
00263 }
00264 
00265 /* --------------------------------------------------------------------------------------------- *
00266  * OCI_FileArrayCreate
00267  * --------------------------------------------------------------------------------------------- */
00268 
00269 OCI_File ** OCI_API OCI_FileArrayCreate
00270 (
00271     OCI_Connection *con,
00272     unsigned int    type,
00273     unsigned int    nbelem
00274 )
00275 {
00276     OCI_Array *arr   = NULL;
00277     OCI_File **files = NULL;
00278 
00279     arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_FILE, type,
00280                           sizeof(OCILobLocator *), sizeof(OCI_File),
00281                           OCI_DTYPE_LOB, NULL);
00282 
00283     if (arr != NULL)
00284     {
00285         files = (OCI_File **) arr->tab_obj;
00286     }
00287 
00288     return files;
00289 }
00290 
00291 /* --------------------------------------------------------------------------------------------- *
00292  * OCI_FileArrayFree
00293  * --------------------------------------------------------------------------------------------- */
00294 
00295 boolean OCI_API OCI_FileArrayFree
00296 (
00297     OCI_File **files
00298 )
00299 {
00300     return OCI_ArrayFreeFromHandles((void **) files);
00301 }
00302 
00303 /* --------------------------------------------------------------------------------------------- *
00304  * OCI_FileSeek
00305  * --------------------------------------------------------------------------------------------- */
00306 
00307 boolean OCI_API OCI_FileSeek
00308 (
00309     OCI_File    *file,
00310     big_uint     offset,
00311     unsigned int mode
00312 )
00313 {
00314     boolean res   = TRUE;
00315     big_uint size = 0;
00316 
00317     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00318 
00319     size = OCI_FileGetSize(file);
00320 
00321     if ((mode == OCI_SEEK_CUR && (offset + file->offset-1) > size))
00322     {
00323         res = FALSE;
00324     }
00325     else if (mode == OCI_SEEK_SET)
00326     {
00327         file->offset = offset + 1;
00328     }
00329     else if (mode == OCI_SEEK_END)
00330     {
00331         file->offset = size-offset + 1;
00332     }
00333     else if (mode == OCI_SEEK_CUR)
00334     {
00335         file->offset += offset;
00336     }
00337     else
00338     {
00339         res = FALSE;
00340     }
00341 
00342     OCI_RESULT(res);
00343 
00344     return res;
00345 }
00346 
00347 /* --------------------------------------------------------------------------------------------- *
00348  * OCI_FileGetOffset
00349  * --------------------------------------------------------------------------------------------- */
00350 
00351 big_uint OCI_API OCI_FileGetOffset
00352 (
00353     OCI_File *file
00354 )
00355 {
00356     OCI_CHECK_PTR(OCI_IPC_FILE, file, 0);
00357 
00358     OCI_RESULT(TRUE);
00359 
00360     return file->offset - 1;
00361 }
00362 
00363 /* --------------------------------------------------------------------------------------------- *
00364  * OCI_FileRead
00365  * --------------------------------------------------------------------------------------------- */
00366 
00367 unsigned int OCI_API OCI_FileRead
00368 (
00369     OCI_File    *file,
00370     void        *buffer,
00371     unsigned int len
00372 )
00373 {
00374     boolean res  = TRUE;
00375     ub4 size_in  = 0;
00376     ub4 size_out = 0;
00377 
00378     OCI_CHECK_PTR(OCI_IPC_FILE, file, 0);
00379     OCI_CHECK_MIN(file->con, NULL, len, 1, 0);
00380 
00381     size_out = size_in = len;
00382 
00383 #ifdef OCI_LOB2_API_ENABLED
00384 
00385     if (OCILib.use_lob_ub8)
00386     {
00387         ub8 size_char = (ub8) len;
00388         ub8 size_byte = (ub8) size_in;
00389 
00390         OCI_CALL2
00391         (
00392             res, file->con,
00393 
00394             OCILobRead2(file->con->cxt, file->con->err,
00395                         file->handle, &size_byte,
00396                         &size_char, (ub8) file->offset,
00397                         buffer, (ub8) size_in,
00398                         (ub1) OCI_ONE_PIECE, (dvoid *) NULL,
00399                         NULL, (ub2) 0, (ub1) SQLCS_IMPLICIT)
00400         )
00401     }
00402 
00403     else
00404 
00405  #endif
00406 
00407     {
00408         ub4 offset = (ub4) file->offset;
00409 
00410         OCI_CALL2
00411         (
00412             res, file->con,
00413 
00414             OCILobRead(file->con->cxt, file->con->err,
00415                        file->handle,  &size_out, offset,
00416                        buffer, size_in, (dvoid *) NULL,
00417                        NULL, (ub2) 0, (ub1) SQLCS_IMPLICIT)
00418         )
00419     }
00420 
00421     if (res == TRUE)
00422     {
00423         file->offset += (big_uint) size_out;
00424     }
00425 
00426     OCI_RESULT(res);
00427 
00428     return size_out;
00429 }
00430 
00431 /* --------------------------------------------------------------------------------------------- *
00432  * OCI_FileGetType
00433  * --------------------------------------------------------------------------------------------- */
00434 
00435 unsigned int OCI_API OCI_FileGetType
00436 (
00437     OCI_File *file
00438 )
00439 {
00440     OCI_CHECK_PTR(OCI_IPC_FILE, file, OCI_UNKNOWN);
00441 
00442     OCI_RESULT(TRUE);
00443 
00444     return file->type;
00445 }
00446 
00447 /* --------------------------------------------------------------------------------------------- *
00448  * OCI_FileGetSize
00449  * --------------------------------------------------------------------------------------------- */
00450 
00451 big_uint OCI_API OCI_FileGetSize
00452 (
00453     OCI_File *file
00454 )
00455 {
00456     boolean res   = TRUE;
00457     big_uint size = 0;
00458 
00459     OCI_CHECK_PTR(OCI_IPC_FILE, file, 0);
00460 
00461 #ifdef OCI_LOB2_API_ENABLED
00462 
00463     if (OCILib.use_lob_ub8)
00464     {
00465         OCI_CALL2
00466         (
00467             res, file->con,
00468 
00469             OCILobGetLength2(file->con->cxt, file->con->err, file->handle, (ub8 *) &size)
00470         )
00471 
00472     }
00473     else
00474 
00475 #endif
00476 
00477     {
00478         ub4 size32 = (ub4) size;
00479 
00480         OCI_CALL2
00481         (
00482             res, file->con,
00483 
00484             OCILobGetLength(file->con->cxt, file->con->err, file->handle, &size32)
00485         )
00486 
00487         size = (big_uint) size32;
00488     }
00489 
00490     OCI_RESULT(res);
00491 
00492     return size;
00493 }
00494 
00495 /* --------------------------------------------------------------------------------------------- *
00496  * OCI_LobFileExists
00497  * --------------------------------------------------------------------------------------------- */
00498 
00499 boolean OCI_API OCI_FileExists
00500 (
00501     OCI_File *file
00502 )
00503 {
00504     boolean res   = TRUE;
00505     boolean value = FALSE;
00506 
00507     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00508 
00509     OCI_CALL2
00510     (
00511         res, file->con,
00512 
00513         OCILobFileExists(file->con->cxt, file->con->err, file->handle, &value)
00514     )
00515 
00516     OCI_RESULT(res);
00517 
00518     return value;
00519 }
00520 
00521 /* --------------------------------------------------------------------------------------------- *
00522  * OCI_FileSetName
00523  * --------------------------------------------------------------------------------------------- */
00524 
00525 boolean OCI_API OCI_FileSetName
00526 (
00527     OCI_File    *file,
00528     const mtext *dir,
00529     const mtext *name
00530 )
00531 {
00532     void *ostr1 = NULL;
00533     void *ostr2 = NULL;
00534     int osize1  = -1;
00535     int osize2  = -1;
00536     boolean res = TRUE;
00537 
00538     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00539 
00540     ostr1 = OCI_GetInputMetaString(dir,  &osize1);
00541     ostr2 = OCI_GetInputMetaString(name, &osize2);
00542 
00543     OCI_CALL2
00544     (
00545         res, file->con,
00546 
00547         OCILobFileSetName(file->con->env, file->con->err,
00548                           &file->handle,
00549                           (OraText *) ostr1, (ub2) osize1,
00550                           (OraText *) ostr2, (ub2) osize2)
00551     )
00552 
00553     OCI_ReleaseMetaString(ostr1);
00554     OCI_ReleaseMetaString(ostr2);
00555 
00556     if (res == TRUE)
00557     {
00558         res = OCI_FileGetInfo(file);
00559     }
00560 
00561     OCI_RESULT(res);
00562 
00563     return res;
00564 }
00565 
00566 /* --------------------------------------------------------------------------------------------- *
00567  * OCI_FileGetDirectory
00568  * --------------------------------------------------------------------------------------------- */
00569 
00570 const mtext * OCI_API OCI_FileGetDirectory
00571 (
00572     OCI_File *file
00573 )
00574 {
00575     boolean res = TRUE;
00576 
00577     OCI_CHECK_PTR(OCI_IPC_FILE, file, NULL);
00578 
00579     if ((file->dir == NULL) || (file->dir[0] == 0))
00580     {
00581         res = OCI_FileGetInfo(file);
00582     }
00583 
00584     OCI_RESULT(res);
00585 
00586     return file->dir;
00587 }
00588 
00589 /* --------------------------------------------------------------------------------------------- *
00590  * OCI_FileGetName
00591  * --------------------------------------------------------------------------------------------- */
00592 
00593 const mtext * OCI_API OCI_FileGetName
00594 (
00595     OCI_File *file
00596 )
00597 {
00598     boolean res = TRUE;
00599 
00600     OCI_CHECK_PTR(OCI_IPC_FILE, file, NULL);
00601 
00602     if ((file->name == NULL) || (file->name[0] == 0))
00603     {
00604         res = OCI_FileGetInfo(file);
00605     }
00606 
00607     OCI_RESULT(res);
00608 
00609     return file->name;
00610 }
00611 
00612 /* --------------------------------------------------------------------------------------------- *
00613  * OCI_FileOpen
00614  * --------------------------------------------------------------------------------------------- */
00615 
00616 boolean OCI_API OCI_FileOpen
00617 (
00618     OCI_File *file
00619 )
00620 {
00621     boolean res = TRUE;
00622 
00623     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00624 
00625     OCI_CALL2
00626     (
00627         res, file->con,
00628 
00629         OCILobFileOpen(file->con->cxt, file->con->err, file->handle, (ub1) OCI_LOB_READONLY)
00630     )
00631 
00632     if (res == TRUE)
00633     {
00634         file->con->nb_files++;
00635     }
00636 
00637     OCI_RESULT(res);
00638 
00639     return res;
00640 }
00641 
00642 /* --------------------------------------------------------------------------------------------- *
00643  * OCI_LobFileIsOpen
00644  * --------------------------------------------------------------------------------------------- */
00645 
00646 boolean OCI_API OCI_FileIsOpen
00647 (
00648     OCI_File *file
00649 )
00650 {
00651     boolean res   = TRUE;
00652     boolean value = FALSE;
00653 
00654     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00655 
00656     OCI_CALL2
00657     (
00658         res, file->con,
00659 
00660         OCILobFileIsOpen(file->con->cxt, file->con->err, file->handle, &value)
00661     )
00662 
00663     OCI_RESULT(res);
00664 
00665     return value;
00666 }
00667 
00668 /* --------------------------------------------------------------------------------------------- *
00669  * OCI_FileClose
00670  * --------------------------------------------------------------------------------------------- */
00671 
00672 boolean OCI_API OCI_FileClose
00673 (
00674     OCI_File *file
00675 )
00676 {
00677     boolean res = TRUE;
00678 
00679     OCI_CHECK_PTR(OCI_IPC_FILE, file, FALSE);
00680 
00681     OCI_CALL2
00682     (
00683         res, file->con,
00684 
00685         OCILobFileClose(file->con->cxt, file->con->err, file->handle)
00686     )
00687 
00688     if (res == TRUE)
00689     {
00690         file->con->nb_files--;
00691     }
00692 
00693     OCI_RESULT(res);
00694 
00695     return res;
00696 }
00697 
00698 /* --------------------------------------------------------------------------------------------- *
00699  * OCI_FileIsEqual
00700  * --------------------------------------------------------------------------------------------- */
00701 
00702 boolean OCI_API OCI_FileIsEqual
00703 (
00704     OCI_File *file,
00705     OCI_File *file2
00706 )
00707 {
00708     boolean res   = TRUE;
00709     boolean value = FALSE;
00710 
00711     OCI_CHECK_PTR(OCI_IPC_FILE, file,  FALSE);
00712     OCI_CHECK_PTR(OCI_IPC_FILE, file2, FALSE);
00713 
00714     OCI_CALL2
00715     (
00716         res, file->con,
00717 
00718         OCILobIsEqual(file->con->env, file->handle, file2->handle, &value)
00719     )
00720 
00721     OCI_RESULT(res);
00722 
00723     return value;
00724 }
00725 
00726 /* --------------------------------------------------------------------------------------------- *
00727  * OCI_FileAssign
00728  * --------------------------------------------------------------------------------------------- */
00729 
00730 boolean OCI_API OCI_FileAssign
00731 (
00732     OCI_File *file,
00733     OCI_File *file_src
00734 )
00735 {
00736     boolean res = TRUE;
00737 
00738     OCI_CHECK_PTR(OCI_IPC_FILE, file,     FALSE);
00739     OCI_CHECK_PTR(OCI_IPC_FILE, file_src, FALSE);
00740 
00741     if ((file->hstate == OCI_OBJECT_ALLOCATED) || (file->hstate == OCI_OBJECT_ALLOCATED_ARRAY))
00742     {
00743         OCI_CALL2
00744         (
00745             res, file->con,
00746 
00747             OCILobLocatorAssign(file->con->cxt, file->con->err, file_src->handle, &file->handle)
00748         )
00749     }
00750     else
00751     {
00752         OCI_CALL2
00753         (
00754             res, file->con,
00755 
00756             OCILobAssign(file->con->env, file->con->err, file_src->handle, &file->handle)
00757         )
00758     }
00759 
00760     if (res == TRUE)
00761     {
00762         OCI_FileGetInfo(file);
00763     }
00764 
00765     OCI_RESULT(res);
00766 
00767     return res;
00768 }