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-21 Instrumented lines: 1116
Code covered: 82.2 % Executed lines: 917
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

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

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