PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/oci8 - oci8_lob.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 419 0.0 %
Date: 2014-04-16 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Stig Sæther Bakken <ssb@php.net>                            |
      16             :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17             :    |                                                                      |
      18             :    | Collection support by Andy Sautins <asautins@veripost.net>           |
      19             :    | Temporary LOB support by David Benson <dbenson@mancala.com>          |
      20             :    | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at>        |
      21             :    |                                                                      |
      22             :    | Redesigned by: Antony Dovgal <antony@zend.com>                       |
      23             :    |                Andi Gutmans <andi@zend.com>                          |
      24             :    |                Wez Furlong <wez@omniti.com>                          |
      25             :    +----------------------------------------------------------------------+
      26             : */
      27             : 
      28             : /* $Id$ */
      29             : 
      30             : 
      31             : 
      32             : #ifdef HAVE_CONFIG_H
      33             : #include "config.h"
      34             : #endif
      35             : 
      36             : #include "php.h"
      37             : #include "ext/standard/info.h"
      38             : #include "php_ini.h"
      39             : 
      40             : #if HAVE_OCI8
      41             : 
      42             : #include "php_oci8.h"
      43             : #include "php_oci8_int.h"
      44             : 
      45             : /* for import/export functions */
      46             : #include <fcntl.h>
      47             : 
      48             : #ifndef O_BINARY
      49             : #define O_BINARY 0
      50             : #endif
      51             : 
      52             : /* {{{ php_oci_lob_create()
      53             :  Create LOB descriptor and allocate all the resources needed */
      54           0 : php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long type TSRMLS_DC)
      55             : {
      56             :         php_oci_descriptor *descriptor;
      57             :         sword errstatus;
      58             : 
      59           0 :         switch (type) {
      60             :                 case OCI_DTYPE_FILE:
      61             :                 case OCI_DTYPE_LOB:
      62             :                 case OCI_DTYPE_ROWID:
      63             :                         /* these three are allowed */
      64           0 :                         break;
      65             :                 default:
      66           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown descriptor type %ld", type);
      67           0 :                         return NULL;
      68             :                         break;
      69             :         }
      70             : 
      71           0 :         descriptor = ecalloc(1, sizeof(php_oci_descriptor));
      72           0 :         descriptor->type = type;
      73           0 :         descriptor->connection = connection;
      74           0 :         zend_list_addref(descriptor->connection->id);
      75             : 
      76           0 :         PHP_OCI_CALL_RETURN(errstatus, OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0));
      77             : 
      78           0 :         if (errstatus != OCI_SUCCESS) {
      79           0 :                 OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
      80           0 :                 PHP_OCI_HANDLE_ERROR(connection, OCI_G(errcode));
      81           0 :                 efree(descriptor);
      82           0 :                 return NULL;
      83             :         } else {
      84           0 :                 OCI_G(errcode) = 0; /* retain backwards compat with OCI8 1.4 */
      85             :         }
      86             : 
      87           0 :         PHP_OCI_REGISTER_RESOURCE(descriptor, le_descriptor);
      88             :         
      89           0 :         descriptor->lob_current_position = 0;
      90           0 :         descriptor->lob_size = -1;                           /* we should set it to -1 to know, that it's just not initialized */
      91           0 :         descriptor->buffering = PHP_OCI_LOB_BUFFER_DISABLED;                         /* buffering is off by default */
      92           0 :         descriptor->charset_form = SQLCS_IMPLICIT;   /* default value */
      93           0 :         descriptor->charset_id = connection->charset;
      94           0 :         descriptor->is_open = 0;
      95           0 :         descriptor->chunk_size = 0;
      96             : 
      97           0 :         if (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE) {
      98             :                 /* add Lobs & Files to hash. we'll flush them at the end */
      99           0 :                 if (!connection->descriptors) {
     100           0 :                         ALLOC_HASHTABLE(connection->descriptors);
     101           0 :                         zend_hash_init(connection->descriptors, 0, NULL, php_oci_descriptor_flush_hash_dtor, 0);
     102           0 :                         connection->descriptor_count = 0;
     103             :                 }
     104             :                 
     105           0 :                 descriptor->index = (connection->descriptor_count)++;
     106           0 :                 if (connection->descriptor_count == LONG_MAX) {
     107           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal descriptor counter has reached limit");
     108           0 :                         php_oci_connection_descriptors_free(connection TSRMLS_CC);
     109           0 :                         return NULL;
     110             :                 }
     111             : 
     112           0 :                 zend_hash_index_update(connection->descriptors,descriptor->index,&descriptor,sizeof(php_oci_descriptor *),NULL);
     113             :         }
     114           0 :         return descriptor;
     115             : 
     116             : }
     117             : /* }}} */
     118             : 
     119             : /* {{{ php_oci_lob_get_length()
     120             :  Get length of the LOB. The length is cached so we don't need to ask Oracle every time */
     121           0 : int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_DC)
     122             : {
     123           0 :         php_oci_connection *connection = descriptor->connection;
     124             :         sword errstatus;
     125             : 
     126           0 :         *length = 0;
     127             :         
     128           0 :         if (descriptor->lob_size >= 0) {
     129           0 :                 *length = descriptor->lob_size;
     130           0 :                 return 0;
     131             :         } else {
     132           0 :                 if (descriptor->type == OCI_DTYPE_FILE) {
     133           0 :                         PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
     134           0 :                         if (errstatus != OCI_SUCCESS) {
     135           0 :                                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     136           0 :                                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     137           0 :                                 return 1;
     138             :                         }
     139             :                 }
     140             :                 
     141           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobGetLength, (connection->svc, connection->err, descriptor->descriptor, (ub4 *)length));
     142             : 
     143           0 :                 if (errstatus != OCI_SUCCESS) {
     144           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     145           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     146           0 :                         return 1;
     147             :                 }
     148             : 
     149           0 :                 descriptor->lob_size = *length;
     150             : 
     151           0 :                 if (descriptor->type == OCI_DTYPE_FILE) {
     152           0 :                         PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
     153             : 
     154           0 :                         if (errstatus != OCI_SUCCESS) {
     155           0 :                                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     156           0 :                                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     157           0 :                                 return 1;
     158             :                         }
     159             :                 }
     160             : 
     161           0 :                 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     162             :         }
     163           0 :         return 0;       
     164             : }
     165             : /* }}} */
     166             : 
     167             : /* {{{ php_oci_lob_callback()
     168             :    Append LOB portion to a memory buffer */
     169           0 : sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp)
     170             : {
     171           0 :         ub4 lenp = (ub4) len;
     172           0 :         php_oci_lob_ctx *ctx = (php_oci_lob_ctx *)ctxp;
     173             : 
     174           0 :         switch (piece)
     175             :         {
     176             :                 case OCI_LAST_PIECE:
     177           0 :                         if ((*(ctx->lob_len) + lenp) > (ctx->alloc_len)) {
     178             :                                 /* this should not happen ever */
     179           0 :                                 *(ctx->lob_data) = NULL;
     180           0 :                                 *(ctx->lob_len) = 0;
     181           0 :                                 return OCI_ERROR;
     182             :                         }
     183           0 :                         memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
     184           0 :                         *(ctx->lob_len) += lenp;
     185           0 :                         *(*(ctx->lob_data) + *(ctx->lob_len)) = 0x00;
     186           0 :                         return OCI_CONTINUE;
     187             : 
     188             :                 case OCI_FIRST_PIECE:
     189             :                 case OCI_NEXT_PIECE:
     190           0 :                         if ((*(ctx->lob_len) + lenp) > ctx->alloc_len) {
     191             :                                 /* this should not happen ever */
     192           0 :                                 *(ctx->lob_data) = NULL;
     193           0 :                                 *(ctx->lob_len) = 0;
     194           0 :                                 return OCI_ERROR;
     195             :                         }
     196           0 :                         memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
     197           0 :                         *(ctx->lob_len) += lenp;
     198           0 :                         return OCI_CONTINUE;
     199             : 
     200             :                 default: {
     201             :                         TSRMLS_FETCH();
     202           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected LOB piece id received (value:%d)", piece);
     203           0 :                         *(ctx->lob_data) = NULL;
     204           0 :                         *(ctx->lob_len) = 0;
     205           0 :                         return OCI_ERROR;
     206             :                 }
     207             :         }
     208             : }
     209             : /* }}} */
     210             : 
     211             : /* {{{ php_oci_lob_calculate_buffer() 
     212             :    Work out the size for LOB buffering */
     213           0 : static inline int php_oci_lob_calculate_buffer(php_oci_descriptor *descriptor, long read_length TSRMLS_DC)
     214             : {
     215           0 :         php_oci_connection *connection = descriptor->connection;
     216             :         ub4 chunk_size;
     217             :         sword errstatus;
     218             : 
     219           0 :         if (descriptor->type == OCI_DTYPE_FILE) {
     220           0 :                 return read_length;
     221             :         }
     222             : 
     223           0 :         if (!descriptor->chunk_size) {
     224           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobGetChunkSize, (connection->svc, connection->err, descriptor->descriptor, &chunk_size));
     225             : 
     226           0 :                 if (errstatus != OCI_SUCCESS) {
     227           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     228           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     229           0 :                         return read_length; /* we have to return original length here */
     230             :                 }
     231           0 :                 descriptor->chunk_size = chunk_size;
     232           0 :                 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     233             :         }
     234             :         
     235           0 :         if ((read_length % descriptor->chunk_size) != 0) {
     236           0 :                 return descriptor->chunk_size * ((read_length / descriptor->chunk_size) + 1);
     237             :         }
     238           0 :         return read_length;
     239             : }
     240             : /* }}} */
     241             : 
     242             : /* {{{ php_oci_lob_read()
     243             :  Read specified portion of the LOB into the buffer */
     244           0 : int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long initial_offset, char **data, ub4 *data_len TSRMLS_DC)
     245             : {
     246           0 :         php_oci_connection *connection = descriptor->connection;
     247           0 :         ub4 length = 0;
     248           0 :         int buffer_size = PHP_OCI_LOB_BUFFER_SIZE;
     249             :         php_oci_lob_ctx ctx;
     250             :         ub1 *bufp;
     251           0 :         oraub8 bytes_read, offset = 0;
     252           0 :         oraub8 requested_len = read_length; /* this is by default */
     253           0 :         oraub8 chars_read = 0;
     254           0 :         int is_clob = 0;
     255           0 :         sb4 bytes_per_char = 1;
     256             :         sword errstatus;
     257             : 
     258           0 :         *data_len = 0;
     259           0 :         *data = NULL;
     260             : 
     261           0 :         ctx.lob_len = data_len;
     262           0 :         ctx.lob_data = data;
     263           0 :         ctx.alloc_len = 0;
     264             : 
     265           0 :         if (php_oci_lob_get_length(descriptor, &length TSRMLS_CC)) {
     266           0 :                 return 1;
     267             :         }
     268             : 
     269           0 :         if (length <= 0) {
     270           0 :                 return 0;
     271             :         }
     272             :         
     273           0 :         if (initial_offset > length) {
     274           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset must be less than size of the LOB");
     275           0 :                 return 1;
     276             :         }
     277             :                 
     278           0 :         if (read_length == -1) {
     279           0 :                 requested_len = length;
     280             :         }
     281             :         
     282           0 :         if (requested_len > (length - initial_offset)) {
     283           0 :                 requested_len = length - initial_offset;
     284             :         }
     285             :         
     286           0 :         if (requested_len <= 0) {
     287           0 :                 return 0;
     288             :         }
     289             :         
     290           0 :         offset = initial_offset;
     291             : 
     292           0 :         if (descriptor->type == OCI_DTYPE_FILE) {
     293           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
     294             : 
     295           0 :                 if (errstatus != OCI_SUCCESS) {
     296           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     297           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     298           0 :                         return 1;
     299             :                 }
     300             :         } else {
     301           0 :                 ub2 charset_id = 0;
     302             : 
     303           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id));
     304             : 
     305           0 :                 if (errstatus != OCI_SUCCESS) {
     306           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     307           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     308           0 :                         return 1;
     309             :                 }
     310             : 
     311           0 :                 if (charset_id > 0) { /* charset_id is always > 0 for [N]CLOBs */
     312           0 :                         is_clob = 1;
     313             :                 }
     314             :         }
     315             : 
     316           0 :         if (is_clob) {
     317           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCINlsNumericInfoGet, (connection->env, connection->err, &bytes_per_char, OCI_NLS_CHARSET_MAXBYTESZ));
     318             : 
     319           0 :                 if (errstatus != OCI_SUCCESS) {
     320           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     321           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     322           0 :                         return 1;
     323             :                 }
     324             :         } else {
     325             :                 /* BLOBs don't have encoding, so bytes_per_char == 1 */
     326             :         }
     327             : 
     328           0 :         ctx.alloc_len = (requested_len + 1) * bytes_per_char;
     329           0 :         *data = ecalloc(bytes_per_char, requested_len + 1);
     330             : 
     331           0 :         if (is_clob) {
     332           0 :                 chars_read = requested_len;
     333           0 :                 bytes_read = 0;
     334             :         } else {
     335           0 :                 chars_read = 0;
     336           0 :                 bytes_read = requested_len;
     337             :         }
     338             : 
     339           0 :         buffer_size = (requested_len < buffer_size ) ? requested_len : buffer_size;          /* optimize buffer size */
     340           0 :         buffer_size = php_oci_lob_calculate_buffer(descriptor, buffer_size TSRMLS_CC);  /* use chunk size */
     341             : 
     342           0 :         bufp = (ub1 *) ecalloc(1, buffer_size);
     343           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobRead2,
     344             :                 (
     345             :                         connection->svc,
     346             :                         connection->err,
     347             :                         descriptor->descriptor,
     348             :                         (oraub8 *)&bytes_read,                                                      /* IN/OUT bytes toread/read */
     349             :                         (oraub8 *)&chars_read,                                                      /* IN/OUT chars toread/read */
     350             :                         (oraub8) offset + 1,                                                    /* offset (starts with 1) */
     351             :                         (dvoid *) bufp,
     352             :                         (oraub8) buffer_size,                                                   /* size of buffer */
     353             :                         OCI_FIRST_PIECE,
     354             :                         (dvoid *)&ctx,
     355             :                         (OCICallbackLobRead2) php_oci_lob_callback,                             /* callback... */
     356             :                         (ub2) descriptor->charset_id,                           /* The character set ID of the buffer data. */
     357             :                         (ub1) descriptor->charset_form                                         /* The character set form of the buffer data. */
     358             :                 )
     359             :         );
     360             :         
     361           0 :         efree(bufp);
     362             :         
     363           0 :         if (is_clob) {
     364           0 :                 offset = descriptor->lob_current_position + chars_read;
     365             :         } else {
     366           0 :                 offset = descriptor->lob_current_position + bytes_read;
     367             :         }
     368             :         
     369           0 :         if (errstatus != OCI_SUCCESS) {
     370           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     371           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     372           0 :                 if (*data) {
     373           0 :                         efree(*data);
     374           0 :                         *data = NULL;
     375             :                 }
     376           0 :                 *data_len = 0;
     377           0 :                 return 1;
     378             :         }
     379             :         
     380           0 :         descriptor->lob_current_position = (int)offset;
     381             : 
     382           0 :         if (descriptor->type == OCI_DTYPE_FILE) {
     383           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
     384             : 
     385           0 :                 if (errstatus != OCI_SUCCESS) {
     386           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     387           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     388           0 :                         if (*data) {
     389           0 :                                 efree(*data);
     390           0 :                                 *data = NULL;
     391             :                         }
     392           0 :                         *data_len = 0;
     393           0 :                         return 1;
     394             :                 }
     395             :         }
     396             : 
     397           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     398           0 :         return 0;
     399             : }
     400             : /* }}} */
     401             : 
     402             : /* {{{ php_oci_lob_write()
     403             :  Write data to the LOB */
     404           0 : int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, int data_len, ub4 *bytes_written TSRMLS_DC)
     405             : {
     406           0 :         OCILobLocator *lob                 = (OCILobLocator *) descriptor->descriptor;
     407           0 :         php_oci_connection *connection = (php_oci_connection *) descriptor->connection;
     408             :         ub4 lob_length;
     409             :         sword errstatus;
     410             :         
     411           0 :         *bytes_written = 0;
     412           0 :         if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
     413           0 :                 return 1;
     414             :         }
     415             :         
     416           0 :         if (!data || data_len <= 0) {
     417           0 :                 return 0;
     418             :         }
     419             :         
     420           0 :         if (offset < 0) {
     421             :                 offset = 0;
     422             :         }
     423             :         
     424           0 :         if (offset > descriptor->lob_current_position) {
     425           0 :                 offset = descriptor->lob_current_position;
     426             :         }
     427             :         
     428           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobWrite,
     429             :                         (
     430             :                                 connection->svc,
     431             :                                 connection->err,
     432             :                                 lob,
     433             :                                 (ub4 *)&data_len,
     434             :                                 (ub4) offset + 1,
     435             :                                 (dvoid *) data,
     436             :                                 (ub4) data_len,
     437             :                                 OCI_ONE_PIECE,
     438             :                                 (dvoid *)0,
     439             :                                 (OCICallbackLobWrite) 0,
     440             :                                 (ub2) descriptor->charset_id,
     441             :                                 (ub1) descriptor->charset_form
     442             :                         )
     443             :                 );
     444             : 
     445           0 :         if (errstatus) {
     446           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     447           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     448           0 :                 *bytes_written = 0;
     449           0 :                 return 1;
     450             :         }
     451           0 :         *bytes_written = data_len;
     452           0 :         descriptor->lob_current_position += data_len;
     453             :         
     454           0 :         if (descriptor->lob_current_position > descriptor->lob_size) {
     455           0 :                 descriptor->lob_size = descriptor->lob_current_position;
     456             :         }
     457             :         
     458             :         /* marking buffer as used */
     459           0 :         if (descriptor->buffering == PHP_OCI_LOB_BUFFER_ENABLED) {
     460           0 :                 descriptor->buffering = PHP_OCI_LOB_BUFFER_USED;
     461             :         }
     462             :         
     463           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     464           0 :         return 0;
     465             : }
     466             : /* }}} */
     467             : 
     468             : /* {{{ php_oci_lob_set_buffering()
     469             :  Turn buffering off/onn for this particular LOB */
     470           0 : int php_oci_lob_set_buffering (php_oci_descriptor *descriptor, int on_off TSRMLS_DC)
     471             : {
     472           0 :         php_oci_connection *connection = descriptor->connection;
     473             :         sword errstatus;
     474             : 
     475           0 :         if (!on_off && descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
     476             :                 /* disabling when it's already off */
     477           0 :                 return 0;
     478             :         }
     479             :         
     480           0 :         if (on_off && descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
     481             :                 /* enabling when it's already on */
     482           0 :                 return 0;
     483             :         }
     484             :         
     485           0 :         if (on_off) {
     486           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobEnableBuffering, (connection->svc, connection->err, descriptor->descriptor));
     487             :         } else {
     488           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobDisableBuffering, (connection->svc, connection->err, descriptor->descriptor));
     489             :         }
     490             : 
     491           0 :         if (errstatus != OCI_SUCCESS) {
     492           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     493           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     494           0 :                 return 1;
     495             :         }
     496           0 :         descriptor->buffering = on_off ? PHP_OCI_LOB_BUFFER_ENABLED : PHP_OCI_LOB_BUFFER_DISABLED;
     497           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     498           0 :         return 0;
     499             : }
     500             : /* }}} */
     501             : 
     502             : /* {{{ php_oci_lob_get_buffering()
     503             :  Return current buffering state for the LOB */
     504           0 : int php_oci_lob_get_buffering (php_oci_descriptor *descriptor)
     505             : {
     506           0 :         if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
     507           0 :                 return 1;
     508             :         } else {
     509           0 :                 return 0;
     510             :         }
     511             : }
     512             : /* }}} */
     513             : 
     514             : /* {{{ php_oci_lob_copy()
     515             :  Copy one LOB (or its part) to another one */
     516           0 : int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from, long length TSRMLS_DC)
     517             : {
     518           0 :         php_oci_connection *connection = descriptor_dest->connection;
     519             :         ub4 length_dest, length_from, copy_len;
     520             :         sword errstatus;
     521             :         
     522           0 :         if (php_oci_lob_get_length(descriptor_dest, &length_dest TSRMLS_CC)) {
     523           0 :                 return 1;
     524             :         }
     525             :         
     526           0 :         if (php_oci_lob_get_length(descriptor_from, &length_from TSRMLS_CC)) {
     527           0 :                 return 1;
     528             :         }
     529             : 
     530           0 :         if (length == -1) {
     531           0 :                 copy_len = length_from - descriptor_from->lob_current_position;
     532             :         } else {
     533           0 :                 copy_len = length;
     534             :         }
     535             : 
     536           0 :         if ((int)copy_len <= 0) {
     537             :                 /* silently fail, there is nothing to copy */
     538           0 :                 return 1;
     539             :         }
     540             : 
     541           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobCopy,
     542             :                         (
     543             :                          connection->svc,
     544             :                          connection->err,
     545             :                          descriptor_dest->descriptor,
     546             :                          descriptor_from->descriptor,
     547             :                          copy_len,
     548             :                          descriptor_dest->lob_current_position+1,
     549             :                          descriptor_from->lob_current_position+1
     550             :                         )
     551             :         );
     552             : 
     553           0 :         if (errstatus != OCI_SUCCESS) {
     554           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     555           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     556           0 :                 return 1;
     557             :         }
     558             :         
     559           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     560           0 :         return 0;
     561             : }
     562             : /* }}} */
     563             : 
     564             : /* {{{ php_oci_lob_close()
     565             :  Close LOB */
     566           0 : int php_oci_lob_close (php_oci_descriptor *descriptor TSRMLS_DC)
     567             : {
     568           0 :         php_oci_connection *connection = descriptor->connection;
     569             :         sword errstatus;
     570             : 
     571           0 :         if (descriptor->is_open) {
     572           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobClose, (connection->svc, connection->err, descriptor->descriptor));
     573             : 
     574           0 :                 if (errstatus != OCI_SUCCESS) {
     575           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     576           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     577           0 :                         return 1;
     578             :                 }
     579           0 :                 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     580             :         }
     581             : 
     582           0 :         if (php_oci_temp_lob_close(descriptor TSRMLS_CC)) {
     583           0 :                 return 1;
     584             :         }
     585             :         
     586           0 :         return 0;
     587             : }
     588             : /* }}} */
     589             : 
     590             : /* {{{ php_oci_temp_lob_close()
     591             :    Close Temporary LOB */
     592           0 : int php_oci_temp_lob_close (php_oci_descriptor *descriptor TSRMLS_DC)
     593             : {
     594           0 :         php_oci_connection *connection = descriptor->connection;
     595             :         int is_temporary;
     596             :         sword errstatus;
     597             : 
     598           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobIsTemporary, (connection->env,connection->err, descriptor->descriptor, &is_temporary));
     599             :         
     600           0 :         if (errstatus != OCI_SUCCESS) {
     601           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     602           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     603           0 :                 return 1;
     604             :         }
     605             :         
     606           0 :         if (is_temporary) {
     607           0 :                 PHP_OCI_CALL_RETURN(errstatus, OCILobFreeTemporary, (connection->svc, connection->err, descriptor->descriptor));
     608             :                 
     609           0 :                 if (errstatus != OCI_SUCCESS) {
     610           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     611           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     612           0 :                         return 1;
     613             :                 }
     614             :         }
     615           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     616           0 :         return 0;
     617             : }
     618             : /* }}} */
     619             : 
     620             : /* {{{ php_oci_lob_flush()
     621             :  Flush buffers for the LOB (only if they have been used) */
     622           0 : int php_oci_lob_flush(php_oci_descriptor *descriptor, long flush_flag TSRMLS_DC)
     623             : {
     624           0 :         OCILobLocator *lob = descriptor->descriptor;
     625           0 :         php_oci_connection *connection = descriptor->connection;
     626             :         sword errstatus;
     627             : 
     628           0 :         if (!lob) {
     629           0 :                 return 1;
     630             :         }
     631             : 
     632           0 :         switch (flush_flag) {
     633             :                 case 0:
     634             :                 case OCI_LOB_BUFFER_FREE:
     635             :                         /* only these two are allowed */
     636           0 :                         break;
     637             :                 default:
     638           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid flag value: %ld", flush_flag);
     639           0 :                         return 1;
     640             :                         break;
     641             :         }
     642             :         
     643             :         /* do not really flush buffer, but report success
     644             :          * to suppress OCI error when flushing not used buffer
     645             :          * */
     646           0 :         if (descriptor->buffering != PHP_OCI_LOB_BUFFER_USED) {
     647           0 :                 return 0;
     648             :         }
     649             : 
     650           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobFlushBuffer, (connection->svc, connection->err, lob, flush_flag));
     651             : 
     652           0 :         if (errstatus != OCI_SUCCESS) {
     653           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     654           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     655           0 :                 return 1;
     656             :         }
     657             : 
     658             :         /* marking buffer as enabled and not used */
     659           0 :         descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
     660           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     661           0 :         return 0;
     662             : }
     663             : /* }}} */
     664             : 
     665             : /* {{{ php_oci_lob_free()
     666             :  Close LOB descriptor and free associated resources */
     667           0 : void php_oci_lob_free (php_oci_descriptor *descriptor TSRMLS_DC)
     668             : {
     669           0 :         if (!descriptor || !descriptor->connection) {
     670           0 :                 return;
     671             :         }
     672             : 
     673           0 :         if (descriptor->connection->descriptors) {
     674             :                 /* delete descriptor from the hash */
     675           0 :                 zend_hash_index_del(descriptor->connection->descriptors, descriptor->index);
     676           0 :                 if (zend_hash_num_elements(descriptor->connection->descriptors) == 0) {
     677           0 :                         descriptor->connection->descriptor_count = 0;
     678             :                 } else {
     679           0 :                         if (descriptor->index + 1 == descriptor->connection->descriptor_count) {
     680             :                                 /* If the descriptor being freed is the end-most one
     681             :                                  * allocated, then the descriptor_count is reduced so
     682             :                                  * a future descriptor can reuse the hash table index.
     683             :                                  * This can prevent the hash index range increasing in
     684             :                                  * the common case that each descriptor is
     685             :                                  * allocated/used/freed before another descriptor is
     686             :                                  * needed.  However it is possible that a script frees
     687             :                                  * descriptors in arbitrary order which would prevent
     688             :                                  * descriptor_count ever being reduced to zero until
     689             :                                  * zend_hash_num_elements() returns 0.
     690             :                                  */
     691           0 :                                 descriptor->connection->descriptor_count--;
     692             :                         }
     693             :                 }
     694             :         }
     695             :         
     696             :         /* flushing Lobs & Files with buffering enabled */
     697           0 :         if ((descriptor->type == OCI_DTYPE_FILE || descriptor->type == OCI_DTYPE_LOB) && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED) {
     698           0 :                 php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE TSRMLS_CC);
     699             :         }
     700             : 
     701           0 :         if (descriptor->type == OCI_DTYPE_LOB) {
     702           0 :                 php_oci_temp_lob_close(descriptor TSRMLS_CC);
     703             :         }
     704             : 
     705           0 :         PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type));
     706             : 
     707           0 :         zend_list_delete(descriptor->connection->id);
     708           0 :         efree(descriptor);
     709             : }
     710             : /* }}} */
     711             : 
     712             : /* {{{ php_oci_lob_import()
     713             :  Import LOB contents from the given file */
     714           0 : int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename TSRMLS_DC)
     715             : {
     716             :         int fp;
     717             :         ub4 loblen;
     718           0 :         OCILobLocator *lob = (OCILobLocator *)descriptor->descriptor;
     719           0 :         php_oci_connection *connection = descriptor->connection;
     720             :         char buf[8192];
     721           0 :         ub4 offset = 1;
     722             :         sword errstatus;
     723             :         
     724             : #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
     725             :         /* Safe mode has been removed in PHP 5.4 */
     726           0 :         if (php_check_open_basedir(filename TSRMLS_CC)) {
     727             : #else
     728             :         if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC)) {
     729             : #endif
     730           0 :                 return 1;
     731             :         }
     732             :         
     733           0 :         if ((fp = VCWD_OPEN(filename, O_RDONLY|O_BINARY)) == -1) {
     734           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't open file %s", filename);
     735           0 :                 return 1;
     736             :         }
     737             : 
     738           0 :         while ((loblen = read(fp, &buf, sizeof(buf))) > 0) {     
     739           0 :                 PHP_OCI_CALL_RETURN(errstatus,
     740             :                                 OCILobWrite,
     741             :                                 (
     742             :                                         connection->svc,
     743             :                                         connection->err,
     744             :                                         lob,
     745             :                                         &loblen,
     746             :                                         offset,
     747             :                                         (dvoid *) &buf,
     748             :                                         loblen,
     749             :                                         OCI_ONE_PIECE,
     750             :                                         (dvoid *)0,
     751             :                                         (OCICallbackLobWrite) 0,
     752             :                                         (ub2) descriptor->charset_id,
     753             :                                         (ub1) descriptor->charset_form
     754             :                                 )
     755             :                 );
     756             : 
     757           0 :                 if (errstatus != OCI_SUCCESS) {
     758           0 :                         connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     759           0 :                         PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     760           0 :                         close(fp);
     761           0 :                         return 1;
     762             :                 } else {
     763           0 :                         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     764             :                 }
     765           0 :                 offset += loblen;
     766             :         }
     767           0 :         close(fp);
     768             :         
     769           0 :         return 0;
     770             : }
     771             :         /* }}} */
     772             : 
     773             : /* {{{ php_oci_lob_append()
     774             :  Append data to the end of the LOB */
     775           0 : int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from TSRMLS_DC)
     776             : {
     777           0 :         php_oci_connection *connection = descriptor_dest->connection;
     778           0 :         OCILobLocator *lob_dest = descriptor_dest->descriptor;
     779           0 :         OCILobLocator *lob_from = descriptor_from->descriptor;
     780             :         ub4 dest_len, from_len;
     781             :         sword errstatus;
     782             : 
     783           0 :         if (php_oci_lob_get_length(descriptor_dest, &dest_len TSRMLS_CC)) {
     784           0 :                 return 1;
     785             :         }
     786             :         
     787           0 :         if (php_oci_lob_get_length(descriptor_from, &from_len TSRMLS_CC)) {
     788           0 :                 return 1;
     789             :         }
     790             : 
     791           0 :         if (from_len <= 0) {
     792           0 :                 return 0;
     793             :         }
     794             : 
     795           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from));
     796             : 
     797           0 :         if (errstatus != OCI_SUCCESS) {
     798           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     799           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     800           0 :                 return 1;
     801             :         }
     802           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     803           0 :         return 0;
     804             : }
     805             : /* }}} */
     806             : 
     807             : /* {{{ php_oci_lob_truncate()
     808             :  Truncate LOB to the given length */
     809           0 : int php_oci_lob_truncate (php_oci_descriptor *descriptor, long new_lob_length TSRMLS_DC)
     810             : {
     811           0 :         php_oci_connection *connection = descriptor->connection;
     812           0 :         OCILobLocator *lob = descriptor->descriptor;
     813             :         ub4 lob_length;
     814             :         sword errstatus;
     815             :         
     816           0 :         if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
     817           0 :                 return 1;
     818             :         }
     819             :         
     820           0 :         if (lob_length <= 0) {
     821           0 :                 return 0;
     822             :         }
     823             : 
     824           0 :         if (new_lob_length < 0) {
     825           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size must be greater than or equal to 0");
     826           0 :                 return 1;
     827             :         }
     828             : 
     829           0 :         if (new_lob_length > lob_length) {
     830           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size must be less than or equal to the current LOB size");
     831           0 :                 return 1;
     832             :         }
     833             :         
     834           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobTrim, (connection->svc, connection->err, lob, new_lob_length));
     835             : 
     836           0 :         if (errstatus != OCI_SUCCESS) {
     837           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     838           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     839           0 :                 return 1;
     840             :         }
     841             :         
     842           0 :         descriptor->lob_size = new_lob_length;
     843           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     844             : 
     845           0 :         return 0;
     846             : }
     847             : /* }}} */
     848             : 
     849             : /* {{{ php_oci_lob_erase()
     850             :  Erase (or fill with whitespaces, depending on LOB type) the LOB (or its part) */
     851           0 : int php_oci_lob_erase (php_oci_descriptor *descriptor, long offset, ub4 length, ub4 *bytes_erased TSRMLS_DC)
     852             : {
     853           0 :         php_oci_connection *connection = descriptor->connection;
     854           0 :         OCILobLocator *lob = descriptor->descriptor;
     855             :         ub4 lob_length;
     856             :         sword errstatus;
     857             : 
     858           0 :         *bytes_erased = 0;
     859             :         
     860           0 :         if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) {
     861           0 :                 return 1;
     862             :         }
     863             :         
     864           0 :         if (offset == -1) {
     865           0 :                 offset = descriptor->lob_current_position;
     866             :         }
     867             : 
     868           0 :         if (length == -1) {
     869           0 :                 length = lob_length;
     870             :         }
     871             :         
     872           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobErase, (connection->svc, connection->err, lob, (ub4 *)&length, offset+1));
     873             : 
     874           0 :         if (errstatus != OCI_SUCCESS) {
     875           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     876           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     877           0 :                 return 1;
     878             :         }
     879             :         
     880           0 :         *bytes_erased = length;
     881           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     882           0 :         return 0;
     883             : }
     884             : /* }}} */
     885             : 
     886             : /* {{{ php_oci_lob_is_equal()
     887             :  Compare two LOB descriptors and figure out if they are pointing to the same LOB */
     888           0 : int php_oci_lob_is_equal (php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result TSRMLS_DC)
     889             : {
     890           0 :         php_oci_connection *connection = descriptor_first->connection;
     891           0 :         OCILobLocator *first_lob   = descriptor_first->descriptor;
     892           0 :         OCILobLocator *second_lob  = descriptor_second->descriptor;
     893             :         sword errstatus;
     894             : 
     895           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobIsEqual, (connection->env, first_lob, second_lob, result));
     896             : 
     897           0 :         if (errstatus) {
     898           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     899           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     900           0 :                 return 1;
     901             :         }
     902           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     903           0 :         return 0;
     904             : }
     905             : /* }}} */
     906             : 
     907             : /* {{{ php_oci_lob_write_tmp()
     908             :  Create temporary LOB and write data to it */
     909           0 : int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, long type, char *data, int data_len TSRMLS_DC)
     910             : {
     911           0 :         php_oci_connection *connection = descriptor->connection;
     912           0 :         OCILobLocator *lob                 = descriptor->descriptor;
     913           0 :         ub4 bytes_written = 0;
     914             :         sword errstatus;
     915             :         
     916           0 :         switch (type) {
     917             :                 case OCI_TEMP_BLOB:
     918             :                 case OCI_TEMP_CLOB:
     919             :                         /* only these two are allowed */
     920           0 :                         break;
     921             :                 default:
     922           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid temporary lob type: %ld", type);
     923           0 :                         return 1;
     924             :                         break;
     925             :         }
     926             : 
     927           0 :         if (data_len < 0) {
     928           0 :                 return 1;
     929             :         }
     930             : 
     931           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobCreateTemporary,
     932             :                         (
     933             :                          connection->svc,
     934             :                          connection->err,
     935             :                          lob,
     936             :                          OCI_DEFAULT,
     937             :                          OCI_DEFAULT,
     938             :                          (ub1)type,
     939             :                          OCI_ATTR_NOCACHE,
     940             :                          OCI_DURATION_SESSION
     941             :                         )
     942             :         );
     943             : 
     944           0 :         if (errstatus) {
     945           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     946           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     947           0 :                 return 1;
     948             :         }
     949             : 
     950           0 :         PHP_OCI_CALL_RETURN(errstatus, OCILobOpen, (connection->svc, connection->err, lob, OCI_LOB_READWRITE));
     951             : 
     952           0 :         if (errstatus) {
     953           0 :                 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
     954           0 :                 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
     955           0 :                 return 1;
     956             :         }
     957             : 
     958           0 :         descriptor->is_open = 1;
     959           0 :         connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
     960             : 
     961           0 :         return php_oci_lob_write(descriptor, 0, data, data_len, &bytes_written TSRMLS_CC);
     962             : }
     963             : /* }}} */
     964             : 
     965             : #endif /* HAVE_OCI8 */
     966             : 
     967             : /*
     968             :  * Local variables:
     969             :  * tab-width: 4
     970             :  * c-basic-offset: 4
     971             :  * End:
     972             :  * vim600: noet sw=4 ts=4 fdm=marker
     973             :  * vim<600: noet sw=4 ts=4
     974             :  */

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:51 +0000 (8 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.