Add stuff for reading header of a file-based stack.
[core.git] / inc / classes / main / stacker / file / class_BaseFileStack.php
index dd8570c45185aeb0f202bb0452221f093ae3c27a..0485b12c20e84eca7e73b8e00dd14ca7fd753468 100644 (file)
@@ -28,39 +28,34 @@ class BaseFileStack extends BaseStacker {
        const STACK_MAGIC = 'STACKv0.1';
 
        /**
-        * Separator magic->count
+        * Separator for header data
         */
-       const SEPARATOR_MAGIC_COUNT = 0x01;
+       const SEPARATOR_HEADER_DATA = 0x01;
 
        /**
-        * Separator count->position
+        * Separator header->entries
         */
-       const SEPARATOR_COUNT_SEEK_POS = 0x02;
-
-       /**
-        * Separator position->entries
-        */
-       const SEPARATOR_SEEK_POS_ENTRIES = 0x03;
+       const SEPARATOR_HEADER_ENTRIES = 0x02;
 
        /**
         * Separator hash->name
         */
-       const SEPARATOR_HASH_NAME = 0x04;
+       const SEPARATOR_HASH_NAME = 0x03;
 
        /**
         * Length of name
         */
-       const COUNT_NAME = 10;
+       const LENGTH_NAME = 10;
 
        /**
         * Length of count
         */
-       const COUNT_LENGTH = 20;
+       const LENGTH_COUNT = 20;
 
        /**
         * Length of position
         */
-       const COUNT_POSITION = 20;
+       const LENGTH_POSITION = 20;
 
        /**
         * Counter for total entries
@@ -72,6 +67,16 @@ class BaseFileStack extends BaseStacker {
         */
        private $seekPosition = 0;
 
+       /**
+        * Size of header
+        */
+       private $headerSize = 0;
+
+       /**
+        * File header
+        */
+       private $header = array();
+
        /**
         * Protected constructor
         *
@@ -81,6 +86,16 @@ class BaseFileStack extends BaseStacker {
        protected function __construct ($className) {
                // Call parent constructor
                parent::__construct($className);
+
+               // Calculate header size
+               $this->headerSize =
+                       strlen(self::MAGIC) +
+                       strlen(self::SEPARATOR_HEADER_DATA) +
+                       self::LENGTH_COUNT +
+                       strlen(self::SEPARATOR_HEADER_DATA) +
+                       self::LENGTH_POSITION +
+                       strlen(self::SEPARATOR_HEADER_ENTRIES)
+               );
        }
 
        /**
@@ -142,6 +157,55 @@ class BaseFileStack extends BaseStacker {
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
+       /**
+        * Reads the file header
+        *
+        * @return      void
+        */
+       private function readFileHeader () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // First rewind to beginning as the header sits at the beginning ...
+               $this->getIteratorInstance()->rewind();
+
+               // Then read it (see constructor for calculation)
+               $data = $this->getIteratorInstance()->read($this->headerLength);
+
+               // Last character must be the separator
+               assert(substr($data, -1, 1) == self::SEPARATOR_HEADER_ENTRIES);
+
+               // Okay, then remove it
+               $data = substr($data, 0, -1);
+
+               // And update seek position
+               $this->updateSeekPosition();
+
+               /*
+                * Now split it:
+                *
+                * 0 => Magic
+                * 1 => Total entries
+                * 2 => Current seek position
+                */
+               $this->header = explode(self::SEPARATOR_HEADER_DATA, $data);
+
+               // Check if the array has only 3 elements
+               assert(count($this->header) == 3);
+
+               // Check magic
+               assert($this->header[0] == self::MAGIC);
+
+               // Check length of count and seek position
+               assert(strlen($this->header[1]) == self::LENGTH_COUNT);
+               assert(strlen($this->header[2]) == self::LENGTH_POSITION);
+
+               // Decode count and seek position
+               $this->header[1] = hex2bin($this->header[1]);
+               $this->header[2] = hex2bin($this->header[2]);
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+       }
+
        /**
         * Checks whether the file header is initialized
         *
@@ -166,6 +230,8 @@ class BaseFileStack extends BaseStacker {
 
                        // Read file header
                        $this->readFileHeader();
+
+                       // Check if its format is valid.
                } // END - if
 
                // Return result
@@ -229,19 +295,19 @@ class BaseFileStack extends BaseStacker {
                        self::STACK_MAGIC,
 
                        // Separator magic<->count
-                       chr(self::SEPARATOR_MAGIC_COUNT),
+                       chr(self::SEPARATOR_HEADER_DATA),
 
                        // Total entries (will be zero) and pad it to 20 chars
-                       str_pad($this->dec2hex($this->getCounter()), self::COUNT_LENGTH, '0', STR_PAD_LEFT),
+                       str_pad($this->dec2hex($this->getCounter()), self::LENGTH_COUNT, '0', STR_PAD_LEFT),
 
                        // Separator count<->seek position
-                       chr(self::SEPARATOR_COUNT_SEEK_POS),
+                       chr(self::SEPARATOR_HEADER_DATA),
 
                        // Position (will be zero)
-                       str_pad($this->dec2hex($this->getSeekPosition(), 2), self::COUNT_POSITION, '0', STR_PAD_LEFT),
+                       str_pad($this->dec2hex($this->getSeekPosition(), 2), self::LENGTH_POSITION, '0', STR_PAD_LEFT),
 
                        // Separator position<->entries
-                       chr(self::SEPARATOR_SEEK_POS_ENTRIES)
+                       chr(self::SEPARATOR_HEADER_ENTRIES)
                );
 
                // Write it to disk (header is always at seek position 0)
@@ -293,7 +359,7 @@ class BaseFileStack extends BaseStacker {
                 * 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::COUNT_NAME + 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