* @version 0.0.0 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team * @license GNU GPL 3.0 or any newer version * @link http://www.ship-simu.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ class CsvInputFile extends BaseInputTextFile implements CsvInputStreamer { /** * Protected constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); } /** * Creates an instance of this File class and prepares it for usage * * @param $fileName Name of the index file * @return $fileInstance An instance of this File class */ public final static function createCsvInputFile ($fileName) { // Get a new instance $fileInstance = new CsvInputFile(); // Set file name $fileInstance->setFileName($fileName); // Init this abstract file $fileInstance->initFile($fileName); // Return the prepared instance return $fileInstance; } /** * Reads a line from CSV file and returns it as an indexed array. Please * note that strings *must* be always in double-quotes, else any found * column separators will be parsed or they may be interpreted incorrectly. * * @param $columnSeparator Character to use separting columns * @return $lineArray An indexed array with the read line */ public function readCsvFileLine ($columnSeparator) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] columnSeparator=%s - CALLED!', __METHOD__, __LINE__, $columnSeparator)); // Read raw line $data = $this->getPointerInstance()->readLine(); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] data()=%s', __METHOD__, __LINE__, strlen($data))); // Parse data $lineArray = $this->parseDataToIndexedArray($data, $columnSeparator); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] lineArray()=%s - EXIT!', __METHOD__, __LINE__, count($lineArray))); // Return it return $lineArray; } /** * Parses given data into an array * * @param $data Raw data e.g. returned from readLine() * @param $columnSeparator Character to use separting columns * @return $lineArray An indexed array with the read line */ private function parseDataToIndexedArray ($data, $columnSeparator) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] data()=%s,columnSeparator=%s - CALLED!', __METHOD__, __LINE__, strlen($data), $columnSeparator)); // Init return array $lineArray = array(); // Whether the parser reads a quoted string (which may contain the column separator again) $isInQuotes = FALSE; // Init column data $column = ''; // Now parse the line for ($idx = 0; $idx < strlen($data); $idx++) { // "Cache" char $char = substr($data, $idx, 1); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] idx=%s,char=%s ...', __METHOD__, __LINE__, $idx, $char)); // Is the column separator found and not within quotes? if (($isInQuotes === FALSE) && ($char == $columnSeparator)) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Adding column=%s ...', __METHOD__, __LINE__, $column)); // Add this line to the array array_push($lineArray, $column); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] lineArray()=%s - After add!', __METHOD__, __LINE__, count($lineArray))); // Clear variable ... $column = ''; // ... and skip it continue; } elseif ($char == chr(34)) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] column=%s ...', __METHOD__, __LINE__, $column)); // $column must be empty at this point if we are at starting quote assert(($isInQuotes === TRUE) || (empty($column))); // Double-quote found, so flip variable $isInQuotes = (!$isInQuotes); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInQuotes=%d ...', __METHOD__, __LINE__, intval($isInQuotes))); // Skip double-quote (escaping of them is not yet supported) continue; } // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Adding char=%s ...', __METHOD__, __LINE__, $idx, $char)); // Add char to column $column .= $char; } // END - for // Is there something outstanding? if (!empty($column)) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Adding column=%s ...', __METHOD__, __LINE__, $column)); // Then don't forget this. :-) array_push($lineArray, $column); // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] lineArray()=%s - After add!', __METHOD__, __LINE__, count($lineArray))); } // END - if // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] lineArray()=%s - EXIT!', __METHOD__, __LINE__, count($lineArray))); // Return it return $lineArray; } } // [EOF] ?>