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

Generated by: LTP GCOV extension version 1.5

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

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