Introduced isReachableFilePath() and isReadableFile().
[core.git] / inc / classes / main / class_BaseFrameworkSystem.php
index 29d5459ceecb3a56194ca8a5e91f09930a3ba64f..f4d7d6787493e73a85994085cf1010ece226cc56 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @author             Roland Haeder <webmaster@shipsimu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.shipsimu.org
  *
  */
 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        /**
-        * Length of count
-        */
-       const LENGTH_COUNT = 20;
-
-       /**
-        * Length of position
+        * Length of output from hash()
         */
-       const LENGTH_POSITION = 20;
+       private static $hashLength = NULL;
 
        /**
         * The real class name
@@ -121,7 +116,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        /**
         * Instance of the stacker
         */
-       private $stackerInstance = NULL;
+       private $stackInstance = NULL;
 
        /**
         * A Compressor instance
@@ -134,7 +129,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        private $parserInstance = NULL;
 
        /**
-        * A ProtocolHandler instance
+        * A HandleableProtocol instance
         */
        private $protocolInstance = NULL;
 
@@ -149,10 +144,15 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        private $helperInstance = NULL;
 
        /**
-        * An instance of a Sourceable class
+        * An instance of a Source class
         */
        private $sourceInstance = NULL;
 
+       /**
+        * An instance of a UrlSource class
+        */
+       private $urlSourceInstance = NULL;
+
        /**
         * An instance of a InputStream class
         */
@@ -189,10 +189,35 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        private $pointerInstance = NULL;
 
        /**
-        * An instance of an index
+        * An instance of an Indexable class
         */
        private $indexInstance = NULL;
 
+       /**
+        * An instance of a Block class
+        */
+       private $blockInstance = NULL;
+
+       /**
+        * A Minable instance
+        */
+       private $minableInstance = NULL;
+
+       /**
+        * A FrameworkDirectory instance
+        */
+       private $directoryInstance = NULL;
+
+       /**
+        * Listener instance
+        */
+       private $listenerInstance = NULL;
+
+       /**
+        * An instance of a communicator
+        */
+       private $communicatorInstance = NULL;
+
        /**
         * Thousands separator
         */
@@ -208,6 +233,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         */
        private $socketResource = FALSE;
 
+       /**
+        * Regular expression to use for validation
+        */
+       private $regularExpression = '';
+
        /**
         * Package data
         */
@@ -219,39 +249,42 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        private $genericArray = array();
 
        /**
-        * Length of output from hash()
-        */
-       private static $hashLength = NULL;
-
-       /**
-        * Counter for total entries
+        * Command name
         */
-       private $totalEntries = 0;
+       private $commandName = '';
 
        /**
-        * Current seek position
+        * Controller name
         */
-       private $seekPosition = 0;
+       private $controllerName = '';
 
        /**
-        * Size of header
+        * Array with bitmasks and such for pack/unpack methods to support both
+        * 32-bit and 64-bit systems
         */
-       private $headerSize = 0;
-
-       /**
-        * File header
-        */
-       private $header = array();
-
-       /**
-        * Seek positions for gaps ("fragmentation")
-        */
-       private $gaps = array();
+       private $packingData = array(
+               32 => array(
+                       'step'   => 3,
+                       'left'   => 0xffff0000,
+                       'right'  => 0x0000ffff,
+                       'factor' => 16,
+                       'format' => 'II',
+               ),
+               64 => array(
+                       'step'   => 7,
+                       'left'   => 0xffffffff00000000,
+                       'right'  => 0x00000000ffffffff,
+                       'factor' => 32,
+                       'format' => 'NN'
+               )
+       );
 
        /**
-        * Seek positions for damaged entries (e.g. mismatching hash sum, ...)
+        * Simple 64-bit check, thanks to "Salman A" from stackoverflow.com:
+        *
+        * The integer size is 4 bytes on 32-bit and 8 bytes on a 64-bit system.
         */
