Rewrote both file i/o classes to have a common BaseFileIo class.
authorRoland Haeder <roland@mxchange.org>
Wed, 14 May 2014 19:17:21 +0000 (21:17 +0200)
committerRoland Haeder <roland@mxchange.org>
Wed, 14 May 2014 19:17:21 +0000 (21:17 +0200)
Signed-off-by: Roland Häder <roland@mxchange.org>
14 files changed:
inc/classes/main/class_Base
inc/classes/main/io/class_BaseFileIo.php [new file with mode: 0644]
inc/classes/main/io/class_FileIoStream.php [deleted file]
inc/classes/main/io/class_FrameworkDirectoryPointer.php [deleted file]
inc/classes/main/io/class_FrameworkFileInputPointer.php [deleted file]
inc/classes/main/io/class_FrameworkFileOutputPointer.php [deleted file]
inc/classes/main/io/directory/.htaccess [new file with mode: 0644]
inc/classes/main/io/directory/class_FrameworkDirectoryPointer.php [new file with mode: 0644]
inc/classes/main/io/input/.htaccess [new file with mode: 0644]
inc/classes/main/io/input/class_FrameworkFileInputPointer.php [new file with mode: 0644]
inc/classes/main/io/io_handler/.htaccess [new file with mode: 0644]
inc/classes/main/io/io_handler/class_FileIoStream.php [new file with mode: 0644]
inc/classes/main/io/output/.htaccess [new file with mode: 0644]
inc/classes/main/io/output/class_FrameworkFileOutputPointer.php [new file with mode: 0644]

index cdef34a662a76cb0ca6f40f9d45fdbb9b608bbfb..992be1bf0e49069e6743f1b80f0df285c94321f3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * A general ???
+ * A general ??? class
  *
  * @author             Roland Haeder <webmaster@ship-simu.org>
  * @version            0.0.0
