Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions class-readcsv.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/

class ReadCSV {
const field_start = 0;
const unquoted_field = 1;
const quoted_field = 2;
const found_quote = 3;
const found_cr_q = 4;
const found_cr = 5;
protected $field_start = 0;
protected $unquoted_field = 1;
protected $quoted_field = 2;
protected $found_quote = 3;
protected $found_cr_q = 4;
protected $found_cr = 5;

private $file;
private $sep;
Expand Down Expand Up @@ -72,12 +72,12 @@ public function get_row() {

$row=array();
$field="";
$state=self::field_start;
$state=$this->field_start;

while (1) {
$char = $this->next_char();

if ($state == self::quoted_field) {
if ($state == $this->quoted_field) {
if ($char === FALSE) {
// EOF. (TODO: error case - no closing quote)
$row[]=$field;
Expand All @@ -86,64 +86,64 @@ public function get_row() {
// Fall through to accumulate quoted chars in switch() {...}
} elseif ($char === FALSE || $char == "\n") {
// End of record.
// (TODO: error case if $state==self::field_start here - trailing comma)
// (TODO: error case if $state==$this->field_start here - trailing comma)
$row[] = $field;
return $row;
} elseif ($char == "\r") {
// Possible start of \r\n line end, but might be just part of foo\rbar
$state = ($state == self::found_quote)? self::found_cr_q: self::found_cr;
$state = ($state == $this->found_quote)? $this->found_cr_q: $this->found_cr;
continue;
} elseif ($char == $this->sep &&
($state == self::field_start ||
$state == self::found_quote ||
$state == self::unquoted_field)) {
($state == $this->field_start ||
$state == $this->found_quote ||
$state == $this->unquoted_field)) {
// End of current field, start of next field
$row[]=$field;
$field="";
$state=self::field_start;
$state=$this->field_start;
continue;
}

switch ($state) {

case self::field_start:
case $this->field_start:
if ($char == '"')
$state = self::quoted_field;
$state = $this->quoted_field;
else {
$state = self::unquoted_field;
$state = $this->unquoted_field;
$field .= $char;
}
break;

case self::quoted_field:
case $this->quoted_field:
if ($char == '"')
$state = self::found_quote;
$state = $this->found_quote;
else
$field .= $char;
break;

case self::unquoted_field:
case $this->unquoted_field:
$field .= $char;
// (TODO: error case if '"' in middle of unquoted field)
break;

case self::found_quote:
case $this->found_quote:
// Found '"' escape sequence
$field .= $char;
$state = self::quoted_field;
$state = $this->quoted_field;
// (TODO: error case if $char!='"' - non-separator char after single quote)
break;

case self::found_cr:
case $this->found_cr:
// Lone \rX instead of \r\n. Treat as literal \rX. (TODO: error case?)
$field .= "\r".$char;
$state = self::unquoted_field;
$state = $this->unquoted_field;
break;

case self::found_cr_q:
case $this->found_cr_q:
// (TODO: error case: "foo"\rX instead of "foo"\r\n or "foo"\n)
$field .= "\r".$char;
$state = self::quoted_field;
$state = $this->quoted_field;
break;
}
}
Expand Down
Loading