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