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

LTP GCOV extension - code coverage report
Current view: directory - oci8 - oci8_lob.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 388
Code covered: 73.5 % Executed lines: 285
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:13 +0000 (5 days ago)

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