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 - spl - spl_directory.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 1189
Code covered: 82.1 % Executed lines: 976
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       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                 :    | Author: Marcus Boerger <helly@php.net>                               |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: spl_directory.c 286526 2009-07-29 17:31:25Z felipe $ */
      20                 : 
      21                 : #ifdef HAVE_CONFIG_H
      22                 : # include "config.h"
      23                 : #endif
      24                 : 
      25                 : #include "php.h"
      26                 : #include "php_ini.h"
      27                 : #include "ext/standard/info.h"
      28                 : #include "ext/standard/file.h"
      29                 : #include "ext/standard/php_string.h"
      30                 : #include "zend_compile.h"
      31                 : #include "zend_exceptions.h"
      32                 : #include "zend_interfaces.h"
      33                 : 
      34                 : #include "php_spl.h"
      35                 : #include "spl_functions.h"
      36                 : #include "spl_engine.h"
      37                 : #include "spl_iterators.h"
      38                 : #include "spl_directory.h"
      39                 : #include "spl_exceptions.h"
      40                 : 
      41                 : #include "php.h"
      42                 : #include "fopen_wrappers.h"
      43                 : 
      44                 : #include "ext/standard/basic_functions.h"
      45                 : #include "ext/standard/php_filestat.h"
      46                 : 
      47                 : #define SPL_HAS_FLAG(flags, test_flag) ((flags & test_flag) ? 1 : 0)
      48                 : 
      49                 : /* declare the class handlers */
      50                 : static zend_object_handlers spl_filesystem_object_handlers;
      51                 : 
      52                 : /* decalre the class entry */
      53                 : PHPAPI zend_class_entry *spl_ce_SplFileInfo;
      54                 : PHPAPI zend_class_entry *spl_ce_DirectoryIterator;
      55                 : PHPAPI zend_class_entry *spl_ce_FilesystemIterator;
      56                 : PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator;
      57                 : PHPAPI zend_class_entry *spl_ce_GlobIterator;
      58                 : PHPAPI zend_class_entry *spl_ce_SplFileObject;
      59                 : PHPAPI zend_class_entry *spl_ce_SplTempFileObject;
      60                 : 
      61                 : static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
      62             214 : {
      63             214 :         if (intern->u.file.current_line) {
      64              78 :                 efree(intern->u.file.current_line);
      65              78 :                 intern->u.file.current_line = NULL;
      66                 :         }
      67             214 :         if (intern->u.file.current_zval) {
      68              21 :                 zval_ptr_dtor(&intern->u.file.current_zval);
      69              21 :                 intern->u.file.current_zval = NULL;
      70                 :         }
      71             214 : } /* }}} */
      72                 : 
      73                 : static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */
      74            4960 : {
      75            4960 :         spl_filesystem_object *intern = (spl_filesystem_object*)object;
      76                 : 
      77            4960 :         if (intern->oth_handler && intern->oth_handler->dtor) {
      78             429 :                 intern->oth_handler->dtor(intern TSRMLS_CC);
      79                 :         }
      80                 :         
      81            4960 :         zend_object_std_dtor(&intern->std TSRMLS_CC);
      82                 :         
      83            4960 :         if (intern->_path.v) {
      84            4892 :                 efree(intern->_path.v);
      85                 :         }
      86            4960 :         if (intern->file_name.v) {
      87            4359 :                 efree(intern->file_name.v);
      88                 :         }
      89            4960 :         switch(intern->type) {
      90                 :         case SPL_FS_INFO:
      91            4365 :                 break;
      92                 :         case SPL_FS_DIR:
      93             548 :                 if (intern->u.dir.dirp) {
      94             545 :                         php_stream_close(intern->u.dir.dirp);
      95             545 :                         intern->u.dir.dirp = NULL;
      96                 :                 }
      97             548 :                 if (intern->u.dir.sub_path.v) {
      98             120 :                         efree(intern->u.dir.sub_path.v);
      99                 :                 }               
     100             548 :                 break;
     101                 :         case SPL_FS_FILE:
     102              47 :                 if (intern->u.file.stream) {
     103              47 :                         if (intern->u.file.zcontext) {
     104                 : /*                              zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
     105                 :                         }
     106              47 :                         if (!intern->u.file.stream->is_persistent) {
     107              47 :                                 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
     108                 :                         } else {
     109               0 :                                 php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
     110                 :                         }
     111              47 :                         if (intern->u.file.open_mode) {
     112              47 :                                 efree(intern->u.file.open_mode);
     113                 :                         }
     114              47 :                         if (intern->orig_path) {
     115              47 :                                 efree(intern->orig_path);
     116                 :                         }
     117                 :                 }
     118              47 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
     119                 :                 break;
     120                 :         }
     121            4960 :         efree(object);
     122            4960 : } /* }}} */
     123                 : 
     124                 : /* {{{ spl_ce_dir_object_new */
     125                 : /* creates the object by 
     126                 :    - allocating memory 
     127                 :    - initializing the object members
     128                 :    - storing the object
     129                 :    - setting it's handlers
     130                 : 
     131                 :    called from 
     132                 :    - clone
     133                 :    - new
     134                 :  */
     135                 : static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_type, spl_filesystem_object **obj TSRMLS_DC)
     136            4960 : {
     137                 :         zend_object_value retval;
     138                 :         spl_filesystem_object *intern;
     139                 :         zval *tmp;
     140                 : 
     141            4960 :         intern = emalloc(sizeof(spl_filesystem_object));
     142            4960 :         memset(intern, 0, sizeof(spl_filesystem_object));
     143                 :         /* intern->type = SPL_FS_INFO; done by set 0 */
     144            4960 :         intern->file_class = spl_ce_SplFileObject;
     145            4960 :         intern->info_class = spl_ce_SplFileInfo;
     146            4960 :         if (obj) *obj = intern;
     147                 : 
     148            4960 :         zend_object_std_init(&intern->std, class_type TSRMLS_CC);
     149            4960 :         zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     150                 : 
     151            4960 :         retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC);
     152            4960 :         retval.handlers = &spl_filesystem_object_handlers;
     153            4960 :         return retval;
     154                 : }
     155                 : /* }}} */
     156                 : 
     157                 : /* {{{ spl_filesystem_object_new */
     158                 : /* See spl_filesystem_object_new_ex */
     159                 : static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type TSRMLS_DC)
     160             987 : {
     161             987 :         return spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC);
     162                 : }
     163                 : /* }}} */
     164                 : 
     165                 : PHPAPI zstr spl_filesystem_object_get_path(spl_filesystem_object *intern, int *len, zend_uchar *type TSRMLS_DC) /* {{{ */
     166            8857 : {
     167            8857 :         if (intern->type == SPL_FS_DIR) {
     168            8784 :                 if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
     169                 :                         zstr ret;
     170               9 :                         if (type) {
     171               9 :                                 *type = IS_STRING;
     172                 :                         }
     173               9 :                         ret.s = php_glob_stream_get_path(intern->u.dir.dirp, 0, len);
     174               9 :                         return ret;
     175                 :                 }
     176                 :         }
     177            8848 :         if (len) {
     178            3946 :                 *len = intern->_path_len;
     179                 :         }
     180            8848 :         if (type) {
     181            8767 :                 *type = intern->_path_type;
     182                 :         }
     183            8848 :         return intern->_path;
     184                 : } /* }}} */
     185                 : 
     186                 : static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
     187           15189 : {
     188                 :         zstr path;
     189                 :         zend_uchar path_type;
     190           15189 :         char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
     191                 : 
     192           15189 :         if (!intern->file_name.v) {
     193            4824 :                 switch (intern->type) {
     194                 :                 case SPL_FS_INFO:
     195                 :                 case SPL_FS_FILE:
     196               0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized");
     197               0 :                         break;
     198                 :                 case SPL_FS_DIR:
     199            4824 :                         path = spl_filesystem_object_get_path(intern, NULL, &path_type TSRMLS_CC);
     200            4824 :                         intern->file_name_len = zspprintf(path_type, &intern->file_name, 0, "%R%c%s",
     201                 :                                                           path_type, path,
     202                 :                                                           slash, intern->u.dir.entry.d_name);
     203            4824 :                         intern->file_name_type = path_type;
     204                 :                         break;
     205                 :                 }
     206                 :         }
     207           15189 : } /* }}} */
     208                 : 
     209                 : static int spl_filesystem_dir_read(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
     210            9370 : {
     211            9370 :         if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
     212             332 :                 intern->u.dir.entry.d_name[0] = '\0';
     213             332 :                 return 0;
     214                 :         } else {
     215            9038 :                 return 1;
     216                 :         }
     217                 : }
     218                 : /* }}} */
     219                 : 
     220                 : #define IS_SLASH_AT(type, zs, pos) (type == IS_UNICODE ? IS_U_SLASH(zs.u[pos]) : IS_SLASH(zs.s[pos]))
     221                 : 
     222                 : static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */
     223            4920 : {
     224            4920 :         return !strcmp(d_name, ".") || !strcmp(d_name, "..");
     225                 : }
     226                 : /* }}} */
     227                 : 
     228                 : /* {{{ spl_filesystem_dir_open */
     229                 : /* open a directory resource */
     230                 : static void spl_filesystem_dir_open(spl_filesystem_object* intern, zend_uchar type, zstr path, int path_len TSRMLS_DC)
     231             548 : {
     232             548 :         int options = REPORT_ERRORS;
     233             548 :         int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);
     234                 : 
     235                 : #if HELLY_0     
     236                 :         if (php_stream_is(intern->u.dir.dirp, &php_glob_stream_ops)) {
     237                 :                 options |= STREAM_USE_GLOB_DIR_OPEN;
     238                 :         }
     239                 : #endif
     240                 : 
     241             548 :         intern->type = SPL_FS_DIR;
     242             548 :         intern->_path_type= type;
     243             548 :         intern->_path_len = path_len;
     244             548 :         intern->u.dir.dirp = php_stream_u_opendir(type, path, path_len, options, NULL);
     245                 : 
     246             936 :         if (intern->_path_len > 1 && IS_SLASH_AT(type, path, intern->_path_len-1)) {
     247             388 :                 intern->_path = ezstrndup(type, path, --intern->_path_len);
     248                 :         } else {
     249             160 :                 intern->_path = ezstrndup(type, path, intern->_path_len);
     250                 :         }
     251             548 :         intern->u.dir.index = 0;
     252                 : 
     253             551 :         if (EG(exception) || intern->u.dir.dirp == NULL) {
     254                 :                 /* throw exception: should've been already happened */
     255               3 :                 intern->u.dir.entry.d_name[0] = '\0';
     256                 :         } else {
     257                 :                 do {
     258             561 :                         spl_filesystem_dir_read(intern TSRMLS_CC);
     259             561 :                 } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
     260                 :         }
     261             548 : }
     262                 : /* }}} */
     263                 : 
     264                 : static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */
     265              47 : {
     266              47 :         intern->type = SPL_FS_FILE;
     267              47 :         intern->u.file.context = php_stream_context_from_zval(intern->u.file.zcontext, 0);
     268              47 :         intern->u.file.stream = php_stream_u_open_wrapper(intern->file_name_type, intern->file_name, intern->file_name_len, intern->u.file.open_mode, (use_include_path ? USE_PATH : 0) | REPORT_ERRORS, NULL, intern->u.file.context);
     269                 : 
     270              47 :         if (!intern->file_name_len || !intern->u.file.stream) {
     271               0 :                 if (!EG(exception)) {
     272               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot open file '%R'", intern->file_name_type, intern->file_name_len ? intern->file_name : EMPTY_ZSTR);
     273                 :                 }
     274               0 :                 intern->file_name = NULL_ZSTR; /* until here it is not a copy */
     275               0 :                 intern->u.file.open_mode = NULL;
     276               0 :                 return FAILURE;
     277                 :         }
     278                 : 
     279              47 :         if (intern->u.file.zcontext) {
     280               0 :                 zend_list_addref(Z_RESVAL_P(intern->u.file.zcontext));
     281                 :         }
     282                 : 
     283              47 :         if (intern->file_name_len > 1 && IS_SLASH_AT(intern->file_name_type, intern->file_name, intern->file_name_len-1)) {
     284               1 :                 intern->file_name_len--;
     285                 :         }
     286                 : 
     287                 :         /* NOTE: Works as long as stream->orig_path is not unicode aware, might
     288                 :          * break later. */
     289              47 :         intern->orig_path = estrndup(intern->u.file.stream->orig_path, strlen(intern->u.file.stream->orig_path));
     290                 : 
     291              47 :         intern->file_name = ezstrndup(intern->file_name_type, intern->file_name, intern->file_name_len);
     292              47 :         intern->u.file.open_mode = estrndup(intern->u.file.open_mode, intern->u.file.open_mode_len);
     293                 : 
     294                 :         /* avoid reference counting in debug mode, thus do it manually */
     295              47 :         ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream));
     296              47 :         Z_SET_REFCOUNT(intern->u.file.zresource, 1);
     297                 :         
     298              47 :         intern->u.file.delimiter = ',';
     299              47 :         intern->u.file.enclosure = '"';
     300                 : 
     301              47 :         zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr);
     302                 : 
     303              47 :         return SUCCESS;
     304                 : } /* }}} */
     305                 : 
     306                 : /* {{{ spl_filesystem_object_clone */
     307                 : /* Local zend_object_value creation (on stack)
     308                 :    Load the 'other' object 
     309                 :    Create a new empty object (See spl_filesystem_object_new_ex)
     310                 :    Open the directory
     311                 :    Clone other members (properties)
     312                 :  */
     313                 : static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC)
     314               7 : {
     315                 :         zend_object_value new_obj_val;
     316                 :         zend_object *old_object;
     317                 :         zend_object *new_object;
     318               7 :         zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
     319                 :         spl_filesystem_object *intern;
     320                 :         spl_filesystem_object *source;
     321                 :         int index;
     322                 :         int skip_dots;
     323                 : 
     324               7 :         old_object = zend_objects_get_address(zobject TSRMLS_CC);
     325               7 :         source = (spl_filesystem_object*)old_object;
     326                 : 
     327               7 :         skip_dots = SPL_HAS_FLAG(source->flags, SPL_FILE_DIR_SKIPDOTS);
     328                 : 
     329               7 :         new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern TSRMLS_CC);
     330               7 :         new_object = &intern->std;
     331                 : 
     332               7 :         intern->flags = source->flags;
     333                 : 
     334               7 :         switch (source->type) {
     335                 :         case SPL_FS_INFO:
     336               3 :                 intern->_path_type = source->_path_type;
     337               3 :                 intern->_path_len = source->_path_len;
     338               3 :                 intern->_path = ezstrndup(source->_path_type, source->_path, source->_path_len);
     339               3 :                 intern->file_name_type = source->file_name_type;
     340               3 :                 intern->file_name_len = source->file_name_len;
     341               3 :                 intern->file_name = ezstrndup(source->file_name_type, source->file_name, intern->file_name_len);
     342               3 :                 break;
     343                 :         case SPL_FS_DIR:
     344               4 :                 spl_filesystem_dir_open(intern, source->_path_type, source->_path, source->_path_len TSRMLS_CC);
     345                 :                 /* read until we hit the position in which we were before */
     346              10 :                 for(index = 0; index < source->u.dir.index; ++index) {
     347                 :                         do {
     348               6 :                                 spl_filesystem_dir_read(intern TSRMLS_CC);
     349               6 :                         } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
     350                 :                 }
     351               4 :                 intern->u.dir.index = index;
     352               4 :                 break;
     353                 :         case SPL_FS_FILE:
     354               0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %v cannot be cloned", old_object->ce->name);
     355                 :                 break;
     356                 :         }
     357                 :         
     358               7 :         intern->file_class = source->file_class;
     359               7 :         intern->info_class = source->info_class;
     360               7 :         intern->oth = source->oth;
     361               7 :         intern->oth_handler = source->oth_handler;
     362                 : 
     363               7 :         zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
     364                 : 
     365               7 :         if (intern->oth_handler && intern->oth_handler->clone) {
     366               0 :                 intern->oth_handler->clone(source, intern TSRMLS_CC);
     367                 :         }
     368                 : 
     369               7 :         return new_obj_val;
     370                 : }
     371                 : /* }}} */
     372                 : 
     373                 : void spl_filesystem_info_set_filename(spl_filesystem_object *intern, zend_uchar type, zstr path, int len, int use_copy TSRMLS_DC) /* {{{ */
     374             413 : {
     375                 :         zstr p1, p2;
     376                 : 
     377             413 :         intern->file_name_type = type;
     378             413 :         intern->file_name = use_copy ? ezstrndup(type, path, len) : path;
     379             413 :         intern->file_name_len = len;
     380                 : 
     381                 :         while (1) {
     382             417 :                 if (type == IS_UNICODE) {
     383              20 :                         p1.u = u_strrchr(intern->file_name.u, '/');
     384                 :                 } else {
     385             397 :                         p1.s = strrchr(intern->file_name.s, '/');
     386                 :                 }
     387                 : #if defined(PHP_WIN32) || defined(NETWARE)
     388                 :                 if (type == IS_UNICODE) {
     389                 :                         p2.u = u_strrchr(intern->file_name.u, '\\');
     390                 :                 } else {
     391                 :                         p2.s = strrchr(intern->file_name.s, '\\');
     392                 :                 }
     393                 : #else
     394             417 :                 p2.v = 0;
     395                 : #endif
     396             820 :                 if (p1.v || p2.v) {
     397                 :                         zstr slash_pos;
     398                 :                         
     399             407 :                         if (type == IS_UNICODE) {
     400              10 :                                 slash_pos.u = (p1.u > p2.u ? p1.u : p2.u);
     401              10 :                                 if (IS_SLASH_AT(type, intern->file_name, intern->file_name_len-1) && intern->file_name_len > 1) {
     402               1 :                                         intern->file_name_len = slash_pos.u - intern->file_name.u;
     403               1 :                                         intern->file_name.u[intern->file_name_len] = 0;
     404               1 :                                         continue;
     405                 :                                 }
     406               9 :                                 intern->_path_len = slash_pos.u - intern->file_name.u;
     407                 :                         } else {
     408             397 :                                 slash_pos.s = (p1.s > p2.s ? p1.s : p2.s);
     409             397 :                                 if (IS_SLASH_AT(type, intern->file_name, intern->file_name_len-1) && intern->file_name_len > 1) {
     410               3 :                                         intern->file_name_len = slash_pos.s - intern->file_name.s;
     411               3 :                                         intern->file_name.s[intern->file_name_len] = 0;
     412               3 :                                         continue;
     413                 :                                 }
     414             394 :                                 intern->_path_len = slash_pos.s - intern->file_name.s;
     415                 :                         }
     416                 :                 } else {
     417              10 :                         intern->_path_len = 0;
     418                 :                 }
     419                 :                 break;
     420               4 :         }
     421                 : 
     422             413 :         intern->_path_type = type;
     423             413 :         intern->_path = ezstrndup(type, path, intern->_path_len);
     424             413 : } /* }}} */
     425                 : 
     426                 : static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_object *source, zend_uchar file_type, zstr file_path, int file_path_len, int use_copy, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
     427               5 : {
     428                 :         spl_filesystem_object *intern;
     429                 :         zval *arg1;
     430                 :         zend_error_handling error_handling;
     431                 : 
     432               5 :         if (!file_path.v || !file_path_len) {
     433                 : #if defined(PHP_WIN32)
     434                 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot create SplFileInfo for empty path");
     435                 :                 if (file_path.v && !use_copy) {
     436                 :                         efree(file_path.v);
     437                 :                 }
     438                 : #else
     439               0 :                 if (file_path.v && !use_copy) {
     440               0 :                         efree(file_path.v);
     441                 :                 }
     442               0 :                 use_copy = 1;
     443               0 :                 file_path_len = 1;
     444               0 :                 file_path.s = "/";
     445               0 :                 file_type = IS_STRING;
     446                 : #endif
     447               0 :                 return NULL;
     448                 :         }
     449                 : 
     450               5 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
     451                 : 
     452               5 :         ce = ce ? ce : source->info_class;
     453               5 :         return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     454               5 :         Z_TYPE_P(return_value) = IS_OBJECT;
     455                 : 
     456               5 :         if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
     457               0 :                 MAKE_STD_ZVAL(arg1);
     458               0 :                 ZVAL_ZSTRL(arg1, file_type, file_path, file_path_len, use_copy);
     459               0 :                 zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
     460               0 :                 zval_ptr_dtor(&arg1);
     461                 :         } else {
     462               5 :                 spl_filesystem_info_set_filename(intern, file_type, file_path, file_path_len, use_copy TSRMLS_CC);
     463                 :         }
     464                 :         
     465               5 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
     466               5 :         return intern;
     467                 : } /* }}} */
     468                 : 
     469                 : static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_filesystem_object *source, int type, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
     470            3961 : {
     471                 :         spl_filesystem_object *intern;
     472            3961 :         zend_bool use_include_path = 0;
     473                 :         zval *arg1, *arg2;
     474                 :         zend_error_handling error_handling;
     475                 : 
     476            3961 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
     477                 : 
     478            3961 :         switch (source->type) {
     479                 :         case SPL_FS_INFO:
     480                 :         case SPL_FS_FILE:
     481               9 :                 break;
     482                 :         case SPL_FS_DIR:
     483            3952 :                 if (!source->u.dir.entry.d_name[0]) {
     484               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Could not open file");
     485               0 :                         zend_restore_error_handling(&error_handling TSRMLS_CC);
     486               0 :                         return NULL;
     487                 :                 }
     488                 :         }
     489                 : 
     490            3961 :         switch (type) {
     491                 :         case SPL_FS_INFO:
     492            3954 :                 ce = ce ? ce : source->info_class;
     493            3954 :                 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     494            3954 :                 Z_TYPE_P(return_value) = IS_OBJECT;
     495                 : 
     496            3954 :                 spl_filesystem_object_get_file_name(source TSRMLS_CC);
     497            3954 :                 if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
     498              74 :                         MAKE_STD_ZVAL(arg1);
     499              74 :                         ZVAL_ZSTRL(arg1, source->file_name_type, source->file_name, source->file_name_len, 1);
     500              74 :                         zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
     501              74 :                         zval_ptr_dtor(&arg1);
     502                 :                 } else {
     503            3880 :                         intern->_path = spl_filesystem_object_get_path(source, &intern->_path_len, &intern->_path_type TSRMLS_CC);
     504            3880 :                         intern->_path = ezstrndup(intern->_path_type, intern->_path, intern->_path_len);
     505            3880 :                         intern->file_name_type = source->file_name_type;
     506            3880 :                         intern->file_name_len = source->file_name_len;
     507            3880 :                         intern->file_name = ezstrndup(source->file_name_type, source->file_name, source->file_name_len);
     508                 :                 }
     509            3954 :                 break;
     510                 :         case SPL_FS_FILE:
     511               7 :                 ce = ce ? ce : source->file_class;
     512               7 :                 return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
     513               7 :                 Z_TYPE_P(return_value) = IS_OBJECT;
     514                 :         
     515               7 :                 spl_filesystem_object_get_file_name(source TSRMLS_CC);
     516                 : 
     517               7 :                 if (ce->constructor->common.scope != spl_ce_SplFileObject) {
     518               0 :                         MAKE_STD_ZVAL(arg1);
     519               0 :                         MAKE_STD_ZVAL(arg2);
     520               0 :                         ZVAL_ZSTRL(arg1, source->file_name_type, source->file_name, source->file_name_len, 1);
     521               0 :                         ZVAL_STRINGL(arg2, "r", 1, 1);
     522               0 :                         zend_call_method_with_2_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1, arg2);
     523               0 :                         zval_ptr_dtor(&arg1);
     524               0 :                         zval_ptr_dtor(&arg2);
     525                 :                 } else {
     526               7 :                         intern->_path = spl_filesystem_object_get_path(source, &intern->_path_len, &intern->_path_type TSRMLS_CC);
     527               7 :                         intern->_path = ezstrndup(intern->_path_type, intern->_path, intern->_path_len);
     528               7 :                         intern->file_name_type = source->file_name_type;
     529               7 :                         intern->file_name_len = source->file_name_len;
     530               7 :                         intern->file_name = source->file_name;
     531                 :                 
     532               7 :                         intern->u.file.open_mode = "r";
     533               7 :                         intern->u.file.open_mode_len = 1;
     534                 :                 
     535               7 :                         if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr", 
     536                 :                                         &intern->u.file.open_mode, &intern->u.file.open_mode_len, 
     537                 :                                         &use_include_path, &intern->u.file.zcontext) == FAILURE) {
     538               1 :                                 zend_restore_error_handling(&error_handling TSRMLS_CC);
     539               1 :                                 intern->u.file.open_mode = NULL;
     540               1 :                                 intern->file_name.v = NULL;
     541               1 :                                 zval_dtor(return_value);
     542               1 :                                 Z_TYPE_P(return_value) = IS_NULL;
     543               1 :                                 return NULL;
     544                 :                         }
     545                 :                 
     546               6 :                         if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == FAILURE) {
     547               0 :                                 zend_restore_error_handling(&error_handling TSRMLS_CC);
     548               0 :                                 zval_dtor(return_value);
     549               0 :                                 Z_TYPE_P(return_value) = IS_NULL;
     550               0 :                                 return NULL;
     551                 :                         }
     552                 :                 }
     553               6 :                 break;
     554                 :         case SPL_FS_DIR:        
     555               0 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
     556               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Operation not supported");
     557               0 :                 return NULL;
     558                 :         }
     559            3960 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
     560            3960 :         return NULL;
     561                 : } /* }}} */
     562                 : 
     563                 : static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */
     564            3247 : {
     565            3247 :         return d_name[0] == '\0' || spl_filesystem_is_dot(d_name);
     566                 : }
     567                 : /* }}} */
     568                 : 
     569             118 : static zstr spl_filesystem_object_get_pathname(spl_filesystem_object *intern, int *len, zend_uchar *type  TSRMLS_DC) { /* {{{ */
     570             118 :         switch (intern->type) {
     571                 :         case SPL_FS_INFO:
     572                 :         case SPL_FS_FILE:
     573             112 :                 *len = intern->file_name_len;
     574             112 :                 *type = intern->file_name_type;
     575             112 :                 return intern->file_name;
     576                 :         case SPL_FS_DIR:
     577               6 :                 if (intern->u.dir.entry.d_name[0]) {
     578               6 :                         spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     579               6 :                         *len = intern->file_name_len;
     580               6 :                         *type = intern->file_name_type;
     581               6 :                         return intern->file_name;
     582                 :                 }
     583                 :         }
     584               0 :         *len  = 0;
     585               0 :         *type = IS_STRING;
     586               0 :         return intern->file_name; /* dummy */
     587                 : }
     588                 : /* }}} */
     589                 : 
     590                 : static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */
     591              15 : {
     592              15 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(obj TSRMLS_CC);
     593                 :         HashTable *rv;
     594                 :         zval *tmp, zrv;
     595                 :         zstr pnstr;
     596                 :         int  pnlen;
     597                 :         char stmp[2];
     598                 :         int path_len;
     599                 :         zstr path;
     600                 :         zend_uchar path_type;
     601                 : 
     602              15 :         *is_temp = 1;
     603                 : 
     604              15 :         ALLOC_HASHTABLE(rv);
     605              15 :         ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 3, 0);
     606                 : 
     607              15 :         INIT_PZVAL(&zrv);
     608              15 :         Z_ARRVAL(zrv) = rv;
     609                 : 
     610              15 :         zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     611                 : 
     612              15 :         path = spl_filesystem_object_get_pathname(intern, &path_len, &path_type TSRMLS_CC);
     613              15 :         pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "pathName", sizeof("pathName")-1, &pnlen TSRMLS_CC);
     614              15 :         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, path_type, path, path_len, 1);
     615              15 :         efree(pnstr.v);
     616              15 :         if (intern->file_name.v) {
     617              15 :                 pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1, &pnlen TSRMLS_CC);
     618              15 :                 path = spl_filesystem_object_get_path(intern, &path_len, &path_type TSRMLS_CC);
     619              30 :                 if (path_len && path_len < intern->file_name_len) {
     620              15 :                         if (intern->file_name_type == IS_UNICODE) {
     621               8 :                                 path.u = intern->file_name.u + path_len + 1;
     622                 :                         } else {
     623               7 :                                 path.s = intern->file_name.s + path_len + 1;
     624                 :                         }
     625              15 :                         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->file_name_type, path, intern->file_name_len - (path_len + 1), 1);
     626                 :                 } else {
     627               0 :                         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->file_name_type, intern->file_name, intern->file_name_len, 1);
     628                 :                 }
     629              15 :                 efree(pnstr.v);
     630                 :         }
     631              15 :         if (intern->type == SPL_FS_DIR) {
     632               1 :                 pnstr = spl_gen_private_prop_name(spl_ce_DirectoryIterator, "glob", sizeof("glob")-1, &pnlen TSRMLS_CC);
     633               1 :                 if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
     634               0 :                         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->_path_type, intern->_path, intern->_path_len, 1);
     635                 :                 } else {
     636               1 :                         add_u_assoc_bool_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, 0);
     637                 :                 }
     638               1 :                 efree(pnstr.v);
     639               1 :                 pnstr = spl_gen_private_prop_name(spl_ce_RecursiveDirectoryIterator, "subPathName", sizeof("subPathName")-1, &pnlen TSRMLS_CC);
     640               1 :                 if (intern->u.dir.sub_path.v) {
     641               0 :                         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->u.dir.sub_path_type, intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
     642                 :                 } else {
     643               1 :                         add_u_assoc_zstrl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, IS_UNICODE, EMPTY_ZSTR, 0, 1);
     644                 :                 }
     645               1 :                 efree(pnstr.v);
     646                 :         }
     647              15 :         if (intern->type == SPL_FS_FILE) {
     648               0 :                 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "openMode", sizeof("openMode")-1, &pnlen TSRMLS_CC);
     649               0 :                 add_u_assoc_stringl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, intern->u.file.open_mode, intern->u.file.open_mode_len, 1);
     650               0 :                 efree(pnstr.v);
     651               0 :                 stmp[1] = '\0';
     652               0 :                 stmp[0] = intern->u.file.delimiter;
     653               0 :                 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "delimiter", sizeof("delimiter")-1, &pnlen TSRMLS_CC);
     654               0 :                 add_u_assoc_stringl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, stmp, 1, 1);
     655               0 :                 efree(pnstr.v);
     656               0 :                 stmp[0] = intern->u.file.enclosure;
     657               0 :                 pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "enclosure", sizeof("enclosure")-1, &pnlen TSRMLS_CC);
     658               0 :                 add_u_assoc_stringl_ex(&zrv, IS_UNICODE, pnstr, pnlen+1, stmp, 1, 1);
     659               0 :                 efree(pnstr.v);
     660                 :         }
     661                 : 
     662              15 :         return rv;
     663                 : }
     664                 : /* }}}} */
     665                 : 
     666                 : #define DIT_CTOR_FLAGS  0x00000001
     667                 : #define DIT_CTOR_GLOB   0x00000002
     668                 : 
     669                 : UChar u_glob[sizeof("glob://")];
     670                 : 
     671                 : void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, long ctor_flags) /* {{{ */
     672             545 : {
     673                 :         spl_filesystem_object *intern;
     674                 :         zstr path;
     675                 :         int parsed, len;
     676                 :         zend_uchar path_type;
     677                 :         long flags;
     678                 :         zend_error_handling error_handling;
     679                 :         
     680             545 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
     681                 : 
     682             545 :         if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_FLAGS)) {
     683             527 :                 flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO;
     684             527 :                 parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|l", &path, &len, &path_type, &flags);
     685                 :         } else {
     686              18 :                 flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
     687              18 :                 parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &path, &len, &path_type);
     688                 :         }
     689                 : 
     690             545 :         if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) {
     691               3 :                 flags |= SPL_FILE_DIR_SKIPDOTS;
     692                 :         }
     693                 : 
     694             545 :         if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_UNIXPATHS)) {
     695               0 :                 flags |= SPL_FILE_DIR_UNIXPATHS;
     696                 :         }
     697                 : 
     698             545 :         if (parsed == FAILURE) {
     699               0 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
     700               0 :                 return;
     701                 :         }
     702             545 :         if (!len) {
     703               1 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Directory name must not be empty.");
     704               1 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
     705               1 :                 return;
     706                 :         }
     707                 : 
     708             544 :         intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     709             544 :         intern->flags = flags;
     710                 : 
     711             544 :         if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_GLOB) && (
     712                 :                 (path_type == IS_STRING && strstr(path.s, "glob://") != path.s) ||
     713                 :                 (path_type == IS_UNICODE && u_strstr(path.u, u_glob) != path.u)
     714                 :         )) {
     715               0 :                 len = zspprintf(path_type, &path, 0, "glob://%R", path_type, path);
     716               0 :                 spl_filesystem_dir_open(intern, path_type, path, len TSRMLS_CC);
     717               0 :                 efree(path.v);
     718                 :         } else {
     719             544 :                 spl_filesystem_dir_open(intern, path_type, path, len TSRMLS_CC);
     720                 :         }
     721                 : 
     722             544 :         intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
     723             544 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
     724                 : }
     725                 : /* }}} */
     726                 : 
     727                 : /* {{{ proto void DirectoryIterator::__construct(string path) U
     728                 :  Cronstructs a new dir iterator from a path. */
     729                 : SPL_METHOD(DirectoryIterator, __construct)
     730              18 : {
     731              18 :         spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     732              18 : }
     733                 : /* }}} */
     734                 : 
     735                 : /* {{{ proto void DirectoryIterator::rewind() U
     736                 :    Rewind dir back to the start */
     737                 : SPL_METHOD(DirectoryIterator, rewind)
     738               3 : {
     739               3 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     740                 : 
     741               3 :         intern->u.dir.index = 0;
     742               3 :         if (intern->u.dir.dirp) {
     743               3 :                 php_stream_rewinddir(intern->u.dir.dirp);
     744                 :         }
     745               3 :         spl_filesystem_dir_read(intern TSRMLS_CC);
     746               3 : }
     747                 : /* }}} */
     748                 : 
     749                 : /* {{{ proto string DirectoryIterator::key() U
     750                 :    Return current dir entry */
     751                 : SPL_METHOD(DirectoryIterator, key)
     752               8 : {
     753               8 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     754                 : 
     755               8 :         if (intern->u.dir.dirp) {
     756               8 :                 RETURN_LONG(intern->u.dir.index);
     757                 :         } else {
     758               0 :                 RETURN_FALSE;
     759                 :         }
     760                 : }
     761                 : /* }}} */
     762                 : 
     763                 : /* {{{ proto DirectoryIterator DirectoryIterator::current() U
     764                 :    Return this (needed for Iterator interface) */
     765                 : SPL_METHOD(DirectoryIterator, current)
     766               5 : {
     767               5 :         RETURN_ZVAL(getThis(), 1, 0);
     768                 : }
     769                 : /* }}} */
     770                 : 
     771                 : /* {{{ proto void DirectoryIterator::next() U
     772                 :    Move to next entry */
     773                 : SPL_METHOD(DirectoryIterator, next)
     774            5648 : {
     775            5648 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     776            5648 :         int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS);
     777                 : 
     778            5648 :         intern->u.dir.index++;
     779                 :         do {
     780            5670 :                 spl_filesystem_dir_read(intern TSRMLS_CC);
     781            5670 :         } while (skip_dots && spl_filesystem_is_dot(intern->u.dir.entry.d_name));
     782            5648 :         if (intern->file_name.v) {
     783            3275 :                 efree(intern->file_name.v);
     784            3275 :                 intern->file_name = NULL_ZSTR;
     785                 :         }
     786            5648 : }
     787                 : /* }}} */
     788                 : 
     789                 : /* {{{ proto void DirectoryIterator::seek(int position)
     790                 :    Seek to the given position */
     791                 : SPL_METHOD(DirectoryIterator, seek)
     792               3 : {
     793               3 :         spl_filesystem_object *intern    = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     794               3 :         zval                  *retval    = NULL;
     795                 :         long                   pos;
     796                 : 
     797               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &pos) == FAILURE) {
     798               0 :                 return;
     799                 :         }
     800                 : 
     801               3 :         if (intern->u.dir.index > pos) {
     802                 :                 /* we first rewind */
     803               1 :                 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval);
     804               1 :                 if (retval) {
     805               1 :                         zval_ptr_dtor(&retval);
     806                 :                 }
     807                 :         }
     808                 : 
     809               8 :         while (intern->u.dir.index < pos) {
     810               3 :                 int valid = 0;
     811               3 :                 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_valid, "valid", &retval);
     812               3 :                 if (retval) {
     813               3 :                         valid = zend_is_true(retval);
     814               3 :                         zval_ptr_dtor(&retval);
     815                 :                 }
     816               3 :                 if (!valid) {
     817               1 :                         break;
     818                 :                 }
     819               2 :                 zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_next, "next", &retval);
     820               2 :                 if (retval) {
     821               2 :                         zval_ptr_dtor(&retval);
     822                 :                 }
     823                 :         }
     824                 : } /* }}} */
     825                 : 
     826                 : 
     827                 : /* {{{ proto string DirectoryIterator::valid() U
     828                 :    Check whether dir contains more entries */
     829                 : SPL_METHOD(DirectoryIterator, valid)
     830            8944 : {
     831            8944 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     832                 : 
     833            8944 :         RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0');
     834                 : }
     835                 : /* }}} */
     836                 : 
     837                 : /* {{{ proto string SplFileInfo::getPath() U
     838                 :    Return the path */
     839                 : SPL_METHOD(SplFileInfo, getPath)
     840              11 : {
     841              11 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     842                 :         int path_len;
     843                 :         zend_uchar path_type;
     844              11 :         zstr path = spl_filesystem_object_get_path(intern, &path_len, &path_type TSRMLS_CC);
     845                 : 
     846              11 :         RETURN_ZSTRL(path_type, path, path_len, ZSTR_DUPLICATE);
     847                 : }
     848                 : /* }}} */
     849                 : 
     850                 : /* {{{ proto string SplFileInfo::getFilename() U
     851                 :    Return filename only */
     852                 : SPL_METHOD(SplFileInfo, getFilename)
     853              38 : {
     854              38 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     855                 :         zstr ret, path;
     856                 :         zend_uchar path_type;
     857                 :         int path_len;
     858                 : 
     859              38 :     path = spl_filesystem_object_get_path(intern, &path_len, &path_type TSRMLS_CC);
     860              38 :         if (path_len && path_len < intern->file_name_len) {
     861              37 :                 if (intern->file_name_type == IS_UNICODE) {
     862              19 :                         ret.u = intern->file_name.u + path_len + 1;
     863                 :                 } else {
     864              18 :                         ret.s = intern->file_name.s + path_len + 1;
     865                 :                 }
     866              37 :                 RETURN_ZSTRL(intern->file_name_type, ret, intern->file_name_len - (path_len + 1), ZSTR_DUPLICATE);
     867                 :         } else {
     868               1 :                 RETURN_ZSTRL(intern->file_name_type, intern->file_name, intern->file_name_len, ZSTR_DUPLICATE);
     869                 :         }
     870                 : }
     871                 : /* }}} */
     872                 : 
     873                 : /* {{{ proto string DirectoryIterator::getFilename() U
     874                 :    Return filename of current dir entry */
     875                 : SPL_METHOD(DirectoryIterator, getFilename)
     876               8 : {
     877               8 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     878                 : 
     879               8 :         RETURN_RT_STRING(intern->u.dir.entry.d_name, ZSTR_DUPLICATE);
     880                 : }
     881                 : /* }}} */
     882                 : 
     883                 : /* {{{ proto string SplFileInfo::getBasename([string $suffix]) U
     884                 :    Returns filename component of path */
     885                 : SPL_METHOD(SplFileInfo, getBasename)
     886               1 : {
     887               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     888                 :         zstr fname, suffix, path;
     889               1 :         int flen, slen = 0, path_len;
     890                 :         zend_uchar path_type, stype;
     891                 : 
     892               1 :         suffix.v = 0;
     893               1 :         if (intern->file_name_type == IS_UNICODE) {  
     894               1 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|t", &suffix, &slen, &stype) == FAILURE) {
     895               0 :                         return;
     896                 :                 }
     897                 :         } else {
     898               0 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix.s, &slen) == FAILURE) {
     899               0 :                         return;
     900                 :                 }
     901                 :         }
     902                 : 
     903               1 :         path = spl_filesystem_object_get_path(intern, &path_len, &path_type TSRMLS_CC);
     904               2 :         if (path_len && path_len < intern->file_name_len) {
     905               1 :                 if (intern->file_name_type == IS_UNICODE) {
     906               1 :                         fname.u = intern->file_name.u + path_len + 1;
     907                 :                 } else {
     908               0 :                         fname.s = intern->file_name.s + path_len + 1;
     909                 :                 }
     910               1 :                 flen = intern->file_name_len - (path_len + 1);
     911                 :         } else {
     912               0 :                 fname = intern->file_name;
     913               0 :                 flen = intern->file_name_len;
     914                 :         }
     915                 : 
     916               1 :         if (intern->file_name_type == IS_UNICODE) {  
     917               1 :                 php_u_basename(fname.u, flen, suffix.u, slen, &fname.u, &flen TSRMLS_CC);
     918                 :         } else {
     919               0 :                 php_basename(fname.s, flen, suffix.s, slen, &fname.s, &flen TSRMLS_CC);
     920                 :         }
     921                 : 
     922               1 :         RETURN_ZSTRL(intern->file_name_type, fname, flen, 0);
     923                 : }
     924                 : /* }}}*/   
     925                 : 
     926                 : /* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U
     927                 :    Returns filename component of current dir entry */
     928                 : SPL_METHOD(DirectoryIterator, getBasename)
     929               2 : {
     930               2 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     931               2 :         char *suffix = 0, *fname;
     932               2 :         int slen = 0, flen;
     933                 :         
     934               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
     935               1 :                 return;
     936                 :         }
     937                 : 
     938               1 :         php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC);
     939                 : 
     940               1 :         RETURN_RT_STRINGL(fname, flen, ZSTR_AUTOFREE);
     941                 : }
     942                 : /* }}} */
     943                 : 
     944                 : /* {{{ proto string SplFileInfo::getPathname() U
     945                 :    Return path and filename */
     946                 : SPL_METHOD(SplFileInfo, getPathname)
     947              98 : {
     948              98 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     949                 :         zstr       path;
     950                 :         zend_uchar path_type;
     951                 :         int        path_len;
     952                 : 
     953              98 :         path = spl_filesystem_object_get_pathname(intern, &path_len, &path_type TSRMLS_CC);
     954              98 :         if (path_len) {
     955              98 :                 RETURN_ZSTRL(path_type, path, path_len, ZSTR_DUPLICATE);
     956                 :         }
     957               0 :         RETURN_BOOL(0);
     958                 : }
     959                 : /* }}} */
     960                 : 
     961                 : /* {{{ proto string FilesystemIterator::key() U
     962                 :    Return getPathname() or getFilename() depending on flags */
     963                 : SPL_METHOD(FilesystemIterator, key)
     964            3095 : {
     965            3095 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     966                 : 
     967            3095 :         if (SPL_FILE_DIR_KEY(intern, SPL_FILE_DIR_KEY_AS_FILENAME)) {
     968               0 :                 RETURN_RT_STRING(intern->u.dir.entry.d_name, ZSTR_DUPLICATE);
     969                 :         } else {
     970            3095 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     971            3095 :                 RETURN_ZSTRL(intern->file_name_type, intern->file_name, intern->file_name_len, 1);
     972                 :         }
     973                 : }
     974                 : /* }}} */
     975                 : 
     976                 : /* {{{ proto string FilesystemIterator::current() U
     977                 :    Return getFilename(), getFileInfo() or $this depending on flags */
     978                 : SPL_METHOD(FilesystemIterator, current)
     979            3176 : {
     980            3176 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     981                 : 
     982            3176 :         if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
     983               4 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     984               4 :                 RETURN_ZSTRL(intern->file_name_type, intern->file_name, intern->file_name_len, ZSTR_DUPLICATE);
     985            3172 :         } else if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_FILEINFO)) {
     986            3169 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
     987            3169 :                 spl_filesystem_object_create_type(0, intern, SPL_FS_INFO, NULL, return_value TSRMLS_CC);
     988                 :         } else {
     989               3 :                 RETURN_ZVAL(getThis(), 1, 0);
     990                 :                 /*RETURN_STRING(intern->u.dir.entry.d_name, 1);*/
     991                 :         }
     992                 : }
     993                 : /* }}} */
     994                 : 
     995                 : /* {{{ proto bool DirectoryIterator::isDot() U
     996                 :    Returns true if current entry is '.' or  '..' */
     997                 : SPL_METHOD(DirectoryIterator, isDot)
     998               4 : {
     999               4 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1000                 : 
    1001               4 :         RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name));
    1002                 : }
    1003                 : /* }}} */
    1004                 : 
    1005                 : /* {{{ proto void SplFileInfo::__construct(string file_name) U
    1006                 :  Cronstructs a new SplFileInfo from a path. */
    1007                 : /* zend_replace_error_handling() is used to throw exceptions in case
    1008                 :    the constructor fails. Here we use this to ensure the object
    1009                 :    has a valid directory resource.
    1010                 :    
    1011                 :    When the constructor gets called the object is already created 
    1012                 :    by the engine, so we must only call 'additional' initializations.
    1013                 :  */
    1014                 : SPL_METHOD(SplFileInfo, __construct)
    1015             408 : {
    1016                 :         spl_filesystem_object *intern;
    1017                 :         zstr path;
    1018                 :         int path_len;
    1019                 :         zend_uchar path_type;
    1020                 :         zend_error_handling error_handling;
    1021                 : 
    1022             408 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
    1023                 : 
    1024             408 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &path, &path_len, &path_type) == FAILURE) {
    1025               0 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
    1026               0 :                 return;
    1027                 :         }
    1028                 : 
    1029             408 :         intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1030                 :         
    1031             408 :         spl_filesystem_info_set_filename(intern, path_type, path, path_len, 1 TSRMLS_CC);
    1032                 : 
    1033             408 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1034                 :         
    1035                 :         /* intern->type = SPL_FS_INFO; already set */
    1036                 : }
    1037                 : /* }}} */
    1038                 : 
    1039                 : /* {{{ FileInfoFunction */
    1040                 : #define FileInfoFunction(func_name, func_num) \
    1041                 : SPL_METHOD(SplFileInfo, func_name) \
    1042                 : { \
    1043                 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
    1044                 :         zend_error_handling error_handling; \
    1045                 :  \
    1046                 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);\
    1047                 :         spl_filesystem_object_get_file_name(intern TSRMLS_CC); \
    1048                 :         php_u_stat(intern->file_name_type, intern->file_name, intern->file_name_len, func_num, FG(default_context), return_value TSRMLS_CC); \
    1049                 :         zend_restore_error_handling(&error_handling TSRMLS_CC); \
    1050                 : }
    1051                 : /* }}} */
    1052                 : 
    1053                 : /* {{{ proto int SplFileInfo::getPerms() U
    1054                 :    Get file permissions */
    1055               2 : FileInfoFunction(getPerms, FS_PERMS)
    1056                 : /* }}} */
    1057                 : 
    1058                 : /* {{{ proto int SplFileInfo::getInode() U
    1059                 :    Get file inode */
    1060               4 : FileInfoFunction(getInode, FS_INODE)
    1061                 : /* }}} */
    1062                 : 
    1063                 : /* {{{ proto int SplFileInfo::getSize() U
    1064                 :    Get file size */
    1065               5 : FileInfoFunction(getSize, FS_SIZE)
    1066                 : /* }}} */
    1067                 : 
    1068                 : /* {{{ proto int SplFileInfo::getOwner() U
    1069                 :    Get file owner */
    1070               3 : FileInfoFunction(getOwner, FS_OWNER)
    1071                 : /* }}} */
    1072                 : 
    1073                 : /* {{{ proto int SplFileInfo::getGroup() U
    1074                 :    Get file group */
    1075               3 : FileInfoFunction(getGroup, FS_GROUP)
    1076                 : /* }}} */
    1077                 : 
    1078                 : /* {{{ proto int SplFileInfo::getATime() U
    1079                 :    Get last access time of file */
    1080               4 : FileInfoFunction(getATime, FS_ATIME)
    1081                 : /* }}} */
    1082                 : 
    1083                 : /* {{{ proto int SplFileInfo::getMTime() U
    1084                 :    Get last modification time of file */
    1085               4 : FileInfoFunction(getMTime, FS_MTIME)
    1086                 : /* }}} */
    1087                 : 
    1088                 : /* {{{ proto int SplFileInfo::getCTime() U
    1089                 :    Get inode modification time of file */
    1090               4 : FileInfoFunction(getCTime, FS_CTIME)
    1091                 : /* }}} */
    1092                 : 
    1093                 : /* {{{ proto string SplFileInfo::getType() U
    1094                 :    Get file type */
    1095               4 : FileInfoFunction(getType, FS_TYPE)
    1096                 : /* }}} */
    1097                 : 
    1098                 : /* {{{ proto bool SplFileInfo::isWritable() U
    1099                 :    Returns true if file can be written */
    1100               9 : FileInfoFunction(isWritable, FS_IS_W)
    1101                 : /* }}} */
    1102                 : 
    1103                 : /* {{{ proto bool SplFileInfo::isReadable() U
    1104                 :    Returns true if file can be read */
    1105              18 : FileInfoFunction(isReadable, FS_IS_R)
    1106                 : /* }}} */
    1107                 : 
    1108                 : /* {{{ proto bool SplFileInfo::isExecutable() U
    1109                 :    Returns true if file is executable */
    1110              16 : FileInfoFunction(isExecutable, FS_IS_X)
    1111                 : /* }}} */
    1112                 : 
    1113                 : /* {{{ proto bool SplFileInfo::isFile() U
    1114                 :    Returns true if file is a regular file */
    1115               7 : FileInfoFunction(isFile, FS_IS_FILE)
    1116                 : /* }}} */
    1117                 : 
    1118                 : /* {{{ proto bool SplFileInfo::isDir() U
    1119                 :    Returns true if file is directory */
    1120              37 : FileInfoFunction(isDir, FS_IS_DIR)
    1121                 : /* }}} */
    1122                 : 
    1123                 : /* {{{ proto bool SplFileInfo::isLink() U
    1124                 :    Returns true if file is symbolic link */
    1125               6 : FileInfoFunction(isLink, FS_IS_LINK)
    1126                 : /* }}} */
    1127                 : 
    1128                 : /* {{{ proto string SplFileInfo::getLinkTarget() U
    1129                 :    Return the target of a symbolic link */
    1130                 : SPL_METHOD(SplFileInfo, getLinkTarget)
    1131               1 : {
    1132               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1133                 :         UChar *target;
    1134                 :         int ret, link_len, target_len;
    1135               1 :         char *link = NULL, buff[MAXPATHLEN];
    1136                 :         zend_error_handling error_handling;
    1137                 : 
    1138               1 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
    1139                 : 
    1140               1 :         if (intern->file_name_type == IS_UNICODE) {
    1141               1 :                 php_stream_path_encode(NULL, &link, &link_len, intern->file_name.u, intern->file_name_len, REPORT_ERRORS, FG(default_context));
    1142                 :         } else {
    1143               0 :                 link = intern->file_name.s;
    1144                 :         }
    1145                 : 
    1146                 : #ifdef HAVE_SYMLINK
    1147               1 :         ret = link ? readlink(link, buff, MAXPATHLEN-1) : -1;
    1148                 : #else
    1149                 :         ret = -1; /* always fail if not implemented */
    1150                 : #endif
    1151                 : 
    1152               1 :         if (link && intern->file_name_type == IS_UNICODE) {
    1153               1 :                 efree(link);
    1154                 :         }
    1155               1 :         if (ret == -1) {
    1156               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %R, error: %s", intern->file_name_type, intern->file_name, strerror(errno));
    1157               0 :                 RETVAL_FALSE;
    1158                 :         } else {
    1159                 :                 /* Append NULL to the end of the string */
    1160               1 :                 buff[ret] = '\0';
    1161                 : 
    1162               1 :                 if (SUCCESS == php_stream_path_decode(NULL, &target, &target_len, buff, ret, REPORT_ERRORS, FG(default_context))) {
    1163               1 :                         RETVAL_UNICODEL(target, target_len, 0);
    1164                 :                 } else {
    1165               0 :                         RETVAL_STRING(buff, 1);
    1166                 :                 }
    1167                 :         }
    1168               1 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1169               1 : }
    1170                 : /* }}} */
    1171                 : 
    1172                 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
    1173                 : /* {{{ proto string SplFileInfo::getRealPath() U
    1174                 :    Return the resolved path */
    1175                 : SPL_METHOD(SplFileInfo, getRealPath)
    1176             747 : {
    1177             747 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1178                 :         UChar *path;
    1179                 :         int filename_len, path_len;
    1180                 :         char *filename, buff[MAXPATHLEN];
    1181             747 :         zend_bool free_filename = 0;
    1182                 :         zend_error_handling error_handling;
    1183                 : 
    1184             747 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
    1185                 : 
    1186             747 :         if (intern->type == SPL_FS_DIR && !intern->file_name.v && intern->u.dir.entry.d_name[0]) {
    1187             746 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
    1188                 :         }
    1189                 : 
    1190             747 :         if (intern->orig_path) {
    1191               1 :                 filename = intern->orig_path;
    1192                 :         } else {
    1193             746 :                 if (intern->file_name_type == IS_UNICODE) {
    1194             746 :                         php_stream_path_encode(NULL, &filename, &filename_len, intern->file_name.u, intern->file_name_len, REPORT_ERRORS, FG(default_context));
    1195             746 :                         free_filename = filename != NULL;
    1196                 :                 } else {
    1197               0 :                         filename = intern->file_name.s;
    1198                 :                 }
    1199                 :         }
    1200                 : 
    1201            1494 :         if (filename && VCWD_REALPATH(filename, buff)) {
    1202                 : #ifdef ZTS
    1203                 :                 if (VCWD_ACCESS(buff, F_OK)) {
    1204                 :                         RETVAL_FALSE;
    1205                 :                 } else
    1206                 : #endif
    1207             747 :                 if (php_stream_path_decode(NULL, &path, &path_len, buff, strlen(buff), REPORT_ERRORS, FG(default_context)) == SUCCESS) {
    1208             747 :                         RETVAL_UNICODEL(path, path_len, 0);
    1209                 :                 } else {
    1210               0 :                         RETVAL_STRING(buff, 1);
    1211                 :                 }
    1212                 :         } else {
    1213               0 :                 RETVAL_FALSE;
    1214                 :         }
    1215                 : 
    1216             747 :         if (free_filename) {
    1217             746 :                 efree(filename);
    1218                 :         }
    1219             747 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1220             747 : }
    1221                 : /* }}} */
    1222                 : #endif
    1223                 : 
    1224                 : /* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path  [, resource context]]]) U
    1225                 :    Open the current file */
    1226                 : SPL_METHOD(SplFileInfo, openFile)
    1227               7 : {
    1228               7 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1229                 : 
    1230               7 :         spl_filesystem_object_create_type(ht, intern, SPL_FS_FILE, NULL, return_value TSRMLS_CC);
    1231               7 : }
    1232                 : /* }}} */
    1233                 : 
    1234                 : /* {{{ proto void SplFileInfo::setFileClass([string class_name]) U
    1235                 :    Class to use in openFile() */
    1236                 : SPL_METHOD(SplFileInfo, setFileClass)
    1237               1 : {
    1238               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1239               1 :         zend_class_entry *ce = spl_ce_SplFileObject;
    1240                 :         zend_error_handling error_handling;
    1241                 : 
    1242               1 :         zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
    1243                 : 
    1244               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
    1245               0 :                 intern->file_class = ce;
    1246                 :         }
    1247                 : 
    1248               1 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1249               1 : }
    1250                 : /* }}} */
    1251                 : 
    1252                 : /* {{{ proto void SplFileInfo::setInfoClass([string class_name]) U
    1253                 :    Class to use in getFileInfo(), getPathInfo() */
    1254                 : SPL_METHOD(SplFileInfo, setInfoClass)
    1255              12 : {
    1256              12 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1257              12 :         zend_class_entry *ce = spl_ce_SplFileInfo;
    1258                 :         zend_error_handling error_handling;
    1259                 : 
    1260              12 :         zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
    1261                 : 
    1262              12 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
    1263              12 :                 intern->info_class = ce;
    1264                 :         }
    1265                 : 
    1266              12 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1267              12 : }
    1268                 : /* }}} */
    1269                 : 
    1270                 : /* {{{ proto SplFileInfo SplFileInfo::getFileInfo([string $class_name]) U
    1271                 :    Get/copy file info */
    1272                 : SPL_METHOD(SplFileInfo, getFileInfo)
    1273               2 : {
    1274               2 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1275               2 :         zend_class_entry *ce = intern->info_class;
    1276                 :         zend_error_handling error_handling;
    1277                 : 
    1278               2 :         zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
    1279                 : 
    1280               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
    1281               2 :                 spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC);
    1282                 :         }
    1283                 : 
    1284               2 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1285               2 : }
    1286                 : /* }}} */
    1287                 : 
    1288                 : /* {{{ proto SplFileInfo SplFileInfo::getPathInfo([string $class_name]) U
    1289                 :    Get/copy file info */
    1290                 : SPL_METHOD(SplFileInfo, getPathInfo)
    1291               5 : {
    1292               5 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1293               5 :         zend_class_entry *ce = intern->info_class;
    1294                 :         zend_error_handling error_handling;
    1295                 : 
    1296               5 :         zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC);
    1297                 : 
    1298               5 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
    1299                 :                 zend_uchar path_type;
    1300                 :                 int path_len;
    1301               5 :                 zstr path = spl_filesystem_object_get_pathname(intern, &path_len, &path_type TSRMLS_CC);
    1302               5 :                 if (path_len) {
    1303               5 :                         spl_filesystem_object_create_info(intern, path_type, path, path_len, 1, ce, return_value TSRMLS_CC);
    1304                 :                 }
    1305                 :         }
    1306               5 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    1307               5 : }
    1308                 : /* }}} */
    1309                 : 
    1310                 : /* {{{ proto void FilesystemIterator::__construct(string path [, int flags])
    1311                 :  Cronstructs a new dir iterator from a path. */
    1312                 : SPL_METHOD(FilesystemIterator, __construct)
    1313               3 : {
    1314               3 :         spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS | SPL_FILE_DIR_SKIPDOTS);
    1315               3 : }
    1316                 : /* }}} */
    1317                 : 
    1318                 : /* {{{ proto void FilesystemIterator::rewind() U
    1319                 :    Rewind dir back to the start */
    1320                 : SPL_METHOD(FilesystemIterator, rewind)
    1321             159 : {
    1322             159 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1323                 : 
    1324             159 :         intern->u.dir.index = 0;
    1325             159 :         if (intern->u.dir.dirp) {
    1326             159 :                 php_stream_rewinddir(intern->u.dir.dirp);
    1327                 :         }
    1328                 :         do {
    1329             247 :                 spl_filesystem_dir_read(intern TSRMLS_CC);
    1330             247 :         } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
    1331             159 : }
    1332                 : /* }}} */
    1333                 : 
    1334                 : /* {{{ proto int FilesystemIterator::getFlags() U
    1335                 :    Get handling flags */
    1336                 : SPL_METHOD(FilesystemIterator, getFlags)
    1337              12 : {
    1338              12 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1339                 : 
    1340              12 :         RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | SPL_FILE_DIR_CURRENT_MODE_MASK | SPL_FILE_DIR_OTHERS_MASK));
    1341                 : } /* }}} */
    1342                 : 
    1343                 : /* {{{ proto void FilesystemIterator::setFlags(long $flags) U
    1344                 :    Set handling flags */
    1345                 : SPL_METHOD(FilesystemIterator, setFlags)
    1346               9 : {
    1347               9 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1348                 :         long flags;
    1349                 : 
    1350               9 :         zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags);
    1351                 : 
    1352               9 :         intern->flags &= ~(SPL_FILE_DIR_KEY_MODE_MASK|SPL_FILE_DIR_CURRENT_MODE_MASK|SPL_FILE_DIR_OTHERS_MASK);
    1353               9 :         intern->flags |= ((SPL_FILE_DIR_KEY_MODE_MASK|SPL_FILE_DIR_CURRENT_MODE_MASK|SPL_FILE_DIR_OTHERS_MASK) & flags);
    1354               9 : } /* }}} */
    1355                 : 
    1356                 : /* {{{ proto bool RecursiveDirectoryIterator::hasChildren([bool $allow_links = false]) U
    1357                 :    Returns whether current entry is a directory and not '.' or '..' */
    1358                 : SPL_METHOD(RecursiveDirectoryIterator, hasChildren)
    1359            3247 : {
    1360            3247 :         zend_bool allow_links = 0;
    1361            3247 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1362                 :         
    1363            3247 :         if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) {
    1364              68 :                 RETURN_FALSE;
    1365                 :         } else {
    1366            3179 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) {
    1367               0 :                         return;
    1368                 :                 }
    1369            3179 :                 spl_filesystem_object_get_file_name(intern TSRMLS_CC);
    1370            3179 :                 if (!allow_links && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) {
    1371            3179 :                         php_u_stat(intern->file_name_type, intern->file_name, intern->file_name_len, FS_IS_LINK, FG(default_context), return_value TSRMLS_CC);
    1372            3179 :                         if (zend_is_true(return_value)) {
    1373               0 :                                 RETURN_FALSE;
    1374                 :                         }
    1375                 :                 }
    1376            3179 :                 php_u_stat(intern->file_name_type, intern->file_name, intern->file_name_len, FS_IS_DIR, FG(default_context), return_value TSRMLS_CC);
    1377                 :     }
    1378                 : }
    1379                 : /* }}} */
    1380                 : 
    1381                 : /* {{{ proto RecursiveDirectoryIterator DirectoryIterator::getChildren() U
    1382                 :    Returns an iterator for the current entry if it is a directory */
    1383                 : SPL_METHOD(RecursiveDirectoryIterator, getChildren)
    1384             120 : {
    1385                 :         zval zpath, zflags;
    1386             120 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1387                 :         spl_filesystem_object *subdir;
    1388             120 :         char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
    1389                 :         
    1390             120 :         spl_filesystem_object_get_file_name(intern TSRMLS_CC);
    1391                 : 
    1392             120 :         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
    1393               0 :                 RETURN_ZSTRL(intern->file_name_type, intern->file_name, intern->file_name_len, 1);
    1394                 :         } else {
    1395             120 :                 INIT_PZVAL(&zflags);
    1396             120 :                 INIT_PZVAL(&zpath);
    1397             120 :                 ZVAL_LONG(&zflags, intern->flags);
    1398             120 :                 ZVAL_ZSTRL(&zpath, intern->file_name_type, intern->file_name, intern->file_name_len, 1);
    1399                 : 
    1400             120 :                 spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), &return_value, 0, &zpath, &zflags TSRMLS_CC);
    1401                 : 
    1402             120 :                 zval_dtor(&zpath);
    1403                 : 
    1404             120 :                 subdir = (spl_filesystem_object*)zend_object_store_get_object(return_value TSRMLS_CC);
    1405             120 :                 if (subdir) {
    1406             220 :                         if (intern->u.dir.sub_path.v && intern->u.dir.sub_path_len > 1) {
    1407             100 :                                 subdir->u.dir.sub_path_type = intern->u.dir.sub_path_type;
    1408             100 :                                 subdir->u.dir.sub_path_len = zspprintf(intern->u.dir.sub_path_type, &subdir->u.dir.sub_path, 0, "%R%c%s", intern->u.dir.sub_path_type, intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name);
    1409                 :                         } else {
    1410              20 :                                 subdir->u.dir.sub_path_len = strlen(intern->u.dir.entry.d_name);
    1411              20 :                                 subdir->u.dir.sub_path_type = IS_STRING;
    1412              20 :                                 subdir->u.dir.sub_path.s = estrndup(intern->u.dir.entry.d_name, subdir->u.dir.sub_path_len);
    1413                 :                         }
    1414             120 :                         subdir->info_class = intern->info_class;
    1415             120 :                         subdir->file_class = intern->file_class;
    1416             120 :                         subdir->oth = intern->oth;
    1417                 :                 }
    1418                 :         }
    1419                 : }
    1420                 : /* }}} */
    1421                 : 
    1422                 : /* {{{ proto void RecursiveDirectoryIterator::getSubPath() U
    1423                 :    Get sub path */
    1424                 : SPL_METHOD(RecursiveDirectoryIterator, getSubPath)
    1425               5 : {
    1426               5 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1427                 : 
    1428               5 :         if (intern->u.dir.sub_path.v) {
    1429               2 :                 RETURN_ZSTRL(intern->u.dir.sub_path_type, intern->u.dir.sub_path, intern->u.dir.sub_path_len, ZSTR_DUPLICATE);
    1430                 :         } else {
    1431               3 :                 RETURN_EMPTY_UNICODE();
    1432                 :         }
    1433                 : }
    1434                 : /* }}} */
    1435                 : 
    1436                 : /* {{{ proto void RecursiveDirectoryIterator::getSubPathname() U
    1437                 :    Get sub path and file name */
    1438                 : SPL_METHOD(RecursiveDirectoryIterator, getSubPathname)
    1439               5 : {
    1440               5 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1441                 :         zstr sub_name;
    1442                 :         int sub_len;
    1443               5 :         char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
    1444                 : 
    1445               5 :         if (intern->u.dir.sub_path.v) {
    1446               2 :                 sub_len = zspprintf(intern->u.dir.sub_path_type, &sub_name, 0, "%R%c%s", intern->u.dir.sub_path_type, intern->u.dir.sub_path, slash, intern->u.dir.entry.d_name);
    1447               2 :                 RETURN_ZSTRL(intern->u.dir.sub_path_type, sub_name, sub_len, 0);
    1448                 :         } else {
    1449               3 :                 RETURN_RT_STRING(intern->u.dir.entry.d_name, ZSTR_DUPLICATE);
    1450                 :         }
    1451                 : }
    1452                 : /* }}} */
    1453                 : 
    1454                 : /* {{{ proto int RecursiveDirectoryIterator::__construct(string path [, int flags])
    1455                 :  Cronstructs a new dir iterator from a path. */
    1456                 : SPL_METHOD(RecursiveDirectoryIterator, __construct)
    1457             523 : {
    1458             523 :         spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS);
    1459             523 : }
    1460                 : /* }}} */
    1461                 : 
    1462                 : /* {{{ proto int GlobIterator::__construct(string path [, int flags]) U
    1463                 :  Cronstructs a new dir iterator from a glob expression (no glob:// needed). */
    1464                 : SPL_METHOD(GlobIterator, __construct)
    1465               1 : {
    1466               1 :         spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIT_CTOR_FLAGS|DIT_CTOR_GLOB);
    1467               1 : }
    1468                 : /* }}} */
    1469                 : 
    1470                 : /* {{{ proto int GlobIterator::cont() U
    1471                 :    Return the number of directories and files found by globbing */
    1472                 : SPL_METHOD(GlobIterator, count)
    1473               0 : {
    1474               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    1475                 : 
    1476               0 :         if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) {
    1477               0 :                 RETURN_LONG(php_glob_stream_get_count(intern->u.dir.dirp, NULL));
    1478                 :         } else {
    1479                 :                 /* should not happen */
    1480               0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "GlobIterator lost glob state");
    1481                 :         }
    1482                 : }
    1483                 : /* }}} */
    1484                 : 
    1485                 : /* {{{ forward declarations to the iterator handlers */
    1486                 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
    1487                 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
    1488                 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
    1489                 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zstr *str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
    1490                 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
    1491                 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
    1492                 : 
    1493                 : /* iterator handler table */
    1494                 : zend_object_iterator_funcs spl_filesystem_dir_it_funcs = {
    1495                 :         spl_filesystem_dir_it_dtor,
    1496                 :         spl_filesystem_dir_it_valid,
    1497                 :         spl_filesystem_dir_it_current_data,
    1498                 :         spl_filesystem_dir_it_current_key,
    1499                 :         spl_filesystem_dir_it_move_forward,
    1500                 :         spl_filesystem_dir_it_rewind
    1501                 : };
    1502                 : /* }}} */
    1503                 : 
    1504                 : /* {{{ spl_ce_dir_get_iterator */
    1505                 : zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
    1506               6 : {
    1507                 :         spl_filesystem_iterator *iterator;
    1508                 :         spl_filesystem_object   *dir_object;
    1509                 : 
    1510               6 :         if (by_ref) {
    1511               1 :                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
    1512                 :         }
    1513               5 :         dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
    1514               5 :         iterator   = spl_filesystem_object_to_iterator(dir_object);
    1515                 : 
    1516               5 :         Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2);
    1517               5 :         iterator->intern.data = (void*)object;
    1518               5 :         iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
    1519               5 :         iterator->current = object;
    1520                 :         
    1521               5 :         return (zend_object_iterator*)iterator;
    1522                 : }
    1523                 : /* }}} */
    1524                 : 
    1525                 : /* {{{ spl_filesystem_dir_it_dtor */
    1526                 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
    1527               5 : {
    1528               5 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1529               5 :         zval *zfree = (zval*)iterator->intern.data;
    1530                 : 
    1531               5 :         iterator->intern.data = NULL; /* mark as unused */
    1532               5 :         zval_ptr_dtor(&iterator->current);
    1533               5 :         zval_ptr_dtor(&zfree);
    1534               5 : }
    1535                 : /* }}} */
    1536                 : 
    1537                 : /* {{{ spl_filesystem_dir_it_valid */
    1538                 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC)
    1539            2881 : {
    1540            2881 :         spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
    1541                 : 
    1542            2881 :         return object->u.dir.entry.d_name[0] != '\0' ? SUCCESS : FAILURE;
    1543                 : }
    1544                 : /* }}} */
    1545                 : 
    1546                 : /* {{{ spl_filesystem_dir_it_current_data */
    1547                 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
    1548            2092 : {
    1549            2092 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1550                 :         
    1551            2092 :         *data = &iterator->current;
    1552            2092 : }
    1553                 : /* }}} */
    1554                 : 
    1555                 : /* {{{ spl_filesystem_dir_it_current_key */
    1556                 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zstr *str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
    1557            1346 : {
    1558            1346 :         spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
    1559                 :         
    1560            1346 :         *int_key = object->u.dir.index;
    1561            1346 :         return HASH_KEY_IS_LONG;
    1562                 : }
    1563                 : /* }}} */
    1564                 : 
    1565                 : /* {{{ spl_filesystem_dir_it_move_forward */
    1566                 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
    1567            2092 : {
    1568            2092 :         spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
    1569                 :         
    1570            2092 :         object->u.dir.index++;
    1571            2092 :         spl_filesystem_dir_read(object TSRMLS_CC);
    1572            2092 :         if (object->file_name.v) {
    1573             750 :                 efree(object->file_name.v);
    1574             750 :                 object->file_name = NULL_ZSTR;
    1575                 :         }
    1576            2092 : }
    1577                 : /* }}} */
    1578                 : 
    1579                 : /* {{{ spl_filesystem_dir_it_rewind */
    1580                 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC)
    1581               5 : {
    1582               5 :         spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
    1583                 :         
    1584               5 :         object->u.dir.index = 0;
    1585               5 :         if (object->u.dir.dirp) {
    1586               5 :                 php_stream_rewinddir(object->u.dir.dirp);
    1587                 :         }
    1588               5 :         spl_filesystem_dir_read(object TSRMLS_CC);
    1589               5 : }
    1590                 : /* }}} */
    1591                 : 
    1592                 : /* {{{ spl_filesystem_tree_it_dtor */
    1593                 : static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC)
    1594               1 : {
    1595               1 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1596               1 :         zval *zfree = (zval*)iterator->intern.data;
    1597                 : 
    1598               1 :         if (iterator->current) {
    1599               0 :                 zval_ptr_dtor(&iterator->current);
    1600                 :         }
    1601               1 :         iterator->intern.data = NULL; /* mark as unused */
    1602                 :         /* free twice as we add ref twice */
    1603               1 :         zval_ptr_dtor(&zfree);
    1604               1 :         zval_ptr_dtor(&zfree);
    1605               1 : }
    1606                 : /* }}} */
    1607                 : 
    1608                 : /* {{{ spl_filesystem_tree_it_current_data */
    1609                 : static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
    1610             783 : {
    1611             783 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1612             783 :         spl_filesystem_object   *object   = spl_filesystem_iterator_to_object(iterator);
    1613                 : 
    1614             783 :         if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
    1615               0 :                 if (!iterator->current) {
    1616               0 :                         ALLOC_INIT_ZVAL(iterator->current);
    1617               0 :                         spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1618               0 :                         ZVAL_ZSTRL(iterator->current, object->file_name_type, object->file_name, object->file_name_len, ZSTR_DUPLICATE);
    1619                 :                 }
    1620               0 :                 *data = &iterator->current;
    1621             783 :         } else if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_FILEINFO)) {
    1622             783 :                 if (!iterator->current) {
    1623             783 :                         ALLOC_INIT_ZVAL(iterator->current);
    1624             783 :                         spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1625             783 :                         spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, iterator->current TSRMLS_CC);
    1626                 :                 }
    1627             783 :                 *data = &iterator->current;
    1628                 :         } else {
    1629               0 :                 *data = (zval**)&iterator->intern.data;
    1630                 :         }
    1631             783 : }
    1632                 : /* }}} */
    1633                 : 
    1634                 : /* {{{ spl_filesystem_tree_it_current_key */
    1635                 : static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, zstr *str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
    1636               0 : {
    1637               0 :         spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
    1638                 :         
    1639               0 :         if (SPL_FILE_DIR_KEY(object, SPL_FILE_DIR_KEY_AS_FILENAME)) {
    1640               0 :                 *str_key_len = strlen(object->u.dir.entry.d_name) + 1;
    1641               0 :                 str_key->s = estrndup(object->u.dir.entry.d_name, *str_key_len - 1);
    1642               0 :                 return HASH_KEY_IS_STRING;
    1643                 :         } else {
    1644               0 :                 spl_filesystem_object_get_file_name(object TSRMLS_CC);
    1645               0 :                 *str_key_len = object->file_name_len + 1;
    1646               0 :                 *str_key = ezstrndup(object->file_name_type, object->file_name, object->file_name_len);
    1647               0 :                 return object->file_name_type;
    1648                 :         }
    1649                 : }
    1650                 : /* }}} */
    1651                 : 
    1652                 : /* {{{ spl_filesystem_tree_it_move_forward */
    1653                 : static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
    1654             783 : {
    1655             783 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1656             783 :         spl_filesystem_object   *object   = spl_filesystem_iterator_to_object(iterator);
    1657                 :         
    1658             783 :         object->u.dir.index++;
    1659                 :         do {
    1660             783 :                 spl_filesystem_dir_read(object TSRMLS_CC);
    1661             783 :         } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
    1662             783 :         if (object->file_name.v) {
    1663             783 :                 efree(object->file_name.v);
    1664             783 :                 object->file_name = NULL_ZSTR;
    1665                 :         }
    1666             783 :         if (iterator->current) {
    1667             783 :                 zval_ptr_dtor(&iterator->current);
    1668             783 :                 iterator->current = NULL;
    1669                 :         }
    1670             783 : }
    1671                 : /* }}} */
    1672                 : 
    1673                 : /* {{{ spl_filesystem_tree_it_rewind */
    1674                 : static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC)
    1675               1 : {
    1676               1 :         spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
    1677               1 :         spl_filesystem_object   *object   = spl_filesystem_iterator_to_object(iterator);
    1678                 :         
    1679               1 :         object->u.dir.index = 0;
    1680               1 :         if (object->u.dir.dirp) {
    1681               1 :                 php_stream_rewinddir(object->u.dir.dirp);
    1682                 :         }
    1683                 :         do {
    1684               3 :                 spl_filesystem_dir_read(object TSRMLS_CC);
    1685               3 :         } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
    1686               1 :         if (iterator->current) {
    1687               0 :                 zval_ptr_dtor(&iterator->current);
    1688               0 :                 iterator->current = NULL;
    1689                 :         }
    1690               1 : }
    1691                 : /* }}} */
    1692                 : 
    1693                 : /* {{{ iterator handler table */
    1694                 : zend_object_iterator_funcs spl_filesystem_tree_it_funcs = {
    1695                 :         spl_filesystem_tree_it_dtor,
    1696                 :         spl_filesystem_dir_it_valid,
    1697                 :         spl_filesystem_tree_it_current_data,
    1698                 :         spl_filesystem_tree_it_current_key,
    1699                 :         spl_filesystem_tree_it_move_forward,
    1700                 :         spl_filesystem_tree_it_rewind
    1701                 : };
    1702                 : /* }}} */
    1703                 : 
    1704                 : /* {{{ spl_ce_dir_get_iterator */
    1705                 : zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
    1706               1 : {
    1707                 :         spl_filesystem_iterator *iterator;
    1708                 :         spl_filesystem_object *dir_object;
    1709                 : 
    1710               1 :         if (by_ref) {
    1711               0 :                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
    1712                 :         }
    1713               1 :         dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
    1714               1 :         iterator   = spl_filesystem_object_to_iterator(dir_object);
    1715                 : 
    1716               1 :         Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2);
    1717               1 :         iterator->intern.data = (void*)object;
    1718               1 :         iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
    1719               1 :         iterator->current = NULL;
    1720                 :         
    1721               1 :         return (zend_object_iterator*)iterator;
    1722                 : }
    1723                 : /* }}} */
    1724                 : 
    1725                 : /* {{{ spl_filesystem_object_cast */
    1726                 : static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC)
    1727            4408 : {
    1728            4408 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
    1729                 :         int ret;
    1730                 :         zval retval;
    1731            4408 :         zval *retval_ptr = &retval;
    1732                 : 
    1733            4408 :         switch (intern->type) {
    1734                 :         case SPL_FS_INFO:
    1735                 :         case SPL_FS_FILE:
    1736            3057 :                 if (type == intern->file_name_type) {
    1737              12 :                         ZVAL_ZSTRL(retval_ptr, intern->file_name_type, intern->file_name, intern->file_name_len, 1);
    1738              12 :                         ret = SUCCESS;
    1739              12 :                         break;
    1740                 :                 }
    1741            3045 :                 if (type == IS_STRING) {
    1742            3042 :                         ZVAL_ZSTRL(retval_ptr, intern->file_name_type, intern->file_name, intern->file_name_len, ZSTR_DUPLICATE);
    1743            3042 :                         zval_unicode_to_string_ex(retval_ptr, ZEND_U_CONVERTER(((UConverter *)extra)) TSRMLS_CC);
    1744            3042 :                         ret = SUCCESS;
    1745            3042 :                         break;
    1746                 :                 }
    1747               3 :                 if (type == IS_UNICODE) {
    1748               3 :                         ZVAL_ASCII_STRINGL(retval_ptr, intern->file_name.s, intern->file_name_len, 1);
    1749               3 :                         ret = SUCCESS;
    1750               3 :                         break;
    1751                 :                 }
    1752               0 :                 ZVAL_NULL(retval_ptr);
    1753               0 :                 ret = FAILURE;
    1754               0 :                 break;
    1755                 :         case SPL_FS_DIR:
    1756            1351 :                 if (type == IS_STRING) {
    1757            1342 :                         ZVAL_STRING(retval_ptr, intern->u.dir.entry.d_name, 1);
    1758            1342 :                         ret = SUCCESS;
    1759            1342 :                         break;
    1760                 :                 }
    1761               9 :                 if (type == IS_UNICODE) {
    1762               9 :                         ZVAL_ASCII_STRING(retval_ptr, intern->u.dir.entry.d_name, 1);
    1763               9 :                         ret = SUCCESS;
    1764               9 :                         break;
    1765                 :                 }
    1766                 :         default:
    1767               0 :                 ZVAL_NULL(retval_ptr);
    1768               0 :                 ret = FAILURE;
    1769                 :                 break;          
    1770                 :         }
    1771            4408 :         if (readobj == writeobj) {
    1772               1 :                 zval_dtor(readobj);
    1773                 :         }
    1774            4408 :         ZVAL_ZVAL(writeobj, retval_ptr, 0, 0);
    1775            4408 :         return ret;
    1776                 : }
    1777                 : /* }}} */
    1778                 : 
    1779                 : /* {{{ declare method parameters */
    1780                 : /* supply a name and default to call by parameter */
    1781                 : ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0) 
    1782                 :         ZEND_ARG_INFO(0, file_name)
    1783                 : ZEND_END_ARG_INFO()
    1784                 : 
    1785                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_openFile, 0, 0, 0)
    1786                 :         ZEND_ARG_INFO(0, open_mode)
    1787                 :         ZEND_ARG_INFO(0, use_include_path)
    1788                 :         ZEND_ARG_INFO(0, context)
    1789                 : ZEND_END_ARG_INFO()
    1790                 : 
    1791                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_optinalFileClass, 0, 0, 0)
    1792                 :         ZEND_ARG_INFO(0, class_name)
    1793                 : ZEND_END_ARG_INFO()
    1794                 : 
    1795                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0)
    1796                 :         ZEND_ARG_INFO(0, suffix)
    1797                 : ZEND_END_ARG_INFO()
    1798                 : 
    1799                 : ZEND_BEGIN_ARG_INFO(arginfo_splfileinfo_void, 0)
    1800                 : ZEND_END_ARG_INFO()
    1801                 : 
    1802                 : /* the method table */
    1803                 : /* each method can have its own parameters and visibility */
    1804                 : static const zend_function_entry spl_SplFileInfo_functions[] = {
    1805                 :         SPL_ME(SplFileInfo,       __construct,   arginfo_info___construct, ZEND_ACC_PUBLIC)
    1806                 :         SPL_ME(SplFileInfo,       getPath,       arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1807                 :         SPL_ME(SplFileInfo,       getFilename,   arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1808                 :         SPL_ME(SplFileInfo,       getBasename,   arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
    1809                 :         SPL_ME(SplFileInfo,       getPathname,   arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1810                 :         SPL_ME(SplFileInfo,       getPerms,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1811                 :         SPL_ME(SplFileInfo,       getInode,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1812                 :         SPL_ME(SplFileInfo,       getSize,       arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1813                 :         SPL_ME(SplFileInfo,       getOwner,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1814                 :         SPL_ME(SplFileInfo,       getGroup,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1815                 :         SPL_ME(SplFileInfo,       getATime,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1816                 :         SPL_ME(SplFileInfo,       getMTime,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1817                 :         SPL_ME(SplFileInfo,       getCTime,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1818                 :         SPL_ME(SplFileInfo,       getType,       arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1819                 :         SPL_ME(SplFileInfo,       isWritable,    arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1820                 :         SPL_ME(SplFileInfo,       isReadable,    arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1821                 :         SPL_ME(SplFileInfo,       isExecutable,  arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1822                 :         SPL_ME(SplFileInfo,       isFile,        arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1823                 :         SPL_ME(SplFileInfo,       isDir,         arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1824                 :         SPL_ME(SplFileInfo,       isLink,        arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1825                 :         SPL_ME(SplFileInfo,       getLinkTarget, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1826                 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
    1827                 :         SPL_ME(SplFileInfo,       getRealPath,   arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1828                 : #endif
    1829                 :         SPL_ME(SplFileInfo,       getFileInfo,   arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1830                 :         SPL_ME(SplFileInfo,       getPathInfo,   arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1831                 :         SPL_ME(SplFileInfo,       openFile,      arginfo_info_openFile,         ZEND_ACC_PUBLIC)
    1832                 :         SPL_ME(SplFileInfo,       setFileClass,  arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1833                 :         SPL_ME(SplFileInfo,       setInfoClass,  arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
    1834                 :         SPL_MA(SplFileInfo,       __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1835                 :         {NULL, NULL, NULL}
    1836                 : };
    1837                 : 
    1838                 : ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) 
    1839                 :         ZEND_ARG_INFO(0, path)
    1840                 : ZEND_END_ARG_INFO()
    1841                 : 
    1842                 : ZEND_BEGIN_ARG_INFO(arginfo_dir_it_seek, 0) 
    1843                 :         ZEND_ARG_INFO(0, position)
    1844                 : ZEND_END_ARG_INFO();
    1845                 : 
    1846                 : 
    1847                 : /* the method table */
    1848                 : /* each method can have its own parameters and visibility */
    1849                 : static const zend_function_entry spl_DirectoryIterator_functions[] = {
    1850                 :         SPL_ME(DirectoryIterator, __construct,   arginfo_dir___construct, ZEND_ACC_PUBLIC)
    1851                 :         SPL_ME(DirectoryIterator, getFilename,   arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1852                 :         SPL_ME(DirectoryIterator, getBasename,   arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
    1853                 :         SPL_ME(DirectoryIterator, isDot,         arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1854                 :         SPL_ME(DirectoryIterator, rewind,        arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1855                 :         SPL_ME(DirectoryIterator, valid,         arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1856                 :         SPL_ME(DirectoryIterator, key,           arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1857                 :         SPL_ME(DirectoryIterator, current,       arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1858                 :         SPL_ME(DirectoryIterator, next,          arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1859                 :         SPL_ME(DirectoryIterator, seek,          arginfo_dir_it_seek, ZEND_ACC_PUBLIC)
    1860                 :         SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1861                 :         {NULL, NULL, NULL}
    1862                 : };
    1863                 : 
    1864                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1) 
    1865                 :         ZEND_ARG_INFO(0, path)
    1866                 :         ZEND_ARG_INFO(0, flags)
    1867                 : ZEND_END_ARG_INFO()
    1868                 : 
    1869                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_hasChildren, 0, 0, 0)
    1870                 :         ZEND_ARG_INFO(0, allow_links)
    1871                 : ZEND_END_ARG_INFO()
    1872                 : 
    1873                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_setFlags, 0, 0, 0)
    1874                 :         ZEND_ARG_INFO(0, flags)
    1875                 : ZEND_END_ARG_INFO()
    1876                 : 
    1877                 : static const zend_function_entry spl_FilesystemIterator_functions[] = {
    1878                 :         SPL_ME(FilesystemIterator, __construct,   arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
    1879                 :         SPL_ME(FilesystemIterator, rewind,        arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1880                 :         SPL_ME(DirectoryIterator,  next,          arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1881                 :         SPL_ME(FilesystemIterator, key,           arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1882                 :         SPL_ME(FilesystemIterator, current,       arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1883                 :         SPL_ME(FilesystemIterator, getFlags,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1884                 :         SPL_ME(FilesystemIterator, setFlags,      arginfo_r_dir_setFlags, ZEND_ACC_PUBLIC)
    1885                 :         {NULL, NULL, NULL}
    1886                 : };
    1887                 : 
    1888                 : static const zend_function_entry spl_RecursiveDirectoryIterator_functions[] = {
    1889                 :         SPL_ME(RecursiveDirectoryIterator, __construct,   arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
    1890                 :         SPL_ME(RecursiveDirectoryIterator, hasChildren,   arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC)
    1891                 :         SPL_ME(RecursiveDirectoryIterator, getChildren,   arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1892                 :         SPL_ME(RecursiveDirectoryIterator, getSubPath,    arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1893                 :         SPL_ME(RecursiveDirectoryIterator, getSubPathname,arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    1894                 :         {NULL, NULL, NULL}
    1895                 : };
    1896                 : 
    1897                 : static const zend_function_entry spl_GlobIterator_functions[] = {
    1898                 :         SPL_ME(GlobIterator, __construct,   arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
    1899                 :         SPL_ME(GlobIterator, count,         arginfo_splfileinfo_void,  ZEND_ACC_PUBLIC)
    1900                 :         {NULL, NULL, NULL}
    1901                 : };
    1902                 : /* }}} */
    1903                 : 
    1904                 : static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    1905              80 : {
    1906                 :         char *buf;
    1907              80 :         size_t line_len = 0;
    1908              80 :         long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;
    1909                 : 
    1910              80 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    1911                 :         
    1912              80 :         if (php_stream_eof(intern->u.file.stream)) {
    1913               2 :                 if (!silent) {
    1914               0 :                         zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
    1915                 :                 }
    1916               2 :                 return FAILURE;
    1917                 :         }
    1918                 : 
    1919              78 :         if (intern->u.file.max_line_len > 0) {
    1920               1 :                 buf = safe_emalloc((intern->u.file.max_line_len + 1), sizeof(char), 0);
    1921               1 :                 if (php_stream_get_line(intern->u.file.stream, ZSTR(buf), intern->u.file.max_line_len, &line_len) == NULL) {
    1922               0 :                         efree(buf);
    1923               0 :                         buf = NULL;
    1924                 :                 } else {
    1925               1 :                         buf[line_len] = '\0';
    1926                 :                 }
    1927                 :         } else {
    1928              77 :                 buf = php_stream_get_line(intern->u.file.stream, NULL_ZSTR, 0, &line_len);
    1929                 :         }
    1930                 : 
    1931              78 :         if (!buf) {
    1932               2 :                 intern->u.file.current_line = estrdup("");
    1933               2 :                 intern->u.file.current_line_len = 0;
    1934                 :         } else {
    1935              76 :                 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) {
    1936              36 :                         line_len = strcspn(buf, "\r\n");
    1937              36 :                         buf[line_len] = '\0';
    1938                 :                 }
    1939                 :         
    1940              76 :                 intern->u.file.current_line = buf;
    1941              76 :                 intern->u.file.current_line_len = line_len;
    1942                 :         }
    1943              78 :         intern->u.file.current_line_num += line_add;
    1944                 : 
    1945              78 :         return SUCCESS;
    1946                 : } /* }}} */
    1947                 : 
    1948                 : static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function *func_ptr, int pass_num_args, zval *return_value, zval *arg2 TSRMLS_DC) /* {{{ */
    1949               3 : {
    1950                 :         zend_fcall_info fci;
    1951                 :         zend_fcall_info_cache fcic;
    1952                 :         zval z_fname;
    1953               3 :         zval * zresource_ptr = &intern->u.file.zresource, *retval;
    1954                 :         int result;
    1955               3 :         int num_args = pass_num_args + (arg2 ? 2 : 1);
    1956                 : 
    1957               3 :         zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0);
    1958                 : 
    1959               3 :         params[0] = &zresource_ptr;
    1960                 :         
    1961               3 :         if (arg2) {
    1962               1 :                 params[1] = &arg2;
    1963                 :         }
    1964                 : 
    1965               3 :         zend_get_parameters_array_ex(pass_num_args, params+(arg2 ? 2 : 1));
    1966                 : 
    1967               3 :         ZVAL_STRING(&z_fname, func_ptr->common.function_name.s, 0);
    1968                 : 
    1969               3 :         fci.size = sizeof(fci);
    1970               3 :         fci.function_table = EG(function_table);
    1971               3 :         fci.object_ptr = NULL;
    1972               3 :         fci.function_name = &z_fname;
    1973               3 :         fci.retval_ptr_ptr = &retval;
    1974               3 :         fci.param_count = num_args;
    1975               3 :         fci.params = params;
    1976               3 :         fci.no_separation = 1;
    1977               3 :         fci.symbol_table = NULL;
    1978                 : 
    1979               3 :         fcic.initialized = 1;
    1980               3 :         fcic.function_handler = func_ptr;
    1981               3 :         fcic.calling_scope = NULL;
    1982               3 :         fcic.called_scope = NULL;
    1983               3 :         fcic.object_ptr = NULL;
    1984                 : 
    1985               3 :         result = zend_call_function(&fci, &fcic TSRMLS_CC);
    1986                 :         
    1987               3 :         ZVAL_ZVAL(return_value, retval, 1, 1);
    1988                 : 
    1989               3 :         efree(params);
    1990               3 :         return result;
    1991                 : } /* }}} */
    1992                 : 
    1993                 : #define FileFunctionCall(func_name, pass_num_args, arg2) /* {{{ */\
    1994                 : { \
    1995                 :         zend_function *func_ptr; \
    1996                 :         int ret; \
    1997                 :         ret = zend_ascii_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \
    1998                 :         if (ret != SUCCESS) { \
    1999                 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Internal error, function '%s' not found. Please report", #func_name); \
    2000                 :                 return; \
    2001                 :         } \
    2002                 :         spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \
    2003                 : } /* }}} */
    2004                 : 
    2005                 : static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, char escape, zval *return_value TSRMLS_DC) /* {{{ */
    2006              18 : {
    2007              18 :         int ret = SUCCESS;
    2008                 :         
    2009                 :         do {
    2010              19 :                 ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC);
    2011              19 :         } while (ret == SUCCESS && !intern->u.file.current_line_len && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY));
    2012                 :         
    2013              18 :         if (ret == SUCCESS) {
    2014              18 :                 size_t buf_len = intern->u.file.current_line_len;
    2015              18 :                 char *buf = estrndup(intern->u.file.current_line, buf_len);
    2016                 : 
    2017              18 :                 if (intern->u.file.current_zval) {
    2018               0 :                         zval_ptr_dtor(&intern->u.file.current_zval);
    2019                 :                 }
    2020              18 :                 ALLOC_INIT_ZVAL(intern->u.file.current_zval);
    2021                 : 
    2022              18 :                 php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
    2023              18 :                 if (return_value) {
    2024              12 :                         if (Z_TYPE_P(return_value) != IS_NULL) {
    2025               0 :                                 zval_dtor(return_value);
    2026               0 :                                 ZVAL_NULL(return_value);
    2027                 :                         }
    2028              12 :                         ZVAL_ZVAL(return_value, intern->u.file.current_zval, 1, 0);
    2029                 :                 }
    2030                 :         }
    2031              18 :         return ret;
    2032                 : }
    2033                 : /* }}} */
    2034                 : 
    2035                 : static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    2036              59 : {
    2037              59 :         zval *retval = NULL;
    2038                 : 
    2039                 :         /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */
    2040              59 :         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) {
    2041              10 :                 if (php_stream_eof(intern->u.file.stream)) {
    2042               1 :                         if (!silent) {
    2043               0 :                                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
    2044                 :                         }
    2045               1 :                         return FAILURE;
    2046                 :                 }
    2047               9 :                 if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) {
    2048               6 :                         return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL TSRMLS_CC);
    2049                 :                 } else {
    2050               3 :                         zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
    2051                 :                 }
    2052               3 :                 if (retval) {
    2053               3 :                         if (intern->u.file.current_line || intern->u.file.current_zval) {
    2054               3 :                                 intern->u.file.current_line_num++;
    2055                 :                         }
    2056               3 :                         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2057               3 :                         if (Z_TYPE_P(retval) == IS_STRING) {
    2058               0 :                                 intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
    2059               0 :                                 intern->u.file.current_line_len = Z_STRLEN_P(retval);
    2060                 :                         } else {
    2061               3 :                                 MAKE_STD_ZVAL(intern->u.file.current_zval);
    2062               3 :                                 ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0);
    2063                 :                         }
    2064               3 :                         zval_ptr_dtor(&retval);
    2065               3 :                         return SUCCESS;
    2066                 :                 } else {
    2067               0 :                         return FAILURE;
    2068                 :                 }
    2069                 :         } else {
    2070              49 :                 return spl_filesystem_file_read(intern, silent TSRMLS_CC);
    2071                 :         }
    2072                 : } /* }}} */
    2073                 : 
    2074                 : static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
    2075              13 : {
    2076              13 :         if (intern->u.file.current_line) {
    2077              13 :                 return intern->u.file.current_line_len == 0;
    2078               0 :         } else if (intern->u.file.current_zval) {
    2079               0 :                 switch(Z_TYPE_P(intern->u.file.current_zval)) {
    2080                 :                 case IS_STRING:
    2081                 :                 case IS_UNICODE:
    2082               0 :                         return Z_STRLEN_P(intern->u.file.current_zval) == 0;
    2083                 :                 case IS_ARRAY:
    2084               0 :                         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)
    2085                 :                         && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) {
    2086               0 :                                 zval ** first = Z_ARRVAL_P(intern->u.file.current_zval)->pListHead->pData;
    2087                 :                                         
    2088               0 :                                 return (Z_TYPE_PP(first) == IS_STRING || Z_TYPE_PP(first) == IS_UNICODE)
    2089                 :                                         && Z_STRLEN_PP(first) == 0;
    2090                 :                         }
    2091               0 :                         return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0;
    2092                 :                 case IS_NULL:
    2093               0 :                         return 1;
    2094                 :                 default:
    2095               0 :                         return 0;
    2096                 :                 }
    2097                 :         } else {
    2098               0 :                 return 1;
    2099                 :         }
    2100                 : }
    2101                 : /* }}} */
    2102                 : 
    2103                 : static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
    2104              58 : {
    2105              58 :         int ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
    2106                 : 
    2107             117 :         while (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY) && ret == SUCCESS && spl_filesystem_file_is_empty_line(intern TSRMLS_CC)) {
    2108               1 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
    2109               1 :                 ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
    2110                 :         }
    2111                 :         
    2112              58 :         return ret;
    2113                 : }
    2114                 : /* }}} */
    2115                 : 
    2116                 : static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
    2117              17 : {
    2118              17 :         if (-1 == php_stream_rewind(intern->u.file.stream)) {
    2119               0 :                 zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name);
    2120                 :         } else {
    2121              17 :                 spl_filesystem_file_free_line(intern TSRMLS_CC);
    2122              17 :                 intern->u.file.current_line_num = 0;
    2123                 :         }
    2124              17 :         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
    2125               2 :                 spl_filesystem_file_read_line(this_ptr, intern, 1 TSRMLS_CC);
    2126                 :         }
    2127              17 : } /* }}} */
    2128                 : 
    2129                 : /* {{{ proto void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path  [, resource context]]]]) U
    2130                 :    Construct a new file object */
    2131                 : SPL_METHOD(SplFileObject, __construct)
    2132              41 : {
    2133              41 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2134              41 :         zend_bool use_include_path = 0;
    2135                 :         zstr p1, p2;
    2136                 :         char *tmp_path;
    2137                 :         int   tmp_path_len;
    2138                 :         zend_error_handling error_handling;
    2139                 : 
    2140              41 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
    2141                 : 
    2142              41 :         intern->u.file.open_mode = "r";
    2143              41 :         intern->u.file.open_mode_len = 1;
    2144                 : 
    2145              41 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|sbr", 
    2146                 :                         &intern->file_name, &intern->file_name_len, &intern->file_name_type,
    2147                 :                         &intern->u.file.open_mode, &intern->u.file.open_mode_len, 
    2148                 :                         &use_include_path, &intern->u.file.zcontext) == FAILURE) {
    2149               0 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
    2150               0 :                 return;
    2151                 :         }
    2152                 :         
    2153              41 :         if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) {
    2154              41 :                 tmp_path_len  = strlen(intern->u.file.stream->orig_path);
    2155                 : 
    2156              41 :                 if (tmp_path_len > 1 && IS_SLASH_AT(IS_STRING, ZSTR(intern->u.file.stream->orig_path), tmp_path_len-1)) {
    2157               1 :                         tmp_path_len--;
    2158                 :                 }
    2159                 : 
    2160              41 :                 tmp_path = estrndup(intern->u.file.stream->orig_path, tmp_path_len);
    2161                 : 
    2162              41 :                 p1.s = strrchr(tmp_path, '/');
    2163                 : #if defined(PHP_WIN32) || defined(NETWARE)
    2164                 :                 p2.s = strrchr(tmp_path, '\\');
    2165                 : #else
    2166              41 :                 p2.v = 0;
    2167                 : #endif
    2168                 : 
    2169              82 :                 if (p1.v || p2.v) {
    2170              41 :                         intern->_path_len = (p1.s > p2.s ? p1.s : p2.s) - tmp_path;
    2171                 :                 } else {
    2172               0 :                         intern->_path_len = 0;
    2173                 :                 }
    2174                 : 
    2175              41 :                 efree(tmp_path);
    2176                 : 
    2177              41 :                 intern->_path      = ZSTR(estrndup(intern->u.file.stream->orig_path, intern->_path_len));
    2178              41 :                 intern->_path_type = IS_STRING;
    2179                 :         }
    2180                 : 
    2181              41 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    2182                 : } /* }}} */
    2183                 : 
    2184                 : /* {{{ proto void SplTempFileObject::__construct([int max_memory]) U
    2185                 :    Construct a new temp file object */
    2186                 : SPL_METHOD(SplTempFileObject, __construct)
    2187               0 : {
    2188               0 :         long max_memory = PHP_STREAM_MAX_MEM;
    2189                 :         char tmp_fname[48];
    2190               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2191                 :         zend_error_handling error_handling;
    2192                 : 
    2193               0 :         zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
    2194                 : 
    2195               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &max_memory) == FAILURE) {
    2196               0 :                 zend_restore_error_handling(&error_handling TSRMLS_CC);
    2197               0 :                 return;
    2198                 :         }
    2199                 : 
    2200               0 :         if (max_memory < 0) {
    2201               0 :                 intern->file_name_type = IS_STRING;
    2202               0 :                 intern->file_name.s = "php://memory";
    2203               0 :                 intern->file_name_len = 12;
    2204               0 :         } else if (ZEND_NUM_ARGS()) {
    2205               0 :                 intern->file_name_type = IS_STRING;
    2206               0 :                 intern->file_name_len = snprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory);
    2207               0 :                 intern->file_name.s = tmp_fname;
    2208                 :         } else {
    2209               0 :                 intern->file_name_type = IS_STRING;
    2210               0 :                 intern->file_name.s = "php://temp";
    2211               0 :                 intern->file_name_len = 10;
    2212                 :         }
    2213               0 :         intern->u.file.open_mode = "wb";
    2214               0 :         intern->u.file.open_mode_len = 1;
    2215               0 :         intern->u.file.zcontext = NULL;
    2216                 :         
    2217               0 :         if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) {
    2218               0 :                 intern->_path_type = IS_STRING;
    2219               0 :                 intern->_path_len = 0;
    2220               0 :                 intern->_path.s = estrndup("", 0);
    2221                 :         }
    2222               0 :         zend_restore_error_handling(&error_handling TSRMLS_CC);
    2223                 : } /* }}} */
    2224                 : 
    2225                 : /* {{{ proto void SplFileObject::rewind() U
    2226                 :    Rewind the file and read the first line */
    2227                 : SPL_METHOD(SplFileObject, rewind)
    2228              13 : {
    2229              13 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2230                 : 
    2231              13 :         spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
    2232              13 : } /* }}} */
    2233                 : 
    2234                 : /* {{{ proto void SplFileObject::eof() U
    2235                 :    Return whether end of file is reached */
    2236                 : SPL_METHOD(SplFileObject, eof)
    2237              39 : {
    2238              39 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2239                 : 
    2240              39 :         RETURN_BOOL(php_stream_eof(intern->u.file.stream));
    2241                 : } /* }}} */
    2242                 : 
    2243                 : /* {{{ proto void SplFileObject::valid() U
    2244                 :    Return !eof() */
    2245                 : SPL_METHOD(SplFileObject, valid)
    2246              45 : {
    2247              45 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2248                 : 
    2249              45 :         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
    2250              14 :                 RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval);
    2251                 :         } else {
    2252              31 :                 RETVAL_BOOL(!php_stream_eof(intern->u.file.stream));
    2253                 :         }
    2254                 : } /* }}} */
    2255                 : 
    2256                 : /* {{{ proto string SplFileObject::fgets() U
    2257                 :    Rturn next line from file */
    2258                 : SPL_METHOD(SplFileObject, fgets)
    2259              12 : {
    2260              12 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2261                 : 
    2262              12 :         if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) {
    2263               0 :                 RETURN_FALSE;
    2264                 :         }
    2265              12 :         RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
    2266                 : } /* }}} */
    2267                 : 
    2268                 : /* {{{ proto string SplFileObject::current() U
    2269                 :    Return current line from file */
    2270                 : SPL_METHOD(SplFileObject, current)
    2271              42 : {
    2272              42 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2273                 : 
    2274              42 :         if (!intern->u.file.current_line && !intern->u.file.current_zval) {
    2275              28 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    2276                 :         }
    2277              42 :         if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) {
    2278              33 :                 RETURN_RT_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, ZSTR_DUPLICATE);
    2279               9 :         } else if (intern->u.file.current_zval) {
    2280               9 :                 RETURN_ZVAL(intern->u.file.current_zval, 1, 0);
    2281                 :         }
    2282               0 :         RETURN_FALSE;
    2283                 : } /* }}} */
    2284                 : 
    2285                 : /* {{{ proto int SplFileObject::key() U
    2286                 :    Return line number */
    2287                 : SPL_METHOD(SplFileObject, key)
    2288              79 : {
    2289              79 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2290                 : 
    2291                 : /*      Do not read the next line to support correct counting with fgetc()
    2292                 :         if (!intern->current_line) {
    2293                 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    2294                 :         } */
    2295              79 :         RETURN_LONG(intern->u.file.current_line_num);
    2296                 : } /* }}} */
    2297                 : 
    2298                 : /* {{{ proto void SplFileObject::next() U
    2299                 :    Read next line */
    2300                 : SPL_METHOD(SplFileObject, next)
    2301              38 : {
    2302              38 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2303                 : 
    2304              38 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2305              38 :         if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
    2306              12 :                 spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
    2307                 :         }
    2308              38 :         intern->u.file.current_line_num++;
    2309              38 : } /* }}} */
    2310                 : 
    2311                 : /* {{{ proto void SplFileObject::setFlags(int flags) U
    2312                 :    Set file handling flags */
    2313                 : SPL_METHOD(SplFileObject, setFlags)
    2314               5 : {
    2315               5 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2316                 : 
    2317               5 :         zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags);
    2318               5 : } /* }}} */
    2319                 : 
    2320                 : /* {{{ proto int SplFileObject::getFlags() U
    2321                 :    Get file handling flags */
    2322                 : SPL_METHOD(SplFileObject, getFlags)
    2323               0 : {
    2324               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2325                 : 
    2326               0 :         RETURN_LONG(intern->flags & SPL_FILE_OBJECT_MASK);
    2327                 : } /* }}} */
    2328                 : 
    2329                 : /* {{{ proto void SplFileObject::setMaxLineLen(int max_len) U
    2330                 :    Set maximum line length */
    2331                 : SPL_METHOD(SplFileObject, setMaxLineLen)
    2332               2 : {
    2333                 :         long max_len;
    2334                 : 
    2335               2 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2336                 : 
    2337               2 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_len) == FAILURE) {
    2338               0 :                 return;
    2339                 :         }
    2340                 : 
    2341               2 :         if (max_len < 0) {
    2342               0 :                 zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero");
    2343               0 :                 return;
    2344                 :         }
    2345                 :         
    2346               2 :         intern->u.file.max_line_len = max_len;
    2347                 : } /* }}} */
    2348                 : 
    2349                 : /* {{{ proto int SplFileObject::getMaxLineLen() U
    2350                 :    Get maximum line length */
    2351                 : SPL_METHOD(SplFileObject, getMaxLineLen)
    2352               1 : {
    2353               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2354                 : 
    2355               1 :         RETURN_LONG((long)intern->u.file.max_line_len);
    2356                 : } /* }}} */
    2357                 : 
    2358                 : /* {{{ proto bool SplFileObject::hasChildren() U
    2359                 :    Return false */
    2360                 : SPL_METHOD(SplFileObject, hasChildren)
    2361               0 : {
    2362               0 :         RETURN_FALSE;
    2363                 : } /* }}} */
    2364                 : 
    2365                 : /* {{{ proto bool SplFileObject::getChildren() U
    2366                 :    Read NULL */
    2367                 : SPL_METHOD(SplFileObject, getChildren)
    2368               0 : {
    2369                 :         /* return NULL */
    2370               0 : } /* }}} */
    2371                 : 
    2372                 : /* {{{ FileFunction */
    2373                 : #define FileFunction(func_name) \
    2374                 : SPL_METHOD(SplFileObject, func_name) \
    2375                 : { \
    2376                 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
    2377                 :         FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \
    2378                 : }
    2379                 : /* }}} */
    2380                 : 
    2381                 : /* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string enclosure [, escape = '\\']]]) U
    2382                 :    Return current line as csv */
    2383                 : SPL_METHOD(SplFileObject, fgetcsv)
    2384              12 : {
    2385              12 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2386              12 :         char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure, escape = intern->u.file.escape;
    2387              12 :         char *delim = NULL, *enclo = NULL, *esc = NULL;
    2388              12 :         int d_len = 0, e_len = 0, esc_len = 0;
    2389                 :         
    2390              12 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
    2391              12 :                 switch(ZEND_NUM_ARGS())
    2392                 :                 {
    2393                 :                 case 3:
    2394               0 :                         if (esc_len != 1) {
    2395               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
    2396               0 :                                 RETURN_FALSE;
    2397                 :                         }
    2398               0 :                         escape = esc[0];
    2399                 :                         /* no break */
    2400                 :                 case 2:
    2401               6 :                         if (e_len != 1) {
    2402               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
    2403               0 :                                 RETURN_FALSE;
    2404                 :                         }
    2405               6 :                         enclosure = enclo[0];
    2406                 :                         /* no break */
    2407                 :                 case 1:
    2408               6 :                         if (d_len != 1) {
    2409               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
    2410               0 :                                 RETURN_FALSE;
    2411                 :                         }
    2412               6 :                         delimiter = delim[0];
    2413                 :                         /* no break */
    2414                 :                 case 0:
    2415                 :                         break;
    2416                 :                 }
    2417              12 :                 spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value TSRMLS_CC);
    2418                 :         }
    2419                 : }
    2420                 : /* }}} */
    2421                 : 
    2422                 : /* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"' [, string escape = '\\']]])
    2423                 :    Set the delimiter and enclosure character used in fgetcsv */
    2424                 : SPL_METHOD(SplFileObject, setCsvControl)
    2425               0 : {
    2426               0 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2427               0 :         char delimiter = ',', enclosure = '"', escape='\\';
    2428               0 :         char *delim = NULL, *enclo = NULL, *esc = NULL;
    2429               0 :         int d_len = 0, e_len = 0, esc_len = 0;
    2430                 :         
    2431               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
    2432               0 :                 switch(ZEND_NUM_ARGS())
    2433                 :                 {
    2434                 :                 case 3:
    2435               0 :                         if (esc_len != 1) {
    2436               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
    2437               0 :                                 RETURN_FALSE;
    2438                 :                         }
    2439               0 :                         escape = esc[0];
    2440                 :                         /* no break */
    2441                 :                 case 2:
    2442               0 :                         if (e_len != 1) {
    2443               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
    2444               0 :                                 RETURN_FALSE;
    2445                 :                         }
    2446               0 :                         enclosure = enclo[0];
    2447                 :                         /* no break */
    2448                 :                 case 1:
    2449               0 :                         if (d_len != 1) {
    2450               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
    2451               0 :                                 RETURN_FALSE;
    2452                 :                         }
    2453               0 :                         delimiter = delim[0];
    2454                 :                         /* no break */
    2455                 :                 case 0:
    2456                 :                         break;
    2457                 :                 }
    2458               0 :                 intern->u.file.delimiter = delimiter;
    2459               0 :                 intern->u.file.enclosure = enclosure;
    2460               0 :                 intern->u.file.escape    = escape;
    2461                 :         }
    2462                 : }
    2463                 : /* }}} */
    2464                 : 
    2465                 : /* {{{ proto array SplFileObject::getCsvControl() U
    2466                 :    Get the delimiter and enclosure character used in fgetcsv */
    2467                 : SPL_METHOD(SplFileObject, getCsvControl)
    2468               1 : {
    2469               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2470                 :         char delimiter[2], enclosure[2];
    2471                 : 
    2472               1 :         array_init(return_value);
    2473                 :         
    2474               1 :         delimiter[0] = intern->u.file.delimiter;
    2475               1 :         delimiter[1] = '\0';
    2476               1 :         enclosure[0] = intern->u.file.enclosure;
    2477               1 :         enclosure[1] = '\0';
    2478                 : 
    2479               1 :         add_next_index_ascii_string(return_value, delimiter, ZSTR_DUPLICATE);
    2480               1 :         add_next_index_ascii_string(return_value, enclosure, ZSTR_DUPLICATE);
    2481               1 : }
    2482                 : /* }}} */
    2483                 : 
    2484                 : /* {{{ proto bool SplFileObject::flock(int operation [, int &wouldblock])
    2485                 :    Portable file locking */
    2486               0 : FileFunction(flock)
    2487                 : /* }}} */
    2488                 : 
    2489                 : /* {{{ proto bool SplFileObject::fflush() U
    2490                 :    Flush the file */
    2491                 : SPL_METHOD(SplFileObject, fflush)
    2492               2 : {
    2493               2 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2494                 : 
    2495               2 :         RETURN_BOOL(!php_stream_flush(intern->u.file.stream));
    2496                 : } /* }}} */
    2497                 : 
    2498                 : /* {{{ proto int SplFileObject::ftell() U
    2499                 :    Return current file position */
    2500                 : SPL_METHOD(SplFileObject, ftell)
    2501               5 : {
    2502               5 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);      
    2503               5 :         long ret = php_stream_tell(intern->u.file.stream);
    2504                 : 
    2505               5 :         if (ret == -1) {
    2506               0 :                 RETURN_FALSE;
    2507                 :         } else {
    2508               5 :                 RETURN_LONG(ret);
    2509                 :         }
    2510                 : } /* }}} */
    2511                 : 
    2512                 : /* {{{ proto int SplFileObject::fseek(int pos [, int whence = SEEK_SET]) U
    2513                 :    Return current file position */
    2514                 : SPL_METHOD(SplFileObject, fseek)
    2515               3 : {
    2516               3 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2517               3 :         long pos, whence = SEEK_SET;
    2518                 : 
    2519               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pos, &whence) == FAILURE) {
    2520               2 :                 return;
    2521                 :         }
    2522                 : 
    2523               1 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2524               1 :         RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence));
    2525                 : } /* }}} */
    2526                 : 
    2527                 : /* {{{ proto int SplFileObject::fgetc() U
    2528                 :    Get a character form the file */
    2529                 : SPL_METHOD(SplFileObject, fgetc)
    2530              25 : {
    2531              25 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2532                 :         char buf[2];
    2533                 :         int result;
    2534                 : 
    2535              25 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2536                 : 
    2537              25 :         result = php_stream_getc(intern->u.file.stream);
    2538                 : 
    2539              25 :         if (result == EOF) {
    2540               2 :                 RETVAL_FALSE;
    2541                 :         } else {
    2542              23 :                 if (result == '\n') {
    2543              11 :                         intern->u.file.current_line_num++;
    2544                 :                 }
    2545              23 :                 buf[0] = result;
    2546              23 :                 buf[1] = '\0';
    2547                 : 
    2548              23 :                 RETURN_RT_STRINGL(buf, 1, ZSTR_DUPLICATE);
    2549                 :         }
    2550                 : } /* }}} */
    2551                 : 
    2552                 : /* {{{ proto string SplFileObject::fgetss([string allowable_tags]) U
    2553                 :    Get a line from file pointer and strip HTML tags */
    2554                 : SPL_METHOD(SplFileObject, fgetss)
    2555               1 : {
    2556               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2557               1 :         zval *arg2 = NULL;
    2558               1 :         MAKE_STD_ZVAL(arg2);
    2559                 : 
    2560               1 :         if (intern->u.file.max_line_len > 0) {
    2561               0 :                 ZVAL_LONG(arg2, intern->u.file.max_line_len);
    2562                 :         } else {
    2563               1 :                 ZVAL_LONG(arg2, 1024);
    2564                 :         }
    2565                 : 
    2566               1 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2567               1 :         intern->u.file.current_line_num++;
    2568                 : 
    2569               1 :         FileFunctionCall(fgetss, ZEND_NUM_ARGS(), arg2);
    2570                 : 
    2571               1 :         zval_ptr_dtor(&arg2);
    2572                 : } /* }}} */
    2573                 : 
    2574                 : /* {{{ proto int SplFileObject::fpassthru() U
    2575                 :    Output all remaining data from a file pointer */
    2576                 : SPL_METHOD(SplFileObject, fpassthru)
    2577               1 : {
    2578               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2579                 : 
    2580               1 :         RETURN_LONG(php_stream_passthru(intern->u.file.stream));
    2581                 : } /* }}} */
    2582                 : 
    2583                 : /* {{{ proto bool SplFileObject::fscanf(string format [, string ...]) U
    2584                 :    Implements a mostly ANSI compatible fscanf() */
    2585                 : SPL_METHOD(SplFileObject, fscanf)
    2586               1 : {
    2587               1 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2588                 : 
    2589               1 :         spl_filesystem_file_free_line(intern TSRMLS_CC);
    2590               1 :         intern->u.file.current_line_num++;
    2591                 : 
    2592               1 :         FileFunctionCall(fscanf, ZEND_NUM_ARGS(), NULL);
    2593                 : }
    2594                 : /* }}} */
    2595                 : 
    2596                 : /* {{{ proto mixed SplFileObject::fwrite(string str [, int length]) U
    2597                 :    Binary-safe file write */
    2598                 : SPL_METHOD(SplFileObject, fwrite)
    2599               6 : {
    2600               6 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2601                 :         char *str;
    2602                 :         int str_len;
    2603               6 :         long length = 0;
    2604                 : 
    2605               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &length) == FAILURE) {
    2606               2 :                 return;
    2607                 :         }
    2608                 : 
    2609               4 :         if (ZEND_NUM_ARGS() > 1) {
    2610               2 :                 str_len = MAX(0, MIN(length, str_len));
    2611                 :         }
    2612               4 :         if (!str_len) {
    2613               0 :                 RETURN_LONG(0);
    2614                 :         }
    2615                 : 
    2616               4 :         RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
    2617                 : } /* }}} */
    2618                 : 
    2619                 : /* {{{ proto bool SplFileObject::fstat()
    2620                 :    Stat() on a filehandle */
    2621               1 : FileFunction(fstat)
    2622                 : /* }}} */
    2623                 : 
    2624                 : /* {{{ proto bool SplFileObject::ftruncate(int size) U
    2625                 :    Truncate file to 'size' length */
    2626                 : SPL_METHOD(SplFileObject, ftruncate)
    2627               3 : {
    2628               3 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2629                 :         long size;
    2630                 :         
    2631               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) {
    2632               1 :                 return;
    2633                 :         }
    2634                 : 
    2635               2 :         if (!php_stream_truncate_supported(intern->u.file.stream)) {
    2636               1 :                 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name);
    2637               1 :                 RETURN_FALSE;
    2638                 :         }
    2639                 :         
    2640               1 :         RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size));
    2641                 : } /* }}} */
    2642                 : 
    2643                 : /* {{{ proto void SplFileObject::seek(int line_pos)
    2644                 :    Seek to specified line */
    2645                 : SPL_METHOD(SplFileObject, seek)
    2646               7 : {
    2647               7 :         spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
    2648                 :         long line_pos;
    2649                 :         
    2650               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) {
    2651               2 :                 return;
    2652                 :         }
    2653               5 :         if (line_pos < 0) {
    2654               1 :                 zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos);
    2655               1 :                 RETURN_FALSE;           
    2656                 :         }
    2657                 :         
    2658               4 :         spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
    2659                 :         
    2660              23 :         while(intern->u.file.current_line_num < line_pos) {
    2661              16 :                 if (spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC) == FAILURE) {
    2662               1 :                         break;
    2663                 :                 }
    2664                 :         }
    2665                 : } /* }}} */
    2666                 : 
    2667                 : /* {{{ Function/Class/Method definitions */
    2668                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object___construct, 0, 0, 1)
    2669                 :         ZEND_ARG_INFO(0, file_name)
    2670                 :         ZEND_ARG_INFO(0, open_mode)
    2671                 :         ZEND_ARG_INFO(0, use_include_path)
    2672                 :         ZEND_ARG_INFO(0, context)
    2673                 : ZEND_END_ARG_INFO()
    2674                 : 
    2675                 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setFlags, 0)
    2676                 :         ZEND_ARG_INFO(0, flags)
    2677                 : ZEND_END_ARG_INFO()
    2678                 : 
    2679                 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setMaxLineLen, 0)
    2680                 :         ZEND_ARG_INFO(0, max_len)
    2681                 : ZEND_END_ARG_INFO()
    2682                 : 
    2683                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetcsv, 0, 0, 0)
    2684                 :         ZEND_ARG_INFO(0, delimiter)
    2685                 :         ZEND_ARG_INFO(0, enclosure)
    2686                 : ZEND_END_ARG_INFO()
    2687                 : 
    2688                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1) 
    2689                 :         ZEND_ARG_INFO(0, operation)
    2690                 :         ZEND_ARG_INFO(1, wouldblock)
    2691                 : ZEND_END_ARG_INFO()
    2692                 : 
    2693                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1) 
    2694                 :         ZEND_ARG_INFO(0, pos)
    2695                 :         ZEND_ARG_INFO(0, whence)
    2696                 : ZEND_END_ARG_INFO()
    2697                 : 
    2698                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) 
    2699                 :         ZEND_ARG_INFO(0, allowable_tags)
    2700                 : ZEND_END_ARG_INFO()
    2701                 : 
    2702                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1)
    2703                 :         ZEND_ARG_INFO(0, format)
    2704                 :         ZEND_ARG_INFO(1, ...)
    2705                 : ZEND_END_ARG_INFO()
    2706                 : 
    2707                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) 
    2708                 :         ZEND_ARG_INFO(0, str)
    2709                 :         ZEND_ARG_INFO(0, length)
    2710                 : ZEND_END_ARG_INFO()
    2711                 : 
    2712                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1) 
    2713                 :         ZEND_ARG_INFO(0, size)
    2714                 : ZEND_END_ARG_INFO()
    2715                 : 
    2716                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1) 
    2717                 :         ZEND_ARG_INFO(0, line_pos)
    2718                 : ZEND_END_ARG_INFO()
    2719                 : 
    2720                 : static const zend_function_entry spl_SplFileObject_functions[] = {
    2721                 :         SPL_ME(SplFileObject, __construct,    arginfo_file_object___construct,   ZEND_ACC_PUBLIC)
    2722                 :         SPL_ME(SplFileObject, rewind,         arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2723                 :         SPL_ME(SplFileObject, eof,            arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2724                 :         SPL_ME(SplFileObject, valid,          arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2725                 :         SPL_ME(SplFileObject, fgets,          arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2726                 :         SPL_ME(SplFileObject, fgetcsv,        arginfo_file_object_fgetcsv,       ZEND_ACC_PUBLIC)
    2727                 :         SPL_ME(SplFileObject, setCsvControl,  arginfo_file_object_fgetcsv,       ZEND_ACC_PUBLIC)
    2728                 :         SPL_ME(SplFileObject, getCsvControl,  arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2729                 :         SPL_ME(SplFileObject, flock,          arginfo_file_object_flock,         ZEND_ACC_PUBLIC)
    2730                 :         SPL_ME(SplFileObject, fflush,         arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2731                 :         SPL_ME(SplFileObject, ftell,          arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2732                 :         SPL_ME(SplFileObject, fseek,          arginfo_file_object_fseek,         ZEND_ACC_PUBLIC)
    2733                 :         SPL_ME(SplFileObject, fgetc,          arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2734                 :         SPL_ME(SplFileObject, fpassthru,      arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2735                 :         SPL_ME(SplFileObject, fgetss,         arginfo_file_object_fgetss,        ZEND_ACC_PUBLIC)
    2736                 :         SPL_ME(SplFileObject, fscanf,         arginfo_file_object_fscanf,        ZEND_ACC_PUBLIC)
    2737                 :         SPL_ME(SplFileObject, fwrite,         arginfo_file_object_fwrite,        ZEND_ACC_PUBLIC)
    2738                 :         SPL_ME(SplFileObject, fstat,          arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2739                 :         SPL_ME(SplFileObject, ftruncate,      arginfo_file_object_ftruncate,     ZEND_ACC_PUBLIC)
    2740                 :         SPL_ME(SplFileObject, current,        arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2741                 :         SPL_ME(SplFileObject, key,            arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2742                 :         SPL_ME(SplFileObject, next,           arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2743                 :         SPL_ME(SplFileObject, setFlags,       arginfo_file_object_setFlags,      ZEND_ACC_PUBLIC)
    2744                 :         SPL_ME(SplFileObject, getFlags,       arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2745                 :         SPL_ME(SplFileObject, setMaxLineLen,  arginfo_file_object_setMaxLineLen, ZEND_ACC_PUBLIC)
    2746                 :         SPL_ME(SplFileObject, getMaxLineLen,  arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2747                 :         SPL_ME(SplFileObject, hasChildren,    arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2748                 :         SPL_ME(SplFileObject, getChildren,    arginfo_splfileinfo_void,          ZEND_ACC_PUBLIC)
    2749                 :         SPL_ME(SplFileObject, seek,           arginfo_file_object_seek,          ZEND_ACC_PUBLIC)
    2750                 :         /* mappings */
    2751                 :         SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets,      arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    2752                 :         SPL_MA(SplFileObject, __toString,     SplFileObject, current,    arginfo_splfileinfo_void, ZEND_ACC_PUBLIC)
    2753                 :         {NULL, NULL, NULL}
    2754                 : };
    2755                 : 
    2756                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_temp_file_object___construct, 0, 0, 0)
    2757                 :         ZEND_ARG_INFO(0, max_memory)
    2758                 : ZEND_END_ARG_INFO()
    2759                 : 
    2760                 : static const zend_function_entry spl_SplTempFileObject_functions[] = {
    2761                 :         SPL_ME(SplTempFileObject, __construct, arginfo_temp_file_object___construct,  ZEND_ACC_PUBLIC)
    2762                 :         {NULL, NULL, NULL}
    2763                 : };
    2764                 : /* }}} */
    2765                 : 
    2766                 : /* {{{ PHP_MINIT_FUNCTION(spl_directory)
    2767                 :  */
    2768                 : PHP_MINIT_FUNCTION(spl_directory)
    2769           17007 : {
    2770           17007 :         u_charsToUChars("glob://", u_glob, sizeof("glob://"));
    2771                 : 
    2772           17007 :         REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_SplFileInfo_functions);
    2773           17007 :         memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    2774           17007 :         spl_filesystem_object_handlers.clone_obj      = spl_filesystem_object_clone;
    2775           17007 :         spl_filesystem_object_handlers.cast_object    = spl_filesystem_object_cast;
    2776           17007 :         spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info;
    2777           17007 :         spl_ce_SplFileInfo->serialize = zend_class_serialize_deny;
    2778           17007 :         spl_ce_SplFileInfo->unserialize = zend_class_unserialize_deny;
    2779                 : 
    2780           17007 :         REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions);
    2781           17007 :         zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator);
    2782           17007 :         REGISTER_SPL_IMPLEMENTS(DirectoryIterator, SeekableIterator);
    2783                 : 
    2784           17007 :         spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator;
    2785                 : 
    2786           17007 :         REGISTER_SPL_SUB_CLASS_EX(FilesystemIterator, DirectoryIterator, spl_filesystem_object_new, spl_FilesystemIterator_functions);
    2787                 : 
    2788           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_MODE_MASK",   SPL_FILE_DIR_CURRENT_MODE_MASK);
    2789           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_PATHNAME", SPL_FILE_DIR_CURRENT_AS_PATHNAME);
    2790           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_FILEINFO", SPL_FILE_DIR_CURRENT_AS_FILEINFO);
    2791           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_SELF",     SPL_FILE_DIR_CURRENT_AS_SELF);
    2792           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_MODE_MASK",       SPL_FILE_DIR_KEY_MODE_MASK);
    2793           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_PATHNAME",     SPL_FILE_DIR_KEY_AS_PATHNAME);
    2794           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "FOLLOW_SYMLINKS",     SPL_FILE_DIR_FOLLOW_SYMLINKS);
    2795           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_FILENAME",     SPL_FILE_DIR_KEY_AS_FILENAME);
    2796           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "NEW_CURRENT_AND_KEY", SPL_FILE_DIR_KEY_AS_FILENAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO);
    2797           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "SKIP_DOTS",           SPL_FILE_DIR_SKIPDOTS);
    2798           17007 :         REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "UNIX_PATHS",          SPL_FILE_DIR_UNIXPATHS);
    2799                 : 
    2800           17007 :         spl_ce_FilesystemIterator->get_iterator = spl_filesystem_tree_get_iterator;
    2801                 : 
    2802           17007 :         REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, FilesystemIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions);
    2803           17007 :         REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator);
    2804                 : 
    2805           17007 :         REGISTER_SPL_SUB_CLASS_EX(GlobIterator, FilesystemIterator, spl_filesystem_object_new, spl_GlobIterator_functions);
    2806           17007 :         REGISTER_SPL_IMPLEMENTS(GlobIterator, Countable);
    2807                 : 
    2808           17007 :         REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new, spl_SplFileObject_functions);
    2809           17007 :         REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator);
    2810           17007 :         REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator);
    2811                 : 
    2812           17007 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "DROP_NEW_LINE", SPL_FILE_OBJECT_DROP_NEW_LINE);
    2813           17007 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_AHEAD",    SPL_FILE_OBJECT_READ_AHEAD);
    2814           17007 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY",    SPL_FILE_OBJECT_SKIP_EMPTY);
    2815           17007 :         REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV",      SPL_FILE_OBJECT_READ_CSV);
    2816                 :         
    2817           17007 :         REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new, spl_SplTempFileObject_functions);
    2818           17007 :         return SUCCESS;
    2819                 : }
    2820                 : /* }}} */
    2821                 : 
    2822                 : /*
    2823                 :  * Local variables:
    2824                 :  * tab-width: 4
    2825                 :  * c-basic-offset: 4
    2826                 :  * End:
    2827                 :  * vim600: noet sw=4 ts=4 fdm=marker
    2828                 :  * vim<600: noet sw=4 ts=4
    2829                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:39 +0000 (36 hours ago)

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