From: Roland Haeder Date: Sun, 18 May 2014 08:53:04 +0000 (+0200) Subject: Add stuff for reading header of a file-based stack. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=603435f373f9d92dc4576d816dd4d6e18c8da05b;p=core.git Add stuff for reading header of a file-based stack. Signed-off-by: Roland Häder --- diff --git a/contrib/file_stack/format.txt b/contrib/file_stack/format.txt index cb8c07ee..336428db 100644 --- a/contrib/file_stack/format.txt +++ b/contrib/file_stack/format.txt @@ -9,7 +9,7 @@ Purpose: | "magic" | separator | count | separator | position | separator | ---------+-----------+-----------+----------+-----------+------0---+-----------+ Bytes: | 9 | 1 | 20 (hex) | 1 | 20 (hex) | 1 | ---------+-----------+-----------+----------+-----------+----------+-----------+ -Example: | STACKv1.0 | 01 | 00...ff | 02 | 00...ff | 03 | +Example: | STACKv1.0 | 01 | 00...ff | 01 | 00...ff | 02 | Continued: @@ -17,7 +17,7 @@ Purpose: | hash 0 | separator | name 0 | entry 0 | hash n | separator | name ---------+--------+-----------+--------+------------+--------+-----------+--------+------------+-----+ Bytes: | 64 | 1 | 10 | 1-n (pack) | 64 | 1 | 10 | 1-n (pack) | 1 | ---------+--------+-----------+--------+------------+--------+-----------+--------+------------+-----+ -Example: | abc | 04 | foo | ... | abc | 04 | bar | ... | EOF | +Example: | abc | 03 | foo | ... | abc | 03 | bar | ... | EOF | Explanations: ------------- diff --git a/inc/classes/interfaces/io/pointer/class_InputPointer.php b/inc/classes/interfaces/io/pointer/class_InputPointer.php index 1d67cd24..0c15cc7b 100644 --- a/inc/classes/interfaces/io/pointer/class_InputPointer.php +++ b/inc/classes/interfaces/io/pointer/class_InputPointer.php @@ -31,6 +31,14 @@ interface InputPointer extends StreamableInput { * @throws InvalidResourceException If there is being set */ function readFromFile (); + + /** + * Reads given amount of bytes from file. + * + * @param $bytes Amount of bytes to read + * @return $data Data read from file + */ + function read ($bytes); } // [EOF] diff --git a/inc/classes/interfaces/iterator/class_SeekableWritableFileIterator.php b/inc/classes/interfaces/iterator/class_SeekableWritableFileIterator.php index 1dde2c27..abd1e583 100644 --- a/inc/classes/interfaces/iterator/class_SeekableWritableFileIterator.php +++ b/inc/classes/interfaces/iterator/class_SeekableWritableFileIterator.php @@ -46,6 +46,14 @@ interface SeekableWritableFileIterator extends SeekableIterator { * @return void */ function writeAtPosition ($seedPosition, $data); + + /** + * Reads given amount of bytes from file. + * + * @param $bytes Amount of bytes to read + * @return $data Data read from file + */ + function read ($bytes); } // [EOF] diff --git a/inc/classes/main/file_directories/io/class_FrameworkFileInputOutputPointer.php b/inc/classes/main/file_directories/io/class_FrameworkFileInputOutputPointer.php index 198c5b09..073c2c7f 100644 --- a/inc/classes/main/file_directories/io/class_FrameworkFileInputOutputPointer.php +++ b/inc/classes/main/file_directories/io/class_FrameworkFileInputOutputPointer.php @@ -75,7 +75,7 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP } /** - * Read data a file pointer + * Read 1024 bytes data from a file pointer * * @return mixed The result of fread() * @throws NullPointerException If the file pointer instance @@ -92,7 +92,7 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP } // Read data from the file pointer and return it - return fread($this->getPointer(), 1024); + return $this->read(1024); } /** @@ -139,6 +139,23 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP // Move the file pointer return fseek($this->getPointer(), $seekPosition, $whence); } + + /** + * Reads given amount of bytes from file. + * + * @param $bytes Amount of bytes to read + * @return $data Data read from file + */ + public function read ($bytes) { + // Try to read given characters + $data = fread($this->getPointer(), $bytes); + + // Was this successfull? + assert(is_string($data)); + + // Then return it + return $data; + } } // [EOF] diff --git a/inc/classes/main/iterator/io/class_FileIoIterator.php b/inc/classes/main/iterator/io/class_FileIoIterator.php index af4c1b47..e6aee1d9 100644 --- a/inc/classes/main/iterator/io/class_FileIoIterator.php +++ b/inc/classes/main/iterator/io/class_FileIoIterator.php @@ -93,6 +93,17 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato return $this->getPointerInstance()->rewind(); } + /** + * Checks wether the current entry is valid (not at the end of the file). + * This method will return TRUE if an emptied (nulled) entry has been found. + * + * @return void + */ + public function valid () { + // Call pointer instance + return $this->getPointerInstance()->valid(); + } + /** * Seeks to given position * @@ -133,13 +144,14 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato } /** - * Checks wether the current entry is valid (not at the end of the file). - * This method will return TRUE if an emptied (nulled) entry has been found. + * Reads given amount of bytes from file. * - * @return void + * @param $bytes Amount of bytes to read + * @return $data Data read from file */ - public function valid () { - $this->partialStub('Please implement this method.'); + public function read ($bytes) { + // Call pointer instance + return $this->getPointerInstance()->read($bytes); } } diff --git a/inc/classes/main/stacker/file/class_BaseFileStack.php b/inc/classes/main/stacker/file/class_BaseFileStack.php index dd8570c4..0485b12c 100644 --- a/inc/classes/main/stacker/file/class_BaseFileStack.php +++ b/inc/classes/main/stacker/file/class_BaseFileStack.php @@ -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