diff --git a/inc/classes/main/io/class_BaseFileIo.php b/inc/classes/main/io/class_BaseFileIo.php
new file mode 100644 (file)
index 0000000..a18a852
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+/**
+ * A general FileIo class
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 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 <http://www.gnu.org/licenses/>.
+ */
+class BaseFileIo extends BaseFrameworkSystem {
+       /**
+        * The current file we are working in
+        */
+       private $fileName = '';
+
+       /**
+        * The file pointer
+        */
+       private $filePointer = NULL;
+
+       /**
+        * Protected constructor
+        *
+        * @param       $className      Name of the class
+        * @return      void
+        */
+       protected function __construct ($className) {
+               // Call parent constructor
+               parent::__construct($className);
+       }
+
+       /**
+        * Destructor for cleaning purposes, etc
+        *
+        * @return      void
+        */
+       public final function __destruct() {
+               // Is there a resource pointer? Then we have to close the file here!
+               if (is_resource($this->getPointer())) {
+                       // Try to close a file
+                       $this->closeFile();
+               } // END - if
+
+               // Call the parent destructor
+               parent::__destruct();
+       }
+
+       /**
+        * Close a file source and set it's instance to null and the file name
+        * to empty
+        *
+        * @return      void
+        * @throws      NullPointerException    If the file pointer instance
+        *                                                                      is not set by setPointer()
+        * @throws      InvalidResourceException        If there is being set
+        */
+       public function closeFile () {
+               if (is_null($this->getPointer())) {
+                       // Pointer not initialized
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               } elseif (!is_resource($this->getPointer())) {
+                       // Pointer is not a valid resource!
+                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
+               }
+
+               // Close the file pointer and reset the instance variable
+               @fclose($this->getPointer());
+               $this->setPointer(NULL);
+               $this->setFileName('');
+       }
+
+       /**
+        * Setter for the file pointer
+        *
+        * @param       $filePointer    File resource
+        * @return      void
+        */
+       public final function setPointer ($filePointer) {
+               $this->filePointer = $filePointer;
+       }
+
+       /**
+        * Getter for the file pointer
+        *
+        * @return      $filePointer    The file pointer which shall be a valid
+        *                                                      file resource
+        */
+       public final function getPointer () {
+               return $this->filePointer;
+       }
+
+       /**
+        * Setter for file name
+        *
+        * @param       $fileName       The new file name
+        * @return      void
+        */
+       public final function setFileName ($fileName) {
+               $fileName = (string) $fileName;
+               $this->fileName = $fileName;
+       }
+
+       /**
+        * Getter for file name
+        *
+        * @return      $fileName       The current file name
+        */
+       public final function getFileName () {
+               return $this->fileName;
+       }
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/io/class_FileIoStream.php b/inc/classes/main/io/class_FileIoStream.php
deleted file mode 100644 (file)
index 35d00ed..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-<?php
-/**
- * An universal class for file input/output streams.
- *
- * @author             Roland Haeder <webmaster@shipsimu.org>
- * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
- * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, FileOutputStreamer {
-       /**
-        * File header indicator
-        */
-       const FILE_IO_FILE_HEADER_ID = '@head';
-
-       /**
-        * Data block indicator
-        */
-       const FILE_IO_DATA_BLOCK_ID = '@data';
-
-       /**
-        * Separator #1
-        */
-       const FILE_IO_CHUNKER = ':';
-
-       /**
-        * Separator #2
-        */
-       const FILE_IO_SEPARATOR = '^';
-
-       /**
-        * Protected constructor
-        */
-       protected function __construct () {
-               // Call parent constructor
-               parent::__construct(__CLASS__);
-       }
-
-       /**
-        * Create a file IO stream. This is a class for performing all actions
-        * on files like creating, deleting and loading them.
-        *
-        * @return      $ioInstance     An instance of FileIoStream
-        */
-       public static final function createFileIoStream () {
-               // Create new instance
-               $ioInstance = new FileIoStream();
-
-               // Return the instance
-               return $ioInstance;
-       }
-
-       /**
-        * Saves data to a given local file and create missing directory structures
-        *
-        * @param       $fileName       The file name for the to be saved file
-        * @param       $dataArray      The data we shall store to the file
-        * @return      void
-        * @see         FileOutputStreamer
-        * @todo        This method needs heavy rewrite
-        */
-       public final function saveFile ($fileName, array $dataArray) {
-               // Try it five times
-               $dirName = ''; $fileInstance = NULL;
-               for ($idx = 0; $idx < 5; $idx++) {
-                       // Get a file output pointer
-                       try {
-                               $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fileName, 'w');
-                       } catch (FileIoException $e) {
-                               // Create missing directory
-                               $dirName = dirname($fileName);
-                               for ($idx2 = 0; $idx2 < (2 - $idx); $idx2++) {
-                                       $dirName = dirname($dirName);
-                               } // END - for
-
-                               // Try to create it
-                               @mkdir($dirName);
-                       }
-               } // END - for
-
-               // Write a header information for validation purposes
-               $fileInstance->writeToFile(sprintf("%s%s%s%s%s%s%s%s%s\n",
-                       self::FILE_IO_FILE_HEADER_ID,
-                       self::FILE_IO_SEPARATOR,
-                       $dataArray[0],
-                       self::FILE_IO_CHUNKER,
-                       time(),
-                       self::FILE_IO_CHUNKER,
-                       strlen($dataArray[1]),
-                       self::FILE_IO_CHUNKER,
-                       md5($dataArray[1])
-               ));
-
-               // Encode the (maybe) binary stream with Base64
-               $b64Stream = base64_encode($dataArray[1]);
-
-               // write the data line by line
-               $line = str_repeat(' ', 50); $idx = 0;
-               while (strlen($line) == 50) {
-                       // Get 50 chars or less
-                       $line = substr($b64Stream, $idx, 50);
-
-                       // Save it to the stream
-                       $fileInstance->writeToFile(sprintf("%s%s%s%s%s\n",
-                               self::FILE_IO_DATA_BLOCK_ID,
-                               self::FILE_IO_SEPARATOR,
-                               $line,
-                               self::FILE_IO_CHUNKER,
-                               md5($line)
-                       ));
-
-                       // Advance to the next 50-chars block
-                       $idx += 50;
-               } // END - while
-
-               // Close the file
-               $fileInstance->closeFile();
-       }
-
-       /**
-        * Reads from a local file
-        *
-        * @param               $fqfn   The full-qualified file-name which we shall load
-        * @return      $array  An array with the element 'header' and 'data'
-        * @see         FileInputStreamer
-        */
-       public final function loadFileContents ($fqfn) {
-               // Initialize some variables and arrays
-               $inputBuffer = '';
-               $lastBuffer = '';
-               $header = array();
-               $data = array();
-               $readData = ''; // This will contain our read data
-
-               // Get a file input handler
-               $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
-
-               // Read all it's contents (we very and transparently decompress it below)
-               while ($readRawLine = $fileInstance->readFromFile()) {
-                       // Add the read line to the buffer
-                       $inputBuffer .= $readRawLine;
-
-                       // Break infinite loop maybe caused by the input handler
-                       if ($lastBuffer == $inputBuffer) break;
-
-                       // Remember last read line for avoiding possible infinite loops
-                       $lastBuffer = $inputBuffer;
-               } // END - while
-
-               // Close directory handle
-               $fileInstance->closeFile();
-
-               // Convert it into an array
-               $inputBuffer = explode(chr(10), $inputBuffer);
-
-               // Now process the read lines and verify it's content
-               foreach ($inputBuffer as $rawLine) {
-                       // Trim it a little but not the leading spaces/tab-stops
-                       $rawLine = rtrim($rawLine);
-
-                       // Analyze this line
-                       if (substr($rawLine, 0, 5) == self::FILE_IO_FILE_HEADER_ID) {
-                               // Header found, so let's extract it
-                               $header = explode(self::FILE_IO_SEPARATOR, $rawLine);
-                               $header = trim($header[1]);
-
-                               // Now we must convert it again into an array
-                               $header = explode(self::FILE_IO_CHUNKER, $header);
-
-                               // Is the header (maybe) valid?
-                               if (count($header) != 4) {
-                                       // Throw an exception
-                                       throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
-                               } // END - if
-                       } elseif (substr($rawLine, 0, 5) == self::FILE_IO_DATA_BLOCK_ID) {
-                               // Is a data line!
-                               $data = explode(self::FILE_IO_SEPARATOR, $rawLine);
-                               $data = $data[1];
-
-                               // First element is the data, second the MD5 checksum
-                               $data = explode(self::FILE_IO_CHUNKER, $data);
-
-                               // Validate the read line
-                               if (count($data) == 2) {
-                                       if (md5($data[0]) != $data[1]) {
-                                               // MD5 hash did not match!
-                                               throw new InvalidMD5ChecksumException(array($this, md5($data[0]), $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
-                                       } // END - if
-                               } else {
-                                       // Invalid count!
-                                       throw new InvalidArrayCountException(array($this, 'data', count($data), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
-                               }
-
-                               // Add this to the readData string
-                               $readData .= $data[0];
-                       } else {
-                               // Other raw lines than header/data tagged lines and re-add the new-line char
-                               $readData .= $rawLine . PHP_EOL;
-                       }
-               } // END - foreach
-
-               // Was raw lines read and no header/data?
-               if ((!empty($readData)) && (count($header) == 0) && (count($data) == 0)) {
-                       // Return raw lines back
-                       return $readData;
-               } // END - if
-
-               // Was a header found?
-               if (count($header) != 4) {
-                       // Throw an exception
-                       throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
-               } // END - if
-
-               // Decode all from Base64
-               $readData = @base64_decode($readData);
-
-               // Does the size match?
-               if (strlen($readData) != $header[2]) {
-                       // Size did not match
-                       throw new InvalidDataLengthException(array($this, strlen($readData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
-               } // END - if
-
-               // Validate the decoded data with the final MD5 hash
-               if (md5($readData) != $header[3]) {
-                       // MD5 hash did not match!
-                       throw new InvalidMD5ChecksumException(array($this, md5($readData), $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
-               } // END - if
-
-               // Return all in an array
-               return array(
-                       'header' => $header,
-                       'data'   => $readData
-               );
-       }
-
-       /**
-        * Streams the data and maybe does something to it
-        *
-        * @param       $data   The data (string mostly) to "stream"
-        * @return      $data   The data (string mostly) to "stream"
-        * @throws      UnsupportedOperationException   If this method is called
-        */
-       public function streamData ($data) {
-               self::createDebugInstance(__CLASS__)->debugOutput('Unhandled ' . strlen($data) . ' bytes in this stream.');
-               throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
-       }
-}
-
-// [EOF]
-?>
diff --git a/inc/classes/main/io/class_FrameworkDirectoryPointer.php b/inc/classes/main/io/class_FrameworkDirectoryPointer.php
deleted file mode 100644 (file)
index da22040..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-<?php
-/**
- * A class for directory reading and getting its contents, no recursion!
- *
- * @author             Roland Haeder <webmaster@shipsimu.org>
- * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
- * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class FrameworkDirectoryPointer extends BaseFrameworkSystem {
-       /**
-        * The current path we are working in
-        */
-       private $pathName = '';
-
-       /**
-        * The directory iterator instance
-        */
-       private $directoryInstance = NULL;
-
-       /**
-        * Protected constructor
-        */
-       protected function __construct () {
-               // Call parent constructor
-               parent::__construct(__CLASS__);
-       }
-
-       /**
-        * Destructor for cleaning purposes, etc
-        */
-       public function __destruct() {
-               // Is there a resource pointer? Then we have to close the directory here!
-               if ($this->getDirectoryInstance() instanceof DirectoryIterator) {
-                       // Try to close a directory
-                       $this->closeDirectory();
-               } // END - if
-
-               // Call the parent destructor
-               parent::__destruct();
-       }
-
-       /**
-        * Create a directory pointer based on the given path. The path will also
-        * be verified here.
-        *
-        * @param       $pathName               The path name we shall pass to opendir()
-        * @param       $inConstructor  If we are in de/con-structor or from somewhere else
-        * @return      $pointerInstance        A prepared instance of FrameworkDirectoryPointer
-        * @throws      PathIsEmptyException    If the provided path name is empty
-        * @throws      InvalidPathStringException      If the provided path name is not a string
-        * @throws      PathIsNoDirectoryException      If the provided path name is not valid
-        * @throws      PathReadProtectedException      If the provided path name is read-protected
-        * @todo        Get rid of inConstructor, could be old-lost code.
-        */
-       public static final function createFrameworkDirectoryPointer ($pathName, $inConstructor = FALSE) {
-               // Some pre-sanity checks...
-               if (is_null($pathName)) {
-                       // No pathname given
-                       if ($inConstructor) {
-                               return NULL;
-                       } else {
-                               throw new PathIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
-                       }
-               } elseif (!is_string($pathName)) {
-                       // Is not a string
-                       if ($inConstructor) {
-                               return NULL;
-                       } else {
-                               throw new InvalidPathStringException(NULL, self::EXCEPTION_INVALID_STRING);
-                       }
-               } elseif (!is_dir($pathName)) {
-                       // Not a directory
-                       if ($inConstructor) {
-                               return NULL;
-                       } else {
-                               throw new PathIsNoDirectoryException($pathName, self::EXCEPTION_INVALID_PATH_NAME);
-                       }
-               } elseif (!is_readable($pathName)) {
-                       // Not readable
-                       if ($inConstructor) {
-                               return NULL;
-                       } else {
-                               throw new PathReadProtectedException($pathName, self::EXCEPTION_READ_PROTECED_PATH);
-                       }
-               }
-
-               // Get an iterator for the directory
-               $directoryInstance = new DirectoryIterator($pathName);
-
-               // Create new instance
-               $pointerInstance = new FrameworkDirectoryPointer();
-
-               // Set directory pointer and path name
-               $pointerInstance->setDirectoryInstance($directoryInstance);
-               $pointerInstance->setPathName($pathName);
-
-               // Return the instance
-               return $pointerInstance;
-       }
-
-       /**
-        * Read raw lines of data from a directory pointer and return the data
-        *
-        * @return      $current        Current entry from encapsulated iterator
-        */
-       public function readRawDirectory () {
-               // Can the next entry be read?
-               assert($this->getDirectoryInstance()->valid());
-
-               // Default is FALSE
-               $current = FALSE;
-
-               // Is it a dot directory?
-               if (!$this->getDirectoryInstance()->isDot()) {
-                       // Read data from the directory pointer and return it
-                       $current = $this->getDirectoryInstance()->current();
-               } // END - if
-
-               // Advance to next entry
-               $this->getDirectoryInstance()->next();
-
-               // Return found entry
-               return $current;
-       }
-
-       /**
-        * Read lines from the current directory pointer except some parts
-        *
-        * @param       $except         Some parts of a directory we want to ignore. Valid: directory and file names, other values will be silently ignored
-        * @return      string          Directory and/or file names read from the current directory pointer
-        */
-       public function readDirectoryExcept (array $except = array()) {
-               // No exceptions given?
-               if (count($except) == 0) {
-                       // No exception given, so read all files and directories, but not recursive
-                       self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: No exceptions given, please use readRawDirectory() instead!');
-                       return $this->readRawDirectory();
-               } // END - if
-
-               // Read a raw line...
-               $rawLine = $this->readRawDirectory();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine);
-
-               // Shall we exclude directories?
-               if ((!is_null($rawLine)) && ($rawLine !== FALSE) && (!in_array($rawLine, $except))) {
-                       // Return read data
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine);
-                       return $rawLine;
-               } elseif ((!is_null($rawLine)) && ($rawLine !== FALSE)) {
-                       // Exclude this part
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawline[' . gettype($rawLine) . ']=' . $rawLine . ' - Recursive call!');
-                       return $this->readDirectoryExcept($except);
-               }
-
-               // End pointer reached
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: Returning NULL!');
-               return NULL;
-       }
-
-       /**
-        * Close a directory source and set it's instance to null and the path name
-        * to empty
-        *
-        * @return      void
-        */
-       public function closeDirectory () {
-               // Close the directory by unsetting it
-               $this->setDirectoryInstance(NULL);
-               $this->setPathName('');
-       }
-
-       /**
-        * Setter for the directory pointer
-        *
-        * @param       $directoryInstance      An instanceof a DirectoryIterator class or NULL to unset ("close") it.
-        * @return      void
-        */
-       protected final function setDirectoryInstance (DirectoryIterator $directoryInstance = NULL) {
-               // Set instance (or NULL)
-               $this->directoryInstance = $directoryInstance;
-       }
-
-       /**
-        * Getter for the directory pointer
-        *
-        * @return      $directoryInstance      The directory pointer which shall be a valid directory resource
-        */
-       public final function getDirectoryInstance () {
-               return $this->directoryInstance;
-       }
-
-       /**
-        * Setter for path name
-        *
-        * @param       $pathName       The new path name
-        * @return      void
-        */
-       public final function setPathName ($pathName) {
-               $pathName = (string) $pathName;
-               $this->pathName = $pathName;
-       }
-
-       /**
-        * Getter for path name
-        *
-        * @return      $pathName       The current path name
-        */
-       public final function getPathName () {
-               return $this->pathName;
-       }
-}
-
-// [EOF]
-?>
diff --git a/inc/classes/main/io/class_FrameworkFileInputPointer.php b/inc/classes/main/io/class_FrameworkFileInputPointer.php
deleted file mode 100644 (file)
index f46e48a..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-/**
- * A class for reading files
- *
- * @author             Roland Haeder <webmaster@shipsimu.org>
- * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
- * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class FrameworkFileInputPointer extends BaseFrameworkSystem {
-       /**
-        * The current file we are working in
-        */
-       private $fileName = '';
-
-       /**
-        * The file pointer
-        */
-       private $filePointer = NULL;
-
-       /**
-        * Protected constructor
-        *
-        * @return      void
-        */
-       protected function __construct () {
-               // Call parent constructor
-               parent::__construct(__CLASS__);
-       }
-
-       /**
-        * Destructor for cleaning purposes, etc
-        *
-        * @return      void
-        */
-       public final function __destruct() {
-               // Is there a resource pointer? Then we have to close the file here!
-               if (is_resource($this->getPointer())) {
-                       // Try to close a file
-                       $this->closeFile();
-               }
-
-               // Call the parent destructor
-               parent::__destruct();
-       }
-
-       /**
-        * Create a file pointer based on the given file. The file will also
-        * be verified here.
-        *
-        * @param               $fileName       The file name we shall pass to fopen()
-        * @throws      FileIsEmptyException    If the provided file name is empty.
-        * @throws      FileIoException         If fopen() returns not a file resource
-        * @return      void
-        */
-       public static final function createFrameworkFileInputPointer ($fileName) {
-               // Some pre-sanity checks...
-               if ((is_null($fileName)) || (empty($fileName))) {
-                       // No filename given
-                       throw new FileIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
-               } elseif (!file_exists($fileName)) {
-                       // File does not exist!
-                       throw new FileIoException($fileName, self::EXCEPTION_FILE_NOT_FOUND);
-               } elseif (!is_readable($fileName)) {
-                       // File does not exist!
-                       throw new FileReadProtectedException($fileName, self::EXCEPTION_FILE_CANNOT_BE_READ);
-               }
-
-               // Try to open a handler
-               $filePointer = fopen($fileName, 'rb');
-               if ((is_null($filePointer)) || ($filePointer === FALSE)) {
-                       // Something bad happend
-                       throw new FileIoException($fileName, self::EXCEPTION_FILE_POINTER_INVALID);
-               } // END - if
-
-               // Create new instance
-               $pointerInstance = new FrameworkFileInputPointer();
-
-               // Set file pointer and file name
-               $pointerInstance->setPointer($filePointer);
-               $pointerInstance->setFileName($fileName);
-
-               // Return the instance
-               return $pointerInstance;
-       }
-
-       /**
-        * Read data a file pointer
-        *
-        * @return      mixed   The result of fread()
-        * @throws      NullPointerException    If the file pointer instance
-        *                                                                      is not set by setPointer()
-        * @throws      InvalidResourceException        If there is being set
-        *                                                                      an invalid file resource
-        */
-       public function readFromFile () {
-               if (is_null($this->getPointer())) {
-                       // Pointer not initialized
-                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
-               } elseif (!is_resource($this->getPointer())) {
-                       // Pointer is not a valid resource!
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-
-               // Read data from the file pointer and return it
-               return fread($this->getPointer(), 1024);
-       }
-
-       /**
-        * Close a file source and set it's instance to null and the file name
-        * to empty
-        *
-        * @return      void
-        * @throws      NullPointerException    If the file pointer instance
-        *                                                                      is not set by setPointer()
-        * @throws      InvalidResourceException        If there is being set
-        */
-       public function closeFile () {
-               if (is_null($this->getPointer())) {
-                       // Pointer not initialized
-                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
-               } elseif (!is_resource($this->getPointer())) {
-                       // Pointer is not a valid resource!
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-
-               // Close the file pointer and reset the instance variable
-               @fclose($this->getPointer());
-               $this->setPointer(NULL);
-               $this->setFileName('');
-       }
-
-       /**
-        * Setter for the file pointer
-        *
-        * @param       $filePointer    File resource
-        * @return      void
-        */
-       public final function setPointer ($filePointer) {
-               // Sanity-check if pointer is a valid file resource
-               if (is_resource($filePointer) || is_null($filePointer)) {
-                       // Is a valid resource
-                       $this->filePointer = $filePointer;
-               } else {
-                       // Throw exception
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-       }
-
-       /**
-        * Getter for the file pointer
-        *
-        * @return      $filePointer    The file pointer which shall be a valid
-        *                                                      file resource
-        */
-       public final function getPointer () {
-               return $this->filePointer;
-       }
-
-       /**
-        * Setter for file name
-        *
-        * @param       $fileName       The new file name
-        * @return      void
-        */
-       public final function setFileName ($fileName) {
-               $fileName = (string) $fileName;
-               $this->fileName = $fileName;
-       }
-
-       /**
-        * Getter for file name
-        *
-        * @return      $fileName       The current file name
-        */
-       public final function getFileName () {
-               return $this->fileName;
-       }
-}
-
-// [EOF]
-?>
diff --git a/inc/classes/main/io/class_FrameworkFileOutputPointer.php b/inc/classes/main/io/class_FrameworkFileOutputPointer.php
deleted file mode 100644 (file)
index 8d80e71..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-<?php
-/**
- * A class for writing files
- *
- * @author             Roland Haeder <webmaster@shipsimu.org>
- * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
- * @license            GNU GPL 3.0 or any newer version
- * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class FrameworkFileOutputPointer extends BaseFrameworkSystem {
-       /**
-        * The current file we are working in
-        */
-       private $fileName = '';
-
-       /**
-        * The file pointer
-        */
-       private $filePointer = NULL;
-
-       /**
-        * Protected constructor
-        */
-       protected function __construct () {
-               // Call parent constructor
-               parent::__construct(__CLASS__);
-       }
-
-       /**
-        * Destructor for cleaning purposes, etc
-        */
-       public final function __destruct() {
-               // Is there a resource pointer? Then we have to close the file here!
-               if (is_resource($this->getPointer())) {
-                       // Try to close a file
-                       $this->closeFile();
-               }
-
-               // Call the parent destructor
-               parent::__destruct();
-       }
-
-       /**
-        * Create a file pointer based on the given file. The file will also
-        * be verified here.
-        *
-        * @param       $fileName       The file name we shall pass to fopen()
-        * @param       $mode           The output mode ('w', 'a' are valid)
-        * @throws      FileIsEmptyException    If the provided file name is empty.
-        * @throws      FileIoException         If fopen() returns not a file resource
-        * @return      void
-        */
-       public static final function createFrameworkFileOutputPointer ($fileName, $mode) {
-               // Some pre-sanity checks...
-               if (is_null($fileName)) {
-                       // No filename given
-                       throw new FileIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
-               } // END - if
-
-               // Try to open a handler
-               $filePointer = @fopen($fileName, $mode);
-               if ((is_null($filePointer)) || ($filePointer === FALSE)) {
-                       // Something bad happend
-                       throw new FileIoException ($fileName, self::EXCEPTION_FILE_POINTER_INVALID);
-               } // END - if
-
-               // Create new instance
-               $pointerInstance = new FrameworkFileOutputPointer();
-
-               // Set file pointer and file name
-               $pointerInstance->setPointer($filePointer);
-               $pointerInstance->setFileName($fileName);
-
-               // Return the instance
-               return $pointerInstance;
-       }
-
-       /**
-        * Write data to a file pointer
-        *
-        * @param       $dataStream             The data stream we shall write to the file
-        * @return      mixed                   Number of writes bytes or FALSE on error
-        * @throws      NullPointerException    If the file pointer instance
-        *                                                                      is not set by setPointer()
-        * @throws      InvalidResourceException        If there is being set
-        *                                                                                      an invalid file resource
-        */
-       public function writeToFile ($dataStream) {
-               if (is_null($this->getPointer())) {
-                       // Pointer not initialized
-                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
-               } elseif (!is_resource($this->getPointer())) {
-                       // Pointer is not a valid resource!
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-
-               // Write data to the file pointer and return written bytes
-               return fwrite($this->getPointer(), $dataStream);
-       }
-
-       /**
-        * Close a file source and set it's instance to null and the file name
-        * to empty
-        *
-        * @return      void
-        * @throws      NullPointerException    If the file pointer instance
-        *                                                                      is not set by setPointer()
-        * @throws      InvalidResourceException        If there is being set
-        */
-       public function closeFile () {
-               if (is_null($this->getPointer())) {
-                       // Pointer not initialized
-                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
-               } elseif (!is_resource($this->getPointer())) {
-                       // Pointer is not a valid resource!
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-
-               // Close the file pointer and reset the instance variable
-               @fclose($this->getPointer());
-               $this->setPointer(NULL);
-               $this->setFileName('');
-       }
-
-       /**
-        * Setter for the file pointer
-        *
-        * @param       $filePointer    File resource
-        * @return      void
-        */
-       public final function setPointer ($filePointer) {
-               // Sanity-check if pointer is a valid file resource
-               if (is_resource($filePointer) || is_null($filePointer)) {
-                       // Is a valid resource
-                       $this->filePointer = $filePointer;
-               } else {
-                       // Throw exception
-                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
-               }
-       }
-
-       /**
-        * Getter for the file pointer
-        *
-        * @return      $filePointer    The file pointer which shall be a valid
-        *                                                      file resource
-        */
-       public final function getPointer () {
-               return $this->filePointer;
-       }
-
-       /**
-        * Setter for file name
-        *
-        * @param       $fileName       The new file name
-        * @return      void
-        */
-       public final function setFileName ($fileName) {
-               $fileName = (string) $fileName;
-               $this->fileName = $fileName;
-       }
-
-       /**
-        * Getter for file name
-        *
-        * @return      $fileName       The current file name
-        */
-       public final function getFileName () {
-               return $this->fileName;
-       }
-}
-
-// [EOF]
-?>
diff --git a/inc/classes/main/io/directory/.htaccess b/inc/classes/main/io/directory/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/inc/classes/main/io/directory/class_FrameworkDirectoryPointer.php b/inc/classes/main/io/directory/class_FrameworkDirectoryPointer.php
new file mode 100644 (file)
index 0000000..da22040
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+/**
+ * A class for directory reading and getting its contents, no recursion!
+ *
+ * @author             Roland Haeder <webmaster@shipsimu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @license            GNU GPL 3.0 or any newer version
+ * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class FrameworkDirectoryPointer extends BaseFrameworkSystem {
+       /**
+        * The current path we are working in
+        */
+       private $pathName = '';
+
+       /**
+        * The directory iterator instance
+        */
+       private $directoryInstance = NULL;
+
+       /**
+        * Protected constructor
+        */
+       protected function __construct () {
+               // Call parent constructor
+               parent::__construct(__CLASS__);
+       }
+
+       /**
+        * Destructor for cleaning purposes, etc
+        */
+       public function __destruct() {
+               // Is there a resource pointer? Then we have to close the directory here!
+               if ($this->getDirectoryInstance() instanceof DirectoryIterator) {
+                       // Try to close a directory
+                       $this->closeDirectory();
+               } // END - if
+
+               // Call the parent destructor
+               parent::__destruct();
+       }
+
+       /**
+        * Create a directory pointer based on the given path. The path will also
+        * be verified here.
+        *
+        * @param       $pathName               The path name we shall pass to opendir()
+        * @param       $inConstructor  If we are in de/con-structor or from somewhere else
+        * @return      $pointerInstance        A prepared instance of FrameworkDirectoryPointer
+        * @throws      PathIsEmptyException    If the provided path name is empty
+        * @throws      InvalidPathStringException      If the provided path name is not a string
+        * @throws      PathIsNoDirectoryException      If the provided path name is not valid
+        * @throws      PathReadProtectedException      If the provided path name is read-protected
+        * @todo        Get rid of inConstructor, could be old-lost code.
+        */
+       public static final function createFrameworkDirectoryPointer ($pathName, $inConstructor = FALSE) {
+               // Some pre-sanity checks...
+               if (is_null($pathName)) {
+                       // No pathname given
+                       if ($inConstructor) {
+                               return NULL;
+                       } else {
+                               throw new PathIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
+                       }
+               } elseif (!is_string($pathName)) {
+                       // Is not a string
+                       if ($inConstructor) {
+                               return NULL;
+                       } else {
+                               throw new InvalidPathStringException(NULL, self::EXCEPTION_INVALID_STRING);
+                       }
+               } elseif (!is_dir($pathName)) {
+                       // Not a directory
+                       if ($inConstructor) {
+                               return NULL;
+                       } else {
+                               throw new PathIsNoDirectoryException($pathName, self::EXCEPTION_INVALID_PATH_NAME);
+                       }
+               } elseif (!is_readable($pathName)) {
+                       // Not readable
+                       if ($inConstructor) {
+                               return NULL;
+                       } else {
+                               throw new PathReadProtectedException($pathName, self::EXCEPTION_READ_PROTECED_PATH);
+                       }
+               }
+
+               // Get an iterator for the directory
+               $directoryInstance = new DirectoryIterator($pathName);
+
+               // Create new instance
+               $pointerInstance = new FrameworkDirectoryPointer();
+
+               // Set directory pointer and path name
+               $pointerInstance->setDirectoryInstance($directoryInstance);
+               $pointerInstance->setPathName($pathName);
+
+               // Return the instance
+               return $pointerInstance;
+       }
+
+       /**
+        * Read raw lines of data from a directory pointer and return the data
+        *
+        * @return      $current        Current entry from encapsulated iterator
+        */
+       public function readRawDirectory () {
+               // Can the next entry be read?
+               assert($this->getDirectoryInstance()->valid());
+
+               // Default is FALSE
+               $current = FALSE;
+
+               // Is it a dot directory?
+               if (!$this->getDirectoryInstance()->isDot()) {
+                       // Read data from the directory pointer and return it
+                       $current = $this->getDirectoryInstance()->current();
+               } // END - if
+
+               // Advance to next entry
+               $this->getDirectoryInstance()->next();
+
+               // Return found entry
+               return $current;
+       }
+
+       /**
+        * Read lines from the current directory pointer except some parts
+        *
+        * @param       $except         Some parts of a directory we want to ignore. Valid: directory and file names, other values will be silently ignored
+        * @return      string          Directory and/or file names read from the current directory pointer
+        */
+       public function readDirectoryExcept (array $except = array()) {
+               // No exceptions given?
+               if (count($except) == 0) {
+                       // No exception given, so read all files and directories, but not recursive
+                       self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: No exceptions given, please use readRawDirectory() instead!');
+                       return $this->readRawDirectory();
+               } // END - if
+
+               // Read a raw line...
+               $rawLine = $this->readRawDirectory();
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine);
+
+               // Shall we exclude directories?
+               if ((!is_null($rawLine)) && ($rawLine !== FALSE) && (!in_array($rawLine, $except))) {
+                       // Return read data
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawLine[' . gettype($rawLine) . ']=' . $rawLine);
+                       return $rawLine;
+               } elseif ((!is_null($rawLine)) && ($rawLine !== FALSE)) {
+                       // Exclude this part
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: rawline[' . gettype($rawLine) . ']=' . $rawLine . ' - Recursive call!');
+                       return $this->readDirectoryExcept($except);
+               }
+
+               // End pointer reached
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DIRECTORY[' . __METHOD__ . ':' . __LINE__ . ']: Returning NULL!');
+               return NULL;
+       }
+
+       /**
+        * Close a directory source and set it's instance to null and the path name
+        * to empty
+        *
+        * @return      void
+        */
+       public function closeDirectory () {
+               // Close the directory by unsetting it
+               $this->setDirectoryInstance(NULL);
+               $this->setPathName('');
+       }
+
+       /**
+        * Setter for the directory pointer
+        *
+        * @param       $directoryInstance      An instanceof a DirectoryIterator class or NULL to unset ("close") it.
+        * @return      void
+        */
+       protected final function setDirectoryInstance (DirectoryIterator $directoryInstance = NULL) {
+               // Set instance (or NULL)
+               $this->directoryInstance = $directoryInstance;
+       }
+
+       /**
+        * Getter for the directory pointer
+        *
+        * @return      $directoryInstance      The directory pointer which shall be a valid directory resource
+        */
+       public final function getDirectoryInstance () {
+               return $this->directoryInstance;
+       }
+
+       /**
+        * Setter for path name
+        *
+        * @param       $pathName       The new path name
+        * @return      void
+        */
+       public final function setPathName ($pathName) {
+               $pathName = (string) $pathName;
+               $this->pathName = $pathName;
+       }
+
+       /**
+        * Getter for path name
+        *
+        * @return      $pathName       The current path name
+        */
+       public final function getPathName () {
+               return $this->pathName;
+       }
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/io/input/.htaccess b/inc/classes/main/io/input/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/inc/classes/main/io/input/class_FrameworkFileInputPointer.php b/inc/classes/main/io/input/class_FrameworkFileInputPointer.php
new file mode 100644 (file)
index 0000000..b6b9cb3
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+/**
+ * A class for reading files
+ *
+ * @author             Roland Haeder <webmaster@shipsimu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @license            GNU GPL 3.0 or any newer version
+ * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class FrameworkFileInputPointer extends BaseFileIo {
+       /**
+        * Protected constructor
+        *
+        * @return      void
+        */
+       protected function __construct () {
+               // Call parent constructor
+               parent::__construct(__CLASS__);
+       }
+
+       /**
+        * Create a file pointer based on the given file. The file will also
+        * be verified here.
+        *
+        * @param               $fileName       The file name we shall pass to fopen()
+        * @throws      FileIsEmptyException    If the provided file name is empty.
+        * @throws      FileIoException         If fopen() returns not a file resource
+        * @return      void
+        */
+       public static final function createFrameworkFileInputPointer ($fileName) {
+               // Some pre-sanity checks...
+               if ((is_null($fileName)) || (empty($fileName))) {
+                       // No filename given
+                       throw new FileIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
+               } elseif (!file_exists($fileName)) {
+                       // File does not exist!
+                       throw new FileIoException($fileName, self::EXCEPTION_FILE_NOT_FOUND);
+               } elseif (!is_readable($fileName)) {
+                       // File does not exist!
+                       throw new FileReadProtectedException($fileName, self::EXCEPTION_FILE_CANNOT_BE_READ);
+               }
+
+               // Try to open a handler
+               $fileInstance = fopen($fileName, 'rb');
+               if ((is_null($fileInstance)) || ($fileInstance === FALSE)) {
+                       // Something bad happend
+                       throw new FileIoException($fileName, self::EXCEPTION_FILE_POINTER_INVALID);
+               } // END - if
+
+               // Create new instance
+               $pointerInstance = new FrameworkFileInputPointer();
+
+               // Set file pointer and file name
+               $pointerInstance->setInstance($fileInstance);
+               $pointerInstance->setFileName($fileName);
+
+               // Return the instance
+               return $pointerInstance;
+       }
+
+       /**
+        * Read data a file pointer
+        *
+        * @return      mixed   The result of fread()
+        * @throws      NullPointerException    If the file pointer instance
+        *                                                                      is not set by setPointer()
+        */
+       public function readFromFile () {
+               if (!$this->getInstance() instanceof SplFileObject) {
+                       // Pointer not initialized
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               }
+
+               // Read data from the file pointer and return it
+               return fread($this->getInstance(), 1024);
+       }
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/io/io_handler/.htaccess b/inc/classes/main/io/io_handler/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/inc/classes/main/io/io_handler/class_FileIoStream.php b/inc/classes/main/io/io_handler/class_FileIoStream.php
new file mode 100644 (file)
index 0000000..35d00ed
--- /dev/null
@@ -0,0 +1,264 @@
+<?php
+/**
+ * An universal class for file input/output streams.
+ *
+ * @author             Roland Haeder <webmaster@shipsimu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @license            GNU GPL 3.0 or any newer version
+ * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class FileIoStream extends BaseFrameworkSystem implements FileInputStreamer, FileOutputStreamer {
+       /**
+        * File header indicator
+        */
+       const FILE_IO_FILE_HEADER_ID = '@head';
+
+       /**
+        * Data block indicator
+        */
+       const FILE_IO_DATA_BLOCK_ID = '@data';
+
+       /**
+        * Separator #1
+        */
+       const FILE_IO_CHUNKER = ':';
+
+       /**
+        * Separator #2
+        */
+       const FILE_IO_SEPARATOR = '^';
+
+       /**
+        * Protected constructor
+        */
+       protected function __construct () {
+               // Call parent constructor
+               parent::__construct(__CLASS__);
+       }
+
+       /**
+        * Create a file IO stream. This is a class for performing all actions
+        * on files like creating, deleting and loading them.
+        *
+        * @return      $ioInstance     An instance of FileIoStream
+        */
+       public static final function createFileIoStream () {
+               // Create new instance
+               $ioInstance = new FileIoStream();
+
+               // Return the instance
+               return $ioInstance;
+       }
+
+       /**
+        * Saves data to a given local file and create missing directory structures
+        *
+        * @param       $fileName       The file name for the to be saved file
+        * @param       $dataArray      The data we shall store to the file
+        * @return      void
+        * @see         FileOutputStreamer
+        * @todo        This method needs heavy rewrite
+        */
+       public final function saveFile ($fileName, array $dataArray) {
+               // Try it five times
+               $dirName = ''; $fileInstance = NULL;
+               for ($idx = 0; $idx < 5; $idx++) {
+                       // Get a file output pointer
+                       try {
+                               $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fileName, 'w');
+                       } catch (FileIoException $e) {
+                               // Create missing directory
+                               $dirName = dirname($fileName);
+                               for ($idx2 = 0; $idx2 < (2 - $idx); $idx2++) {
+                                       $dirName = dirname($dirName);
+                               } // END - for
+
+                               // Try to create it
+                               @mkdir($dirName);
+                       }
+               } // END - for
+
+               // Write a header information for validation purposes
+               $fileInstance->writeToFile(sprintf("%s%s%s%s%s%s%s%s%s\n",
+                       self::FILE_IO_FILE_HEADER_ID,
+                       self::FILE_IO_SEPARATOR,
+                       $dataArray[0],
+                       self::FILE_IO_CHUNKER,
+                       time(),
+                       self::FILE_IO_CHUNKER,
+                       strlen($dataArray[1]),
+                       self::FILE_IO_CHUNKER,
+                       md5($dataArray[1])
+               ));
+
+               // Encode the (maybe) binary stream with Base64
+               $b64Stream = base64_encode($dataArray[1]);
+
+               // write the data line by line
+               $line = str_repeat(' ', 50); $idx = 0;
+               while (strlen($line) == 50) {
+                       // Get 50 chars or less
+                       $line = substr($b64Stream, $idx, 50);
+
+                       // Save it to the stream
+                       $fileInstance->writeToFile(sprintf("%s%s%s%s%s\n",
+                               self::FILE_IO_DATA_BLOCK_ID,
+                               self::FILE_IO_SEPARATOR,
+                               $line,
+                               self::FILE_IO_CHUNKER,
+                               md5($line)
+                       ));
+
+                       // Advance to the next 50-chars block
+                       $idx += 50;
+               } // END - while
+
+               // Close the file
+               $fileInstance->closeFile();
+       }
+
+       /**
+        * Reads from a local file
+        *
+        * @param               $fqfn   The full-qualified file-name which we shall load
+        * @return      $array  An array with the element 'header' and 'data'
+        * @see         FileInputStreamer
+        */
+       public final function loadFileContents ($fqfn) {
+               // Initialize some variables and arrays
+               $inputBuffer = '';
+               $lastBuffer = '';
+               $header = array();
+               $data = array();
+               $readData = ''; // This will contain our read data
+
+               // Get a file input handler
+               $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
+
+               // Read all it's contents (we very and transparently decompress it below)
+               while ($readRawLine = $fileInstance->readFromFile()) {
+                       // Add the read line to the buffer
+                       $inputBuffer .= $readRawLine;
+
+                       // Break infinite loop maybe caused by the input handler
+                       if ($lastBuffer == $inputBuffer) break;
+
+                       // Remember last read line for avoiding possible infinite loops
+                       $lastBuffer = $inputBuffer;
+               } // END - while
+
+               // Close directory handle
+               $fileInstance->closeFile();
+
+               // Convert it into an array
+               $inputBuffer = explode(chr(10), $inputBuffer);
+
+               // Now process the read lines and verify it's content
+               foreach ($inputBuffer as $rawLine) {
+                       // Trim it a little but not the leading spaces/tab-stops
+                       $rawLine = rtrim($rawLine);
+
+                       // Analyze this line
+                       if (substr($rawLine, 0, 5) == self::FILE_IO_FILE_HEADER_ID) {
+                               // Header found, so let's extract it
+                               $header = explode(self::FILE_IO_SEPARATOR, $rawLine);
+                               $header = trim($header[1]);
+
+                               // Now we must convert it again into an array
+                               $header = explode(self::FILE_IO_CHUNKER, $header);
+
+                               // Is the header (maybe) valid?
+                               if (count($header) != 4) {
+                                       // Throw an exception
+                                       throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+                               } // END - if
+                       } elseif (substr($rawLine, 0, 5) == self::FILE_IO_DATA_BLOCK_ID) {
+                               // Is a data line!
+                               $data = explode(self::FILE_IO_SEPARATOR, $rawLine);
+                               $data = $data[1];
+
+                               // First element is the data, second the MD5 checksum
+                               $data = explode(self::FILE_IO_CHUNKER, $data);
+
+                               // Validate the read line
+                               if (count($data) == 2) {
+                                       if (md5($data[0]) != $data[1]) {
+                                               // MD5 hash did not match!
+                                               throw new InvalidMD5ChecksumException(array($this, md5($data[0]), $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+                                       } // END - if
+                               } else {
+                                       // Invalid count!
+                                       throw new InvalidArrayCountException(array($this, 'data', count($data), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+                               }
+
+                               // Add this to the readData string
+                               $readData .= $data[0];
+                       } else {
+                               // Other raw lines than header/data tagged lines and re-add the new-line char
+                               $readData .= $rawLine . PHP_EOL;
+                       }
+               } // END - foreach
+
+               // Was raw lines read and no header/data?
+               if ((!empty($readData)) && (count($header) == 0) && (count($data) == 0)) {
+                       // Return raw lines back
+                       return $readData;
+               } // END - if
+
+               // Was a header found?
+               if (count($header) != 4) {
+                       // Throw an exception
+                       throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+               } // END - if
+
+               // Decode all from Base64
+               $readData = @base64_decode($readData);
+
+               // Does the size match?
+               if (strlen($readData) != $header[2]) {
+                       // Size did not match
+                       throw new InvalidDataLengthException(array($this, strlen($readData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
+               } // END - if
+
+               // Validate the decoded data with the final MD5 hash
+               if (md5($readData) != $header[3]) {
+                       // MD5 hash did not match!
+                       throw new InvalidMD5ChecksumException(array($this, md5($readData), $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+               } // END - if
+
+               // Return all in an array
+               return array(
+                       'header' => $header,
+                       'data'   => $readData
+               );
+       }
+
+       /**
+        * Streams the data and maybe does something to it
+        *
+        * @param       $data   The data (string mostly) to "stream"
+        * @return      $data   The data (string mostly) to "stream"
+        * @throws      UnsupportedOperationException   If this method is called
+        */
+       public function streamData ($data) {
+               self::createDebugInstance(__CLASS__)->debugOutput('Unhandled ' . strlen($data) . ' bytes in this stream.');
+               throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/io/output/.htaccess b/inc/classes/main/io/output/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/inc/classes/main/io/output/class_FrameworkFileOutputPointer.php b/inc/classes/main/io/output/class_FrameworkFileOutputPointer.php
new file mode 100644 (file)
index 0000000..1af2697
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/**
+ * A class for writing files
+ *
+ * @author             Roland Haeder <webmaster@shipsimu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @license            GNU GPL 3.0 or any newer version
+ * @link               http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class FrameworkFileOutputPointer extends BaseFileIo {
+       /**
+        * Protected constructor
+        *
+        * @return      void
+        */
+       protected function __construct () {
+               // Call parent constructor
+               parent::__construct(__CLASS__);
+       }
+
+       /**
+        * Create a file pointer based on the given file. The file will also
+        * be verified here.
+        *
+        * @param       $fileName       The file name we shall pass to fopen()
+        * @param       $mode           The output mode ('w', 'a' are valid)
+        * @throws      FileIsEmptyException    If the provided file name is empty.
+        * @throws      FileIoException         If fopen() returns not a file resource
+        * @return      void
+        */
+       public static final function createFrameworkFileOutputPointer ($fileName, $mode) {
+               // Some pre-sanity checks...
+               if (is_null($fileName)) {
+                       // No filename given
+                       throw new FileIsEmptyException(NULL, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
+               } // END - if
+
+               // Try to open a handler
+               $filePointer = @fopen($fileName, $mode);
+               if ((is_null($filePointer)) || ($filePointer === FALSE)) {
+                       // Something bad happend
+                       throw new FileIoException ($fileName, self::EXCEPTION_FILE_POINTER_INVALID);
+               } // END - if
+
+               // Create new instance
+               $pointerInstance = new FrameworkFileOutputPointer();
+
+               // Set file pointer and file name
+               $pointerInstance->setPointer($filePointer);
+               $pointerInstance->setFileName($fileName);
+
+               // Return the instance
+               return $pointerInstance;
+       }
+
+       /**
+        * Write data to a file pointer
+        *
+        * @param       $dataStream             The data stream we shall write to the file
+        * @return      mixed                   Number of writes bytes or FALSE on error
+        * @throws      NullPointerException    If the file pointer instance
+        *                                                                      is not set by setPointer()
+        * @throws      InvalidResourceException        If there is being set
+        *                                                                                      an invalid file resource
+        */
+       public function writeToFile ($dataStream) {
+               if (is_null($this->getPointer())) {
+                       // Pointer not initialized
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               } elseif (!is_resource($this->getPointer())) {
+                       // Pointer is not a valid resource!
+                       throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
+               }
+
+               // Write data to the file pointer and return written bytes
+               return fwrite($this->getPointer(), $dataStream);
+       }
+}
+
+// [EOF]
+?>