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

LCOV - code coverage report
Current view: top level - ext/oci8 - oci8_lob.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 296 402 73.6 %
Date: 2014-11-15 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 15 Nov 2014 06:19:34 +0000 (8 days ago)

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