Introduced rewineUpdateSeekPosition() which needs to be called after
[core.git] / inc / classes / main / class_BaseFrameworkSystem.php
index 0041d37dd2d66d50302e42a7a8065c4c2b49c8ed..b8bca94329e55388d099e512cd3273901a55b94b 100644 (file)
@@ -512,7 +512,7 @@ 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)
                ));
        }
 
@@ -2913,6 +2913,27 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                $this->headerSize = $headerSize;
        }
 
+       /**
+        * Getter for header array
+        *
+        * @return      $totalEntries   Size of file header
+        */
+       protected final function getHeade () {
+               // Get it
+               return $this->header;
+       }
+
+       /**
+        * Setter for header
+        *
+        * @param       $header         Array for a file header
+        * @return      void
+        */
+       protected final function setHeader (array $header) {
+               // Set it
+               $this->header = $header;
+       }
+
        /**
         * Getter for seek position
         *
@@ -2940,77 +2961,16 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         * @return      void
         */
        protected function updateSeekPosition () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
 
                // Get key (= seek position)
                $seekPosition = $this->getIteratorInstance()->key();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Setting seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Setting seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
 
                // And set it here
                $this->setSeekPosition($seekPosition);
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
-       }
-
-       /**
-        * Reads the file header
-        *
-        * @return      void
-        */
-       protected 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->getHeaderSize());
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Read %d bytes (%d wanted).', __METHOD__, __LINE__, strlen($data), $this->getHeaderSize()));
-
-               // Have all requested bytes been read?
-               assert(strlen($data) == $this->getHeaderSize());
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-
-               // Last character must be the separator
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] data(-1)=%s', __METHOD__, __LINE__, dechex(ord(substr($data, -1, 1)))));
-               assert(substr($data, -1, 1) == chr(self::SEPARATOR_HEADER_ENTRIES));
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-
-               // 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(chr(self::SEPARATOR_HEADER_DATA), $data);
-
-               // Check if the array has only 3 elements
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] header(%d)=%s', __METHOD__, __LINE__, count($this->header), print_r($this->header, TRUE)));
-               assert(count($this->header) == 3);
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-
-               // Check magic
-               assert($this->header[0] == self::STACK_MAGIC);
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-
-               // Check length of count and seek position
-               assert(strlen($this->header[1]) == self::LENGTH_COUNT);
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-               assert(strlen($this->header[2]) == self::LENGTH_POSITION);
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Passed assert().', __METHOD__, __LINE__));
-
-               // 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__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
        /**
@@ -3019,7 +2979,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         * @return      $isInitialized  Whether the file header is initialized
         */
        protected function isFileHeaderInitialized () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // Is the method there?
+               assert(is_callable(array($this, 'readFileHeader')));
+
                // Default is not initialized
                $isInitialized = FALSE;
 
@@ -3027,7 +2991,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                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));
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] rewindStatus=%s', __METHOD__, __LINE__, $rewindStatus));
 
                        // Is the rewind() call successfull?
                        if ($rewindStatus != 1) {
@@ -3043,7 +3007,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                } // END - if
 
                // Return result
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -3053,11 +3017,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         * @return      $isInitialized          Whether the file's size is zero
         */
        protected function isFileInitialized () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
 
                // 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));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] fileSize=%s', __METHOD__, __LINE__, $fileSize));
 
                /*
                 * The returned file size should not be FALSE or NULL as this means
@@ -3069,7 +3033,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                $isInitialized = ($fileSize > 0);
 
                // Return result
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -3079,49 +3043,56 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         * @return      void
         */
        protected function createFileHeader () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // The method flushFileHeader() must be callable
+               assert(is_callable(array($this, 'flushFileHeader')));
+
                // The file's header should not be initialized here
                assert(!$this->isFileHeaderInitialized());
 
                // Simple flush file header which will create it.
                $this->flushFileHeader();
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+               // Rewind seek position (to beginning of file) and update/flush file header
+               $this->rewineUpdateSeekPosition();
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
        }
 
        /**
-        * Flushes the file header
+        * Seeks to beginning of file, updates seek position in this object and
+        * flushes the header.
         *
         * @return      void
         */
-       protected function flushFileHeader () {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-
-               // Put all informations together
-               $header = sprintf('%s%s%s%s%s%s',
-                       // Magic
-                       self::STACK_MAGIC,
+       protected function rewineUpdateSeekPosition () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
 
-                       // Separator magic<->count
-                       chr(self::SEPARATOR_HEADER_DATA),
+               // Seek to beginning of file
+               $this->getIteratorInstance()->rewind();
 
-                       // Total entries (will be zero) and pad it to 20 chars
-                       str_pad($this->dec2hex($this->getCounter()), self::LENGTH_COUNT, '0', STR_PAD_LEFT),
+               // And update seek position ...
+               $this->updateSeekPosition();
 
-                       // Separator count<->seek position
-                       chr(self::SEPARATOR_HEADER_DATA),
+               // ... to write it back into the file
+               $this->flushFileHeader();
 
-                       // Position (will be zero)
-                       str_pad($this->dec2hex($this->getSeekPosition(), 2), self::LENGTH_POSITION, '0', STR_PAD_LEFT),
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+       }
 
-                       // Separator position<->entries
-                       chr(self::SEPARATOR_HEADER_ENTRIES)
-               );
+       /**
+        * Seeks to old position
+        *
+        * @return      void
+        */
+       protected function seekToOldPosition () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
 
-               // Write it to disk (header is always at seek position 0)
-               $this->writeData(0, $header);
+               // Seek to currently ("old") saved position
+               $this->getIteratorInstance()->seek($this->getSeekPosition());
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
        }
 
        /**
@@ -3129,10 +3100,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         *
         * @param       $seekPosition   Seek position
         * @param       $data                   Data to be written
+        * @param       $flushHeader    Whether to flush the header (default: flush)
         * @return      void
         */
-       protected function writeData ($seekPosition, $data) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s,data()=%s - CALLED!', __METHOD__, __LINE__, $seekPosition, strlen($data)));
+       protected function writeData ($seekPosition, $data, $flushHeader = TRUE) {
+               /* 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);
@@ -3140,12 +3112,16 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                // Update seek position
                $this->updateSeekPosition();
 
-               // Flush header
-               $this->flushHeader();
+               // Flush the header?
+               if ($flushHeader === TRUE) {
+                       // Flush header
+                       $this->flushFileHeader();
+
+                       // Seek to old position
+                       $this->seekToOldPosition();
+               } // END - if
 
-               // Seek to old position
-               $this->seekToOldPosition();
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
        /**
@@ -3155,7 +3131,10 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
         * @return      void
         */
        protected function preAllocateFile ($type) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // caluclateMinimumFileEntryLength() must be callable
+               assert(is_callable(array($this, 'caluclateMinimumFileEntryLength')));
 
                // Is it enabled?
                if ($this->getConfigInstance()->getConfigEntry($type . '_pre_allocate_enabled') != 'Y') {
@@ -3169,21 +3148,21 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
                // 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));
+               // Calculate minimum length for one entry
+               $minLengthEntry = $this->caluclateMinimumFileEntryLength();
+               /* 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));
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
 
                // Now simply write a NUL there. This will pre-allocate the file.
                $this->writeData($seekPosition, chr(0));
 
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+               // Rewind seek position (to beginning of file) and update/flush file header
+               $this->rewineUpdateSeekPosition();
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 }