-       private $damagedEntries = array();
+       private $archArrayElement = FALSE;
 
        /***********************
         * Exception codes.... *
@@ -313,9 +346,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        const EXCEPTION_FATAL_ERROR                  = 0x035;
        const EXCEPTION_FILE_NOT_FOUND               = 0x036;
        const EXCEPTION_ASSERTION_FAILED             = 0x037;
-       const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
-       const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
-       const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03a;
+       const EXCEPTION_FILE_NOT_REACHABLE           = 0x038;
+       const EXCEPTION_FILE_CANNOT_BE_READ          = 0x039;
+       const EXCEPTION_FILE_CANNOT_BE_WRITTEN       = 0x03a;
+       const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03b;
+       const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03c;
 
        /**
         * Hexadecimal->Decimal translation array
@@ -387,6 +422,9 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                        // Then set it
                        self::$startupTime = microtime(TRUE);
                } // END - if
+
+               // Set array element
+               $this->archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
        }
 
        /**
@@ -502,7 +540,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Magic function to catch setting of missing but set class fields/attributes
+        * Magic method to catch setting of missing but set class fields/attributes
         *
         * @param       $name   Name of the field/attribute
         * @param       $value  Value to store
@@ -512,12 +550,12 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
                        $name,
                        gettype($value),
-                       $value
+                       print_r($value, TRUE)
                ));
        }
 
        /**
-        * Magic function to catch getting of missing fields/attributes
+        * Magic method to catch getting of missing fields/attributes
         *
         * @param       $name   Name of the field/attribute
         * @return      void
@@ -529,7 +567,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Magic function to catch unsetting of missing fields/attributes
+        * Magic method to catch unsetting of missing fields/attributes
         *
         * @param       $name   Name of the field/attribute
         * @return      void
@@ -540,6 +578,36 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                ));
        }
 
+       /**
+        * Magic method to catch object serialization
+        *
+        * @return      $unsupported    Unsupported method
+        * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
+        */
+       public final function __sleep () {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
+       /**
+        * Magic method to catch object deserialization
+        *
+        * @return      $unsupported    Unsupported method
+        * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
+        */
+       public final function __wakeup () {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
+       /**
+        * Magic method to catch calls when an object instance is called
+        *
+        * @return      $unsupported    Unsupported method
+        * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
+        */
+       public final function __invoke () {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
        /**
         * Setter for the real class name
         *
@@ -988,20 +1056,20 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        /**
         * Setter for stacker instance
         *
-        * @param       $stackerInstance        An instance of an stacker
+        * @param       $stackInstance  An instance of an stacker
         * @return      void
         */
-       public final function setStackerInstance (Stackable $stackerInstance) {
-               $this->stackerInstance = $stackerInstance;
+       public final function setStackInstance (Stackable $stackInstance) {
+               $this->stackInstance = $stackInstance;
        }
 
        /**
         * Getter for stacker instance
         *
-        * @return      $stackerInstance        An instance of an stacker
+        * @return      $stackInstance  An instance of an stacker
         */
-       public final function getStackerInstance () {
-               return $this->stackerInstance;
+       public final function getStackInstance () {
+               return $this->stackInstance;
        }
 
        /**
@@ -1043,19 +1111,19 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Setter for ProtocolHandler instance
+        * Setter for HandleableProtocol instance
         *
-        * @param       $protocolInstance       An instance of an ProtocolHandler
+        * @param       $protocolInstance       An instance of an HandleableProtocol
         * @return      void
         */
-       public final function setProtocolInstance (ProtocolHandler $protocolInstance = NULL) {
+       public final function setProtocolInstance (HandleableProtocol $protocolInstance) {
                $this->protocolInstance = $protocolInstance;
        }
 
        /**
-        * Getter for ProtocolHandler instance
+        * Getter for HandleableProtocol instance
         *
-        * @return      $protocolInstance       An instance of an ProtocolHandler
+        * @return      $protocolInstance       An instance of an HandleableProtocol
         */
        public final function getProtocolInstance () {
                return $this->protocolInstance;
@@ -1101,6 +1169,27 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                return $this->socketResource;
        }
 
+       /**
+        * Setter for regular expression
+        *
+        * @param       $regularExpression      A valid regular expression
+        * @return      void
+        */
+       public final function setRegularExpression ($regularExpression) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression=' . $regularExpression . ',previous[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+               $this->regularExpression = $regularExpression;
+       }
+
+       /**
+        * Getter for regular expression
+        *
+        * @return      $regularExpression      A valid regular expression
+        */
+       public final function getRegularExpression () {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+               return $this->regularExpression;
+       }
+
        /**
         * Setter for helper instance
         *
@@ -1121,24 +1210,43 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Setter for a Sourceable instance
+        * Setter for a Source instance
         *
-        * @param       $sourceInstance The Sourceable instance
+        * @param       $sourceInstance         An instance of a Source class
         * @return      void
         */
-       protected final function setSourceInstance (Sourceable $sourceInstance) {
+       protected final function setSourceInstance (Source $sourceInstance) {
                $this->sourceInstance = $sourceInstance;
        }
 
        /**
-        * Getter for a Sourceable instance
+        * Getter for a Source instance
         *
-        * @return      $sourceInstance The Sourceable instance
+        * @return      $sourceInstance         An instance of a Source class
         */
        protected final function getSourceInstance () {
                return $this->sourceInstance;
        }
 
+       /**
+        * Setter for a UrlSource instance
+        *
+        * @param       $sourceInstance         An instance of a UrlSource class
+        * @return      void
+        */
+       protected final function setUrlSourceInstance (UrlSource $urlSourceInstance) {
+               $this->urlSourceInstance = $urlSourceInstance;
+       }
+
+       /**
+        * Getter for a UrlSource instance
+        *
+        * @return      $urlSourceInstance              An instance of a UrlSource class
+        */
+       protected final function getUrlSourceInstance () {
+               return $this->urlSourceInstance;
+       }
+
        /**
         * Getter for a InputStream instance
         *
@@ -1274,24 +1382,40 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Setter for InputOutputPointer instance
+        * Setter for FilePointer instance
         *
-        * @param       $pointerInstance        An instance of an InputOutputPointer class
+        * @param       $pointerInstance        An instance of an FilePointer class
         * @return      void
         */
-       protected final function setPointerInstance (InputOutputPointer $pointerInstance) {
+       protected final function setPointerInstance (FilePointer $pointerInstance) {
                $this->pointerInstance = $pointerInstance;
        }
 
        /**
-        * Getter for InputOutputPointer instance
+        * Getter for FilePointer instance
         *
-        * @return      $pointerInstance        An instance of an InputOutputPointer class
+        * @return      $pointerInstance        An instance of an FilePointer class
         */
        public final function getPointerInstance () {
                return $this->pointerInstance;
        }
 
+       /**
+        * Unsets pointer instance which triggers a call of __destruct() if the
+        * instance is still there. This is surely not fatal on already "closed"
+        * file pointer instances.
+        *
+        * I don't want to mess around with above setter by giving it a default
+        * value NULL as setter should always explicitly only set (existing) object
+        * instances and NULL is NULL.
+        *
+        * @return      void
+        */
+       protected final function unsetPointerInstance () {
+               // Simply it to NULL
+               $this->pointerInstance = NULL;
+       }
+
        /**
         * Setter for Indexable instance
         *
@@ -1311,6 +1435,139 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                return $this->indexInstance;
        }
 
+       /**
+        * Setter for Block instance
+        *
+        * @param       $blockInstance  An instance of an Block class
+        * @return      void
+        */
+       protected final function setBlockInstance (Block $blockInstance) {
+               $this->blockInstance = $blockInstance;
+       }
+
+       /**
+        * Getter for Block instance
+        *
+        * @return      $blockInstance  An instance of an Block class
+        */
+       public final function getBlockInstance () {
+               return $this->blockInstance;
+       }
+
+       /**
+        * Setter for Minable instance
+        *
+        * @param       $minableInstance        A Minable instance
+        * @return      void
+        */
+       protected final function setMinableInstance (Minable $minableInstance) {
+               $this->minableInstance = $minableInstance;
+       }
+
+       /**
+        * Getter for minable instance
+        *
+        * @return      $minableInstance        A Minable instance
+        */
+       protected final function getMinableInstance () {
+               return $this->minableInstance;
+       }
+
+       /**
+        * Setter for FrameworkDirectory instance
+        *
+        * @param       $directoryInstance      A FrameworkDirectoryPointer instance
+        * @return      void
+        */
+       protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
+               $this->directoryInstance = $directoryInstance;
+       }
+
+       /**
+        * Getter for FrameworkDirectory instance
+        *
+        * @return      $directoryInstance      A FrameworkDirectory instance
+        */
+       protected final function getDirectoryInstance () {
+               return $this->directoryInstance;
+       }
+
+       /**
+        * Setter for listener instance
+        *
+        * @param       $listenerInstance       A Listenable instance
+        * @return      void
+        */
+       protected final function setListenerInstance (Listenable $listenerInstance) {
+               $this->listenerInstance = $listenerInstance;
+       }
+
+       /**
+        * Getter for listener instance
+        *
+        * @return      $listenerInstance       A Listenable instance
+        */
+       protected final function getListenerInstance () {
+               return $this->listenerInstance;
+       }
+
+       /**
+        * Getter for communicator instance
+        *
+        * @return      $communicatorInstance   An instance of a Communicator class
+        */
+       public final function getCommunicatorInstance () {
+               return $this->communicatorInstance;
+       }
+
+       /**
+        * Setter for communicator instance
+        *
+        * @param       $communicatorInstance   An instance of a Communicator class
+        * @return      void
+        */
+       protected final function setCommunicatorInstance (Communicator $communicatorInstance) {
+               $this->communicatorInstance = $communicatorInstance;
+       }
+
+       /**
+        * Setter for command name
+        *
+        * @param       $commandName    Last validated command name
+        * @return      void
+        */
+       protected final function setCommandName ($commandName) {
+               $this->commandName = $commandName;
+       }
+
+       /**
+        * Getter for command name
+        *
+        * @return      $commandName    Last validated command name
+        */
+       protected final function getCommandName () {
+               return $this->commandName;
+       }
+
+       /**
+        * Setter for controller name
+        *
+        * @param       $controllerName Last validated controller name
+        * @return      void
+        */
+       protected final function setControllerName ($controllerName) {
+               $this->controllerName = $controllerName;
+       }
+
+       /**
+        * Getter for controller name
+        *
+        * @return      $controllerName Last validated controller name
+        */
+       protected final function getControllerName () {
+               return $this->controllerName;
+       }
+
        /**
         * Checks whether an object equals this object. You should overwrite this
         * method to implement own equality checks
@@ -1387,7 +1644,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Prepare the template engine (WebTemplateEngine by default) for a given
+        * Prepare the template engine (HtmlTemplateEngine by default) for a given
         * application helper instance (ApplicationHelper by default).
         *
         * @param               $applicationInstance    An application helper instance or
@@ -1410,7 +1667,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                } // END - if
 
                // Initialize the template engine
-               $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
+               $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
 
                // Return the prepared instance
                return $templateInstance;
@@ -1548,7 +1805,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                        // Try it
                        try {
                                // Get a debugger instance
-                               $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
+                               $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_' . self::getResponseTypeFromSystem() . '_class'));
                        } catch (NullPointerException $e) {
                                // Didn't work, no instance there
                                exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
@@ -1778,7 +2035,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         */
        protected final function getDatabaseEntry () {
                // Is there an instance?
-               if (is_null($this->getResultInstance())) {
+               if (!$this->getResultInstance() instanceof SearchableResult) {
                        // Throw an exception here
                        throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
                } // END - if
@@ -1788,7 +2045,8 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
 
                // Do we have an entry?
                if ($this->getResultInstance()->valid() === FALSE) {
-                       throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
+                       // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
+                       throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
                } // END - if
 
                // Get next entry
@@ -1826,21 +2084,55 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, TRUE).'</pre>');
 
                // Convert dashes to underscore
-               $fieldName = $this->convertDashesToUnderscores($fieldName);
+               $fieldName2 = $this->convertDashesToUnderscores($fieldName);
 
                // Does the field exist?
-               if (isset($fieldArray[$fieldName])) {
+               if ($this->isFieldSet($fieldName)) {
                        // Get it
-                       $fieldValue = $fieldArray[$fieldName];
+                       $fieldValue = $fieldArray[$fieldName2];
+               } elseif (defined('DEVELOPER')) {
+                       // Missing field entry, may require debugging
+                       self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, TRUE) . '</pre>,fieldName=' . $fieldName . ' not found!');
                } else {
                        // Missing field entry, may require debugging
-                       self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
+                       self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
                }
 
                // Return it
                return $fieldValue;
        }
 
+       /**
+        * Checks if given field is set
+        *
+        * @param       $fieldName      Field name to check
+        * @return      $isSet          Whether the given field name is set
+        * @throws      NullPointerException    If the result instance is null
+        */
+       public function isFieldSet ($fieldName) {
+               // Get result instance
+               $resultInstance = $this->getResultInstance();
+
+               // Is this instance null?
+               if (is_null($resultInstance)) {
+                       // Then the user instance is no longer valid (expired cookies?)
+                       throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+               } // END - if
+
+               // Get current array
+               $fieldArray = $resultInstance->current();
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, TRUE).'</pre>');
+
+               // Convert dashes to underscore
+               $fieldName = $this->convertDashesToUnderscores($fieldName);
+
+               // Determine it
+               $isSet = isset($fieldArray[$fieldName]);
+
+               // Return result
+               return $isSet;
+       }
+
        /**
         * Flushs all pending updates to the database layer
         *
@@ -2100,14 +2392,17 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         *
         * @return      $responseType   Analyzed response type
         */
-       protected function getResponseTypeFromSystem () {
+       protected static function getResponseTypeFromSystem () {
                // Default is console
                $responseType = 'console';
 
                // Is 'HTTP_HOST' set?
                if (isset($_SERVER['HTTP_HOST'])) {
-                       // Then it is a HTTP response/request
-                       $responseType = 'http';
+                       /*
+                        * Then it is a HTML response/request as RSS and so on may be
+                        * transfered over HTTP as well.
+                        */
+                       $responseType = 'html';
                } // END - if
 
                // Return it
@@ -2826,6 +3121,28 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                return $isValid;
        }
 
+       /**
+        * Initializes the web output instance
+        *
+        * @return      void
+        */
+       protected function initWebOutputInstance () {
+               // Get application instance
+               $applicationInstance = Registry::getRegistry()->getInstance('app');
+
+               // Is this a response instance?
+               if ($this instanceof Responseable) {
+                       // Then set it in application instance
+                       $applicationInstance->setResponseInstance($this);
+               } // END - if
+
+               // Init web output instance
+               $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
+
+               // Set it locally
+               $this->setWebOutputInstance($outputInstance);
+       }
+
        /**
         * Translates boolean TRUE to 'Y' and FALSE to 'N'
         *
@@ -2844,250 +3161,120 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
        }
 
        /**
-        * Initializes counter for valid entries, arrays for damaged entries and
-        * an array for gap seek positions. If you call this method on your own,
-        * please re-analyze the file structure. So you are better to call
-        * analyzeFile() instead of this method.
-        *
-        * @return      void
-        */
-       protected function initCountersGapsArray () {
-               // Init counter and seek position
-               $this->setCounter(0);
-               $this->setSeekPosition(0);
-
-               // Init arrays
-               $this->gaps = array();
-               $this->damagedEntries = array();
-       }
-
-       /**
-        * Getter for total entries
-        *
-        * @return      $totalEntries   Total entries in this file
-        */
-       protected final function getCounter () {
-               // Get it
-               return $this->totalEntries;
-       }
-
-       /**
-        * Setter for total entries
+        * Encodes raw data (almost any type) by "serializing" it and then pack it
+        * into a "binary format".
         *
-        * @param       $totalEntries   Total entries in this file
-        * @return      void
-        */
-       protected final function setCounter ($counter) {
-               // Set it
-               $this->totalEntries = $counter;
-       }
-
-       /**
-        * Increment counter
-        *
-        * @return      void
-        */
-       protected final function incrementCounter () {
-               // Get it
-               $this->totalEntries++;
-       }
-
-       /**
-        * Getter for header size
-        *
-        * @return      $totalEntries   Size of file header
-        */
-       protected final function getHeaderSize () {
-               // Get it
-               return $this->headerSize;
-       }
-
-       /**
-        * Setter for header size
-        *
-        * @param       $headerSize             Size of file header
-        * @return      void
-        */
-       protected final function setHeaderSize ($headerSize) {
-               // Set it
-               $this->headerSize = $headerSize;
-       }
-
-       /**
-        * Getter for seek position
-        *
-        * @return      $seekPosition   Current seek position (stored here in object)
-        */
-       protected final function getSeekPosition () {
-               // Get it
-               return $this->seekPosition;
-       }
-
-       /**
-        * Setter for seek position
-        *
-        * @param       $seekPosition   Current seek position (stored here in object)
-        * @return      void
-        */
-       protected final function setSeekPosition ($seekPosition) {
-               // And set it
-               $this->seekPosition = $seekPosition;
-       }
-
-       /**
-        * Updates seekPosition attribute from file to avoid to much access on file.
-        *
-        * @return      void
+        * @param       $rawData        Raw data (almost any type)
+        * @return      $encoded        Encoded data
         */
-       protected function updateSeekPosition () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+       protected function encodeData ($rawData) {
+               // Make sure no objects or resources pass through
+               assert(!is_object($rawData));
+               assert(!is_resource($rawData));
 
-               // Get key (= seek position)
-               $seekPosition = $this->getIteratorInstance()->key();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Setting seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+               // First "serialize" it (json_encode() is faster than serialize())
+               $encoded = $this->packString(json_encode($rawData));
 
-               // And set it here
-               $this->setSeekPosition($seekPosition);
-
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               // And return it
+               return $encoded;
        }
 
        /**
-        * Checks whether the file header is initialized
+        * Pack a string into a "binary format". Please execuse me that this is
+        * widely undocumented. :-(
         *
-        * @return      $isInitialized  Whether the file header is initialized
+        * @param       $str            Unpacked string
+        * @return      $packed         Packed string
+        * @todo        Improve documentation
         */
-       protected function isFileHeaderInitialized () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-               // Default is not initialized
-               $isInitialized = FALSE;
+       protected function packString ($str) {
+               // Debug message
+               //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('str=' . $str . ' - CALLED!');
 
-               // Is the file initialized?
-               if ($this->isFileInitialized()) {
-                       // Some bytes has been written, so rewind to start of it.
-                       $rewindStatus = $this->getIteratorInstance()->rewind();
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] rewindStatus=%s', __METHOD__, __LINE__, $rewindStatus));
+               // First compress the string (gzcompress is okay)
+               $str = gzcompress($str);
 
-                       // Is the rewind() call successfull?
-                       if ($rewindStatus != 1) {
-                               // Something bad happened
-                               self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Could not rewind().', __METHOD__, __LINE__));
-                       } // END - if
+               // Init variable
+               $packed = '';
 
-                       // Read file header
-                       $this->readFileHeader();
+               // And start the "encoding" loop
+               for ($idx = 0; $idx < strlen($str); $idx += $this->packingData[$this->archArrayElement]['step']) {
+                       $big = 0;
+                       for ($i = 0; $i < $this->packingData[$this->archArrayElement]['step']; $i++) {
+                               $factor = ($this->packingData[$this->archArrayElement]['step'] - 1 - $i);
 
-                       // The above method does already check the header
-                       $isInitialized = TRUE;
-               } // END - if
+                               if (($idx + $i) <= strlen($str)) {
+                                       $ord = ord(substr($str, ($idx + $i), 1));
 
-               // Return result
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
-               return $isInitialized;
-       }
-
-       /**
-        * Checks whether the assigned file has been initialized
-        *
-        * @return      $isInitialized          Whether the file's size is zero
-        */
-       protected function isFileInitialized () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+                                       $add = $ord * pow(256, $factor);
 
-               // Get it from iterator which holds the pointer instance. If FALSE is returned
-               $fileSize = $this->getIteratorInstance()->size();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] fileSize=%s', __METHOD__, __LINE__, $fileSize));
+                                       $big += $add;
 
-               /*
-                * The returned file size should not be FALSE or NULL as this means
-                * that the pointer class does not work correctly.
-                */
-               assert(is_int($fileSize));
+                                       //print 'idx=' . $idx . ',i=' . $i . ',ord=' . $ord . ',factor=' . $factor . ',add=' . $add . ',big=' . $big . PHP_EOL;
+                               } // END - if
+                       } // END - for
 
-               // Is more than 0 returned?
-               $isInitialized = ($fileSize > 0);
+                       $l = ($big & $this->packingData[$this->archArrayElement]['left']) >>$this->packingData[$this->archArrayElement]['factor'];
+                       $r = $big & $this->packingData[$this->archArrayElement]['right'];
 
-               // Return result
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
-               return $isInitialized;
-       }
+                       $chunk = str_pad(pack($this->packingData[$this->archArrayElement]['format'], $l, $r), 8, '0', STR_PAD_LEFT);
+                       //* NOISY-DEBUG */ print 'big=' . $big . ',chunk('.strlen($chunk) . ')='.md5($chunk).PHP_EOL;
 
-       /**
-        * Creates the assigned file
-        *
-        * @return      void
-        */
-       protected function createFileHeader () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-               // The file's header should not be initialized here
-               assert(!$this->isFileHeaderInitialized());
-
-               // Simple flush file header which will create it.
-               $this->flushFileHeader();
+                       $packed .= $chunk;
+               } // END - for
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+               // Return it
+               //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('packed=' . $packed . ' - EXIT!');
+               return $packed;
        }
 
        /**
-        * Writes data at given position
+        * Checks whether the given file/path is in open_basedir(). This does not
+        * gurantee that the file is actually readable and/or writeable. If you need
+        * such gurantee then please use isReadableFile() instead.
         *
-        * @param       $seekPosition   Seek position
-        * @param       $data                   Data to be written
-        * @return      void
+        * @param       $filePathName   Name of the file/path to be checked
+        * @return      $isReachable    Whether it is within open_basedir()
         */
