Diffs
CSV_Iterator/trunk/tests/src/CSV/CSV_IteratorTest.php
@@ -21,26 +21,15 @@
}
/**
- * @todo Implement testRewind().
+ * @dataProvider constructData
*/
- public function testRewind() {
- // Remove the following lines when you implement this test.
- $this->markTestIncomplete(
- 'This test has not been implemented yet.'
- );
+ public function testRewind($file, $encoding, $delimiter, $enclosure, $expected) {
+ $obj = new CSV_Iterator(realpath(dirname(__FILE__) . '/../../fixtures/' . $file), $encoding, $delimiter, $enclosure);
+ $obj->rewind();
+ $this->assertEquals(current($expected), $obj->current());
}
/**
- * @todo Implement testNext().
- */
- public function testNext() {
- // Remove the following lines when you implement this test.
- $this->markTestIncomplete(
- 'This test has not been implemented yet.'
- );
- }
-
- /**
* @dataProvider constructData
*/
public function testCurrent($file, $encoding, $delimiter, $enclosure, $expected) {
@@ -49,26 +38,6 @@
}
/**
- * @todo Implement testKey().
- */
- public function testKey() {
- // Remove the following lines when you implement this test.
- $this->markTestIncomplete(
- 'This test has not been implemented yet.'
- );
- }
-
- /**
- * @todo Implement testValid().
- */
- public function testValid() {
- // Remove the following lines when you implement this test.
- $this->markTestIncomplete(
- 'This test has not been implemented yet.'
- );
- }
-
- /**
* @todo Implement testSetRowLength().
*/
public function testSetRowLength() {
@@ -139,7 +108,6 @@
)),
array('withHeaderWithoutEOLatEOF.csv', 'ascii', ',', '"', array(
array('header1'=>'value1', 'header2'=>'value2'),
- array('header1'=>'value3', 'header2'=>'value4'),
)),
);
}
CSV_Iterator/trunk/tests/fixtures/withHeaderWithoutEOLatEOF.csv
@@ -1,3 +1,2 @@
header1,header2
-value1,value2
-value3,value4
\ ファイルの末尾に改行がありません
+value1,value2
\ ファイルの末尾に改行がありません
CSV_Iterator/trunk/src/CSV/Iterator.php
@@ -30,7 +30,7 @@
$this->enclosure = mb_convert_encoding($enclosure, 'utf-8');
$this->setRowLength($rowlength);
- $this->filePointer = fopen($file, 'r');
+ $this->filePointer = fopen($file, 'rb');
$this->_setEncoding($encoding);
$this->setOutputEncoding($outputEncoding);
@@ -42,19 +42,18 @@
public function rewind()
{
fseek($this->filePointer, $this->offset);
+ $this->rowCounter = -1;
$this->next();
- $this->rowCounter = 0;
}
public function next()
{
-
+ ++$this->rowCounter;
$data = $this->readRow();
if($data!==null && count($data)!==count($this->header)) {
- throw new RuntimeException('CSV parse error. Number of columns is not equal to number of header.');
+ throw new RuntimeException('CSV parse error. Number of columns is not equal to number of header at row #'. $this->rowCounter .'.' . var_export(array($data, $this->header), true));
}
$this->currentRow = $data ? array_combine($this->header, $data) : null;
- ++$this->rowCounter;
}
public function current()
@@ -96,10 +95,10 @@
// また、マルチバイト関係で安全に処理するために、文字エンコーディングを一旦UTF-8にする
while (!feof($this->filePointer)) {
// $line .= mb_convert_encoding(call_user_func_array('fgets', $arg), 'utf-8', $this->encoding);
- $line .= mb_convert_encoding(call_user_func_array('stream_get_line', $arg), 'utf-8', $this->encoding);
+// $line .= mb_convert_encoding(call_user_func_array('stream_get_line', $arg), 'utf-8', $this->encoding);
+ $line .= mb_convert_encoding(self::getLine($this->filePointer, $this->rowLength, $this->eol), 'utf-8', $this->encoding);
$itemcnt = preg_match_all('/'.$e.'/u', $line, $dummy);
if ($itemcnt % 2 == 0) break;
- $line .= "\xd\xa";
}
$csv_line = preg_replace('/(?:\r\n|[\r\n])?$/u', $d, trim($line));
@@ -159,5 +158,33 @@
{
$this->outputEncoding = strtoupper($encoding)==='UTF-8' ? null : $encoding;
}
+
+ /**
+ * stream_get_lineにバグがあるため仕方なく作った
+ *
+ * @see http://bugs.php.net/bug.php?id=49148
+ * @param resource $fp ファイルポインタ
+ * @param int $buf_size 最大サイズ
+ * @param string $eol 行区切り
+ * @return string 1行分の文字
+ */
+ static public function getLine($fp, $buf_size, $eol)
+ {
+ $ret = '';
+ $eol_len = strlen($eol);
+ $eol_pos = 0;
+ if(!$buf_size) $buf_size = PHP_INT_MAX;
+ while(($c = fgetc($fp))!==false && strlen($ret) < $buf_size) {
+ $ret .= $c;
+ if($c === $eol[$eol_pos]) {
+ if(++$eol_pos === $eol_len) {
+ break;
+ }
+ continue;
+ }
+ $eol_pos = 0;
+ }
+ return $ret;
+ }
}
?>