Continued CSV parsing:
[core.git] / inc / classes / main / file_directories / text / input / csv / class_CsvInputFile.php
index b6c8d5e631a636ed9a6d56924af3f865de209e39..0c4c5a25f6568a256126927b262138bb04df466a 100644 (file)
@@ -51,6 +51,121 @@ class CsvInputFile extends BaseInputTextFile implements CsvInputStreamer {
                // Return the prepared instance
                return $fileInstance;
        }
                // 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]
 }
 
 // [EOF]