-       protected function writeData ($seekPosition, $data) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s,data()=%s - CALLED!', __METHOD__, __LINE__, $seekPosition, strlen($data)));
-
-               // Write data at given position
-               $this->getIteratorInstance()->writeAtPosition($seekPosition, $data);
+       public static function isReachableFilePath ($filePathName) {
+               // Is not reachable by default
+               $isReachable = FALSE;
 
-               // Update seek position
-               $this->updateSeekPosition();
+               // Get open_basedir parameter
+               $openBaseDir = ini_get('open_basedir');
 
-               // Flush header
-               $this->flushHeader();
+               // Is it set?
+               if (!empty($openBaseDir)) {
+                       // Check all entries
+                       foreach (explode(PATH_SEPARATOR, $openBaseDir) as $dir) {
+                               // Check on existence
+                               if (substr($filePathName, 0, strlen($dir)) == $dir) {
+                                       // Is reachable
+                                       $isReachable = TRUE;
+                               } // END - if
+                       } // END - foreach
+               } // END - if
 
-               // Seek to old position
-               $this->seekToOldPosition();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               // Return status
+               return $isReachable;
        }
 
        /**
-        * Pre-allocates file (if enabled) with some space for later faster write access.
+        * Checks whether the give file is within open_basedir() (done by
+        * isReachableFilePath()), is actually a file and is readable.
         *
-        * @param       $type   Type of the file
-        * @return      void
+        * @param       $fileName               Name of the file to be checked
+        * @return      $isReadable             Whether the file is readable (and therefor exists)
         */
-       protected function preAllocateFile ($type) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-
-               // Is it enabled?
-               if ($this->getConfigInstance()->getConfigEntry($type . '_pre_allocate_enabled') != 'Y') {
-                       // Not enabled
-                       self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Not pre-allocating file.', __METHOD__, __LINE__));
-
-                       // Don't continue here.
-                       return;
-               } // END - if
-
-               // Message to user
-               self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Pre-allocating file ...', __METHOD__, __LINE__));
-
-               /*
-                * Calculate minimum length for one entry:
-                * minimum length = hash length + separator + name + minimum entry size = ?? + 1 + 10 + 1 = ??
-                */
-               $minLengthEntry = self::getHashLength() + strlen(self::SEPARATOR_HASH_NAME) + self::LENGTH_NAME + 1;
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] minLengthEntry=%s', __METHOD__, __LINE__, $minLengthEntry));
-
-               // Calulcate seek position
-               $seekPosition = $minLengthEntry * $this->getConfigInstance()->getConfigEntry($type . '_pre_allocate_count');
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+       public static function isReadableFile ($fileName) {
+               // Default is not readable
+               $isReadable = FALSE;
 
-               // Now simply write a NUL there. This will pre-allocate the file.
-               $this->writeData($seekPosition, chr(0));
+               // Is within parameters, so check if it is a file and readable
+               $isReadable = ((self::isReachableFilePath($fileName)) && (is_file($fileName)) && (is_readable($fileName)));
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               // Return status
+               return $isReadable;
        }
 }