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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:04 +0000 (3 days ago)

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