Annotation of embedaddon/php/ext/spl/spl_directory.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>