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

Reply via email to