helly Tue May 3 18:18:19 2005 EDT Added files: /php-src/ext/spl/tests fileobject_002.phpt
Modified files: /php-src/ext/spl spl_directory.c /php-src/ext/spl/internal fileobject.inc Log: - Make line counting work with FileObject::fgetc() - Add a test for FileObject::fgetc() - Update docs
http://cvs.php.net/diff.php/php-src/ext/spl/spl_directory.c?r1=1.43&r2=1.44&ty=u Index: php-src/ext/spl/spl_directory.c diff -u php-src/ext/spl/spl_directory.c:1.43 php-src/ext/spl/spl_directory.c:1.44 --- php-src/ext/spl/spl_directory.c:1.43 Tue May 3 17:11:24 2005 +++ php-src/ext/spl/spl_directory.c Tue May 3 18:18:19 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.c,v 1.43 2005/05/03 21:11:24 helly Exp $ */ +/* $Id: spl_directory.c,v 1.44 2005/05/03 22:18:19 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -872,19 +872,14 @@ static void spl_file_object_free_line(spl_file_object *intern TSRMLS_DC) /* {{{ */ { - long line_add = 0; - if (intern->current_line) { efree(intern->current_line); intern->current_line = NULL; - line_add = 1; } if (intern->current_zval) { zval_ptr_dtor(&intern->current_zval); intern->current_zval = NULL; - line_add = 1; } - intern->current_line_num += line_add; } /* }}} */ static void spl_file_object_free_storage(void *object TSRMLS_DC) /* {{{ */ @@ -944,7 +939,10 @@ char *buf; size_t line_len; int len; + long line_add = (intern->current_line || intern->current_zval) ? 1 : 0; + spl_file_object_free_line(intern TSRMLS_CC); + if (php_stream_eof(intern->stream)) { if (!silent) { zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name); @@ -954,8 +952,6 @@ buf = php_stream_get_line(intern->stream, NULL, intern->max_line_len, &line_len); - spl_file_object_free_line(intern TSRMLS_CC); - if (!buf) { intern->current_line = estrdup(""); intern->current_line_len = 0; @@ -973,18 +969,28 @@ intern->current_line = buf; intern->current_line_len = line_len; } + intern->current_line_num += line_add; return SUCCESS; } /* }}} */ -static void spl_file_object_read_line(zval * this_ptr, spl_file_object *intern, int silent TSRMLS_DC) /* {{{ */ +static int spl_file_object_read_line(zval * this_ptr, spl_file_object *intern, int silent TSRMLS_DC) /* {{{ */ { zval *retval; /* if overloaded call the function, otherwise do it directly */ if (intern->func_getCurr->common.scope != spl_ce_FileObject) { + if (php_stream_eof(intern->stream)) { + if (!silent) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name); + } + return FAILURE; + } zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), &intern->func_getCurr, "getCurrentLine", &retval); if (retval) { + if (intern->current_line || intern->current_zval) { + intern->current_line_num++; + } spl_file_object_free_line(intern TSRMLS_CC); if (Z_TYPE_P(retval) == IS_STRING) { intern->current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); @@ -994,9 +1000,12 @@ ZVAL_ZVAL(intern->current_zval, retval, 1, 0); } zval_ptr_dtor(&retval); + return SUCCESS; + } else { + return FAILURE; } } else { - spl_file_object_read(intern, silent TSRMLS_CC); + return spl_file_object_read(intern, silent TSRMLS_CC); } } /* }}} */ @@ -1134,9 +1143,10 @@ { spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); +/* Do not read the next line to support correct counting with fgetc() if (!intern->current_line) { spl_file_object_read_line(getThis(), intern, 1 TSRMLS_CC); - } + } */ RETURN_LONG(intern->current_line_num); } /* }}} */ @@ -1147,6 +1157,7 @@ spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_file_object_free_line(intern TSRMLS_CC); + intern->current_line_num++; } /* }}} */ /* {{{ proto void FileObject::setFlags(int flags) @@ -1279,6 +1290,7 @@ ZVAL_LONG(arg2, intern->max_line_len); spl_file_object_free_line(intern TSRMLS_CC); + intern->current_line_num++; FileFunctionCall(fgetcsv, arg2); @@ -1338,11 +1350,16 @@ char buf[2]; int result; + spl_file_object_free_line(intern TSRMLS_CC); + result = php_stream_getc(intern->stream); if (result == EOF) { RETVAL_FALSE; } else { + if (result == '\n') { + intern->current_line_num++; + } buf[0] = result; buf[1] = '\0'; @@ -1360,6 +1377,7 @@ ZVAL_LONG(arg2, intern->max_line_len); spl_file_object_free_line(intern TSRMLS_CC); + intern->current_line_num++; FileFunctionCall(fgetss, arg2); @@ -1382,6 +1400,7 @@ spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_file_object_free_line(intern TSRMLS_CC); + intern->current_line_num++; FileFunctionCall(fscanf, NULL); } http://cvs.php.net/diff.php/php-src/ext/spl/internal/fileobject.inc?r1=1.1&r2=1.2&ty=u Index: php-src/ext/spl/internal/fileobject.inc diff -u php-src/ext/spl/internal/fileobject.inc:1.1 php-src/ext/spl/internal/fileobject.inc:1.2 --- php-src/ext/spl/internal/fileobject.inc:1.1 Thu Apr 14 17:02:09 2005 +++ php-src/ext/spl/internal/fileobject.inc Tue May 3 18:18:19 2005 @@ -15,7 +15,7 @@ * @version 1.0 * @since PHP 5.1 */ -class FileObject implements RecursiveIterator +class FileObject implements RecursiveIterator, SeekableIterator { private $fp; private $fname; @@ -65,6 +65,7 @@ */ function fgets() { + $this->freeLine(); $this->lnum++; $buf = fgets($this->fp, $this->max_len); @@ -77,6 +78,7 @@ */ function fgetcsv($delimiter = ';', $enclosure = '') { + $this->freeLine(); $this->lnum++; return fgetcsv($this->fp, $this->max_len, $delimiter, $enclosure); } @@ -122,7 +124,11 @@ */ function fgetc() { - return fgetc($this->fp); + $this->freeLine(); + $c = fgetc($this->fp); + if ($c == '\n') { + $this->lnum++; + } } /** Read and return remaining part of stream @@ -146,6 +152,7 @@ */ function fscanf($format /* , ... */) { + $this->freeLine(); $this->lnum++; return fscanf($this->fp, $format /* , ... */); } @@ -228,7 +235,7 @@ */ function rewind() { - $this->line = NULL; + $this->freeLine(); $this->lnum = 0; } @@ -254,15 +261,13 @@ } /** - * @note Fill current line buffer if not done yet. * @return line number + * @note fgetc() will increase the line number when reaing a new line char. + * This has the effect key() called on a read a new line will already + * return the increased line number. */ function key() { - if (is_null($this->line)) - { - $line = getCurrentLine(); - } return $this->lnum; } @@ -270,7 +275,7 @@ */ function next() { - $this->line = NULL; + $this->freeLine(); } /** @@ -278,16 +283,41 @@ */ private function readLine() { - $this->lnum++; - return fgets($this->fp, $this->max_len); + if ($this->eof()) + { + $this->freeLine(); + throw new RuntimeException("Cannot read from file " . $this->fname); + } + if ($this->line) { + $this->lnum++; + } + $this->freeLine(); + $this->line = fgets($this->fp, $this->max_len); + return $this->line; + } + + /** + * Free the current line buffer and increment the line counter + */ + private function freeLine() + { + if ($this->line) { + $this->line = NULL; + } } /* - * @note if you overload this function key() and current() will increment - * $this->lnum. + * @note If you DO overload this function key() and current() will increment + * $this->lnum automatically. If not then function reaLine() will do + * that for you. */ function getCurrentLine() { + $this->freeLine(); + if ($this->eof()) + { + throw new RuntimeException("Cannot read from file " . $this->fname); + } $this->readLine(); } @@ -298,6 +328,18 @@ { return current(); } + + /** + * @param $line_pos Seek to this line + */ + function seek($line_pos) + { + $this->rewind(); + while($this->lnum < $line_pos && !$this->eof()) + { + $this->getCurrentLine(); + } + } } ?> http://cvs.php.net/co.php/php-src/ext/spl/tests/fileobject_002.phpt?r=1.1&p=1 Index: php-src/ext/spl/tests/fileobject_002.phpt +++ php-src/ext/spl/tests/fileobject_002.phpt --TEST-- SPL: FileObject::fgetc --FILE-- <?php function test($name) { echo "===$name===\n"; $o = new FileObject(dirname(__FILE__) . '/' . $name); var_dump($o->key()); while(($c = $o->fgetc()) !== false) { var_dump($o->key(), $c, $o->eof()); } echo "===EOF?===\n"; var_dump($o->eof()); var_dump($o->key()); var_dump($o->eof()); } test('fileobject_001a.txt'); test('fileobject_001b.txt'); ?> ===DONE=== <?php exit(0); ?> --EXPECT-- ===fileobject_001a.txt=== int(0) int(0) string(1) "0" bool(false) int(1) string(1) " " bool(false) int(1) string(1) "1" bool(false) int(2) string(1) " " bool(false) int(2) string(1) "2" bool(false) int(3) string(1) " " bool(false) int(3) string(1) "3" bool(false) int(4) string(1) " " bool(false) int(4) string(1) "4" bool(false) int(5) string(1) " " bool(false) int(5) string(1) "5" bool(false) int(6) string(1) " " bool(false) ===EOF?=== bool(true) int(6) bool(true) ===fileobject_001b.txt=== int(0) int(0) string(1) "0" bool(false) int(1) string(1) " " bool(false) int(1) string(1) "1" bool(false) int(2) string(1) " " bool(false) int(2) string(1) "2" bool(false) int(3) string(1) " " bool(false) int(3) string(1) "3" bool(false) int(4) string(1) " " bool(false) int(4) string(1) "4" bool(false) int(5) string(1) " " bool(false) int(5) string(1) "5" bool(false) ===EOF?=== bool(true) int(5) bool(true) ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php