X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=framework%2Fmain%2Fclasses%2Fstacker%2Ffile%2Fclass_BaseFileStack.php;h=303caca77c7666d0f91e05b18640b50d3c199cc7;hb=HEAD;hp=1960259d04732e4c089505674822aca946646acc;hpb=9aafc2b0b062e10d0fa5d61bfb551938fcf422e2;p=core.git diff --git a/framework/main/classes/stacker/file/class_BaseFileStack.php b/framework/main/classes/stacker/file/class_BaseFileStack.php index 1960259d..303caca7 100644 --- a/framework/main/classes/stacker/file/class_BaseFileStack.php +++ b/framework/main/classes/stacker/file/class_BaseFileStack.php @@ -1,19 +1,23 @@ * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team * @license GNU GPL 3.0 or any newer version * @link http://www.ship-simu.org * @@ -40,33 +44,17 @@ use \UnexpectedValueException; * along with this program. If not, see . */ abstract class BaseFileStack extends BaseStacker { + // Load traits + use IndexableTrait; + use IteratorTrait; + // Exception codes const EXCEPTION_BAD_MAGIC = 0xe100; /** - * Magic for this stack - */ - const STACK_MAGIC = 'STACKv0.1'; - - /** - * Name of array index for gap position - */ - const ARRAY_INDEX_GAP_POSITION = 'gap'; - - /** - * Name of array index for hash - */ - const ARRAY_INDEX_HASH = 'hash'; - - /** - * Name of array index for length of raw data - */ - const ARRAY_INDEX_DATA_LENGTH = 'length'; - - /** - * An instance of an Indexable class + * Minimum block length */ - private $indexInstance = NULL; + private static $minimumBlockLength = 0; /** * Protected constructor @@ -79,25 +67,6 @@ abstract class BaseFileStack extends BaseStacker { parent::__construct($className); } - /** - * Setter for Indexable instance - * - * @param $indexInstance An instance of an Indexable class - * @return void - */ - protected final function setIndexInstance (Indexable $indexInstance) { - $this->indexInstance = $indexInstance; - } - - /** - * Getter for Indexable instance - * - * @return $indexInstance An instance of an Indexable class - */ - public final function getIndexInstance () { - return $this->indexInstance; - } - /** * Reads the file header * @@ -106,40 +75,49 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnexpectedValueException If header is not proper length * @throws InvalidMagicException If a bad magic was found */ - public function readFileHeader () { + public function readStackHeader () { // First rewind to beginning as the header sits at the beginning ... - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: CALLED!', __METHOD__, __LINE__)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: CALLED!'); $this->getIteratorInstance()->rewind(); + // Get header size + $headerSize = $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize(); + // Then read it (see constructor for calculation) - $data = $this->getIteratorInstance()->read($this->getIteratorInstance()->getHeaderSize()); - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getHeaderSize())); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: headerSize=%d', $headerSize)); + $data = $this->getIteratorInstance()->getBinaryFileInstance()->read($headerSize); // Have all requested bytes been read? - if (strlen($data) != $this->getIteratorInstance()->getHeaderSize()) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize())); + if (strlen($data) != $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize()) { // Bad data length throw new UnexpectedValueException(sprintf('data(%d)=%s does not match iteratorInstance->headerSize=%d', strlen($data), $data, - $this->getIteratorInstance()->getHeaderSize() - )); + $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize() + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); + } elseif (empty(trim($data, chr(0)))) { + // Empty header, file is freshly pre-allocated + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Empty file header detected - EXIT!'); + return; } // Last character must be the separator - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: data(-1)=%s', dechex(ord(substr($data, -1, 1))))); - if (substr($data, -1, 1) !== chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: data(-1)=0x%s', dechex(ord(substr($data, -1, 1))))); + if (substr($data, -1, 1) !== chr(BinaryFile::SEPARATOR_HEADER_ENTRIES)) { // Not valid separator - throw new UnexpectedValueException(sprintf('data=%s does not have separator=%s at the end.', + throw new UnexpectedValueException(sprintf('data=%s does not have separator=0x%s at the end.', $data, - BaseBinaryFile::SEPARATOR_HEADER_ENTRIES - )); + dechex(BinaryFile::SEPARATOR_HEADER_ENTRIES) + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); } // Okay, then remove it $data = substr($data, 0, -1); // And update seek position - $this->getIteratorInstance()->updateSeekPosition(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->iteratorInstance->binaryFileInstance->updateSeekPosition() ...'); + $this->getIteratorInstance()->getBinaryFileInstance()->updateSeekPosition(); /* * Now split it: @@ -148,47 +126,56 @@ abstract class BaseFileStack extends BaseStacker { * 1 => total entries * 2 => current seek position */ - $header = explode(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), $data); + $header = explode(chr(BinaryFile::SEPARATOR_HEADER_DATA), $data); - // Set header here - $this->getIteratorInstance()->setHeader($header); + // Map numeric indexes to associative indexes + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Invoking ArrayUtils::mapNumericKeysToAssociative(%d) ...', count($header))); + $header = ArrayUtils::mapNumericKeysToAssociative($header, [ + BinaryFile::HEADER_NAME_MAGIC, + BinaryFile::HEADER_NAME_TOTAL_ENTRIES, + BinaryFile::HEADER_NAME_SEEK_POSITION, + ]); // Check if the array has only 3 elements - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: header(%d)=%s', count($header), print_r($header, true))); - if (count($header) != 3) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: HEADER_STACK_ELEMENT_COUNT=%d,header()=%d', BinaryFile::HEADER_STACK_ELEMENT_COUNT, count($header))); + //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: HEADER_STACK_ELEMENT_COUNT=%d,header(%d)=%s', BinaryFile::HEADER_STACK_ELEMENT_COUNT, count($header), print_r($header, true))); + if (count($header) != BinaryFile::HEADER_STACK_ELEMENT_COUNT) { // Header array count is not expected - throw new UnexpectedValueException(sprintf('data=%s has %d elements, expected 3', + throw new UnexpectedValueException(sprintf('data=%s has %d elements, but expected is %d', $data, - count($header) - )); - } elseif ($header[0] != self::STACK_MAGIC) { + count($header), + BinaryFile::HEADER_STACK_ELEMENT_COUNT + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); + } elseif ($header[BinaryFile::HEADER_NAME_MAGIC] != StackableFile::STACK_MAGIC) { // Bad magic throw new InvalidMagicException($data, self::EXCEPTION_BAD_MAGIC); - } - - // Check length of count and seek position - if (strlen($header[1]) != BaseBinaryFile::LENGTH_COUNT) { + } elseif (strlen($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]) != BinaryFile::LENGTH_COUNT) { // Count length not valid - throw new UnexpectedValueException(sprintf('header[1](%d)=%s is not expected %d length', - strlen($header[1]), - $header[1], - BaseBinaryFile::LENGTH_COUNT - )); - } elseif (strlen($header[1]) != BaseBinaryFile::LENGTH_POSITION) { + throw new UnexpectedValueException(sprintf('header[%s](%d)=%s is not expected %d length', + BinaryFile::HEADER_NAME_TOTAL_ENTRIES, + strlen($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]), + $header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES], + BinaryFile::LENGTH_COUNT + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); + } elseif (strlen($header[BinaryFile::HEADER_NAME_SEEK_POSITION]) != BinaryFile::LENGTH_POSITION) { // Position length not valid - throw new UnexpectedValueException(sprintf('header[2](%d)=%s is not expected %d length', - strlen($header[1]), - $header[1], - BaseBinaryFile::LENGTH_POSITION - )); + throw new UnexpectedValueException(sprintf('header[%s](%d)=%s is not expected %d length', + BinaryFile::HEADER_NAME_SEEK_POSITION, + strlen($header[BinaryFile::HEADER_NAME_SEEK_POSITION]), + $header[BinaryFile::HEADER_NAME_SEEK_POSITION], + BinaryFile::LENGTH_POSITION + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); } // Decode count and seek position - $header[1] = hex2bin($header[1]); - $header[2] = hex2bin($header[2]); + $header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES] = hex2bin($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]); + $header[BinaryFile::HEADER_NAME_SEEK_POSITION] = hex2bin($header[BinaryFile::HEADER_NAME_SEEK_POSITION]); + + // Set header here + $this->getIteratorInstance()->getBinaryFileInstance()->setHeader($header); // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: EXIT!', __METHOD__, __LINE__)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: EXIT!'); } /** @@ -198,32 +185,33 @@ abstract class BaseFileStack extends BaseStacker { */ public function flushFileHeader () { // Put all informations together - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: CALLED!', __METHOD__, __LINE__)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: CALLED!'); $header = sprintf('%s%s%s%s%s%s', // Magic - self::STACK_MAGIC, + StackableFile::STACK_MAGIC, // Separator magic<->count - chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), + chr(BinaryFile::SEPARATOR_HEADER_DATA), - // Total entries (will be zero) and pad it to 20 chars - str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getCounter()), BaseBinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT), + // Padded total entries + str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getBinaryFileInstance()->getCounter()), BinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT), // Separator count<->seek position - chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), + chr(BinaryFile::SEPARATOR_HEADER_DATA), - // Position (will be zero) - str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getSeekPosition(), 2), BaseBinaryFile::LENGTH_POSITION, '0', STR_PAD_LEFT), + // Padded seek position + str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getBinaryFileInstance()->getSeekPosition(), 2), BinaryFile::LENGTH_POSITION, '0', STR_PAD_LEFT), // Separator position<->entries - chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES) + chr(BinaryFile::SEPARATOR_HEADER_ENTRIES) ); // Write it to disk (header is always at seek position 0) - $this->getIteratorInstance()->writeData(0, $header, false); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Invoking this->iteratorInstance->writeAtPosition(0, header=%s) ...', $header)); + $this->getIteratorInstance()->getBinaryFileInstance()->writeAtPosition(0, $header); // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: EXIT!', __METHOD__, __LINE__)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: EXIT!'); } /** @@ -232,55 +220,88 @@ abstract class BaseFileStack extends BaseStacker { * @param $fileInfoInstance An instance of a SplFileInfo class * @param $type Type of this stack (e.g. url_source for URL sources) * @return void + * @throws InvalidArgumentException If a parameter is invalid * @todo Currently the stack file is not cached, please implement a memory-handling class and if enough RAM is found, cache the whole stack file. */ protected function initFileStack (SplFileInfo $fileInfoInstance, string $type) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: fileInfoInstance[%s]=%s,type=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance, $type)); + if (empty($type)) { + // Invalid parameter + throw new InvalidArgumentException('Parameter "type" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Get a stack file instance - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: fileInfoInstance=%s,type=%s - CALLED!', $fileInfoInstance, $type)); - $fileInstance = ObjectFactory::createObjectByConfiguredName('stack_file_class', array($fileInfoInstance, $this)); + $stackInstance = ObjectFactory::createObjectByConfiguredName('stack_file_class', array($fileInfoInstance, $this)); // Get iterator instance - $iteratorInstance = ObjectFactory::createObjectByConfiguredName('file_iterator_class', array($fileInstance)); + $iteratorInstance = ObjectFactory::createObjectByConfiguredName('file_iterator_class', array($stackInstance)); // Set iterator here $this->setIteratorInstance($iteratorInstance); // Calculate header size - $this->getIteratorInstance()->setHeaderSize( - strlen(self::STACK_MAGIC) + - strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA)) + - BaseBinaryFile::LENGTH_COUNT + - strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA)) + - BaseBinaryFile::LENGTH_POSITION + - strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) + $headerSize = ( + strlen(StackableFile::STACK_MAGIC) + + strlen(chr(BinaryFile::SEPARATOR_HEADER_DATA)) + + BinaryFile::LENGTH_COUNT + + strlen(chr(BinaryFile::SEPARATOR_HEADER_DATA)) + + BinaryFile::LENGTH_POSITION + + strlen(chr(BinaryFile::SEPARATOR_HEADER_ENTRIES)) ); - // Init counters and gaps array - $this->getIteratorInstance()->initCountersGapsArray(); + // Setting it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Setting headerSize=%d ...', $headerSize)); + $this->getIteratorInstance()->getBinaryFileInstance()->setHeaderSize($headerSize); - // Is the file's header initialized? - if (!$this->getIteratorInstance()->isFileHeaderInitialized()) { - // No, then create it (which may pre-allocate the stack) - $this->getIteratorInstance()->createFileHeader(); - - // And pre-allocate a bit - $this->getIteratorInstance()->preAllocateFile('file_stack'); - } - - // Load the file header - $this->readFileHeader(); - - // Count all entries in file - $this->getIteratorInstance()->analyzeFile(); + // Init counters and gaps array + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->iteratorInstance->initCountersGapsArray() ...'); + $this->getIteratorInstance()->getBinaryFileInstance()->initCountersGapsArray(); /* * Get stack index instance. This can be used for faster * "defragmentation" and startup. */ + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Creating index instance for fileInfoInstance[%s]=%s,type=%s ...', get_class($fileInfoInstance), $fileInfoInstance, $type)); $indexInstance = FileStackIndexFactory::createFileStackIndexInstance($fileInfoInstance, $type); // And set it here + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: indexInstance=%s', $indexInstance->__toString())); $this->setIndexInstance($indexInstance); + + // Is the file's header initialized? + if (!$this->getIteratorInstance()->getBinaryFileInstance()->isFileHeaderInitialized()) { + // First pre-allocate a bit + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->iteratorInstance->preAllocateFile(file_stack) ...'); + $this->getIteratorInstance()->getBinaryFileInstance()->preAllocateFile('file_stack'); + + // Then create file header + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: this->iteratorInstance->createFileHeader() ...'); + $this->getIteratorInstance()->getBinaryFileInstance()->createFileHeader(); + } + + // Load the file header + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->readStackHeader() ...'); + $this->readStackHeader(); + + // Is the index loaded correctly, e.g. the stack file is just created? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->indexInstance->isIndexLoaded() ...'); + if (!$this->getIndexInstance()->isIndexLoaded()) { + /* + * Something horrible has happened to the index as it should be + * loaded at this point. The stack's file structure then needs to + * be analyzed and the index rebuild. + */ + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Invoking this->iteratorInstance->analyzeFileStructure() ...'); + $this->getIteratorInstance()->getBinaryFileInstance()->analyzeFileStructure(); + + // Rebuild index from file + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Invoking this->iteratorInstance->rebuildIndexFromStack(%s) ...', $this->__toString())); + $this->getIndexInstance()->rebuildIndexFromStack($this); + } + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: EXIT!'); } /** @@ -290,14 +311,19 @@ abstract class BaseFileStack extends BaseStacker { * @param $value Value to add to this stacker * @return void * @throws FullStackerException If the stack is full + * @throws InvalidArgumentException If a parameter is not valid * @throws InvalidArgumentException Not all variable types are wanted here */ - protected function addValue (string $stackerName, $value) { - // Do some tests - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('stackerName=%s,value[%s]=%s - CALLED!', $stackerName, gettype($value), print_r($value, true))); - if ($this->isStackFull($stackerName)) { + protected function addValueToStack (string $stackerName, $value) { + // Validate parameter + /* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s,value[]=%s - CALLED!', $stackerName, gettype($value))); + //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s,value[%s]=%s', $stackerName, gettype($value), print_r($value, true))); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif ($this->isStackFull($stackerName)) { // Stacker is full - throw new FullStackerException(array($this, $stackerName, $value), self::EXCEPTION_STACKER_IS_FULL); + throw new BadMethodCallException(sprintf('stackerName=%s is full but method call.', $stackerName), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL); } elseif (is_resource($value) || is_object($value)) { // Not wanted type throw new InvalidArgumentException(sprintf('value[]=%s is not supported', gettype($value))); @@ -307,10 +333,16 @@ abstract class BaseFileStack extends BaseStacker { * Now add the value to the file stack which returns gap position, a * hash and length of the raw data. */ - $data = $this->getIteratorInstance()->writeValueToFile($stackerName, $value); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Invoking this->iteratorInstance->binaryFileInstance->writeValueToFile(%s,value[]=%s) ...', $stackerName, gettype($value))); + $data = $this->getIteratorInstance()->getBinaryFileInstance()->writeValueToFile($stackerName, $value); // Add the hash and gap position to the index - $this->getIndexInstance()->addHashToIndex($stackerName, $data); + //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: data=%s', print_r($data, true)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: Invoking this->indexInstance->addHashedDataToIndex(%s,data()=%d) ...', $stackerName, count($data))); + $this->getIndexInstance()->addHashedDataToIndex($stackerName, $data); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: EXIT!'); } /** @@ -318,20 +350,26 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $value Value of last added value - * @throws EmptyStackerException If the stack is empty + * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If the stack is empty */ protected function getLastValue (string $stackerName) { - // Is the stack not yet initialized or full? - if ($this->isStackEmpty($stackerName)) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif ($this->isStackEmpty($stackerName)) { // Throw an exception - throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY); - } // END - if + throw new BadMethodCallException([$this, $stackerName], FrameworkInterface::EXCEPTION_BAD_METHOD_CALL); + } // Now get the last value - /* NOISY-DEBUG: */ $this->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); + /* NOISY-DEBUG: */ DebugMiddleware::getSelfInstance()->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); $value = NULL; // Return it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: value[]=%s - EXIT!', gettype($value))); return $value; } @@ -340,20 +378,26 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $value Value of last added value - * @throws EmptyStackerException If the stack is empty + * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If the stack is empty */ protected function getFirstValue (string $stackerName) { - // Is the stack not yet initialized or full? - if ($this->isStackEmpty($stackerName)) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif ($this->isStackEmpty($stackerName)) { // Throw an exception - throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY); - } // END - if + throw new BadMethodCallException([$this, $stackerName], FrameworkInterface::EXCEPTION_BAD_METHOD_CALL); + } // Now get the first value - /* NOISY-DEBUG: */ $this->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); + /* NOISY-DEBUG: */ DebugMiddleware::getSelfInstance()->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); $value = NULL; // Return it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: value[]=%s - EXIT!', gettype($value))); return $value; } @@ -362,17 +406,22 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $value Value "poped" from array - * @throws EmptyStackerException If the stack is empty + * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If the stack is empty */ protected function popLast (string $stackerName) { - // Is the stack not yet initialized or full? - if ($this->isStackEmpty($stackerName)) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif ($this->isStackEmpty($stackerName)) { // Throw an exception - throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY); - } // END - if + throw new BadMethodCallException([$this, $stackerName], FrameworkInterface::EXCEPTION_BAD_METHOD_CALL); + } // Now, remove the last entry, we don't care about the return value here, see elseif() block above - /* NOISY-DEBUG: */ $this->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); + /* NOISY-DEBUG: */ DebugMiddleware::getSelfInstance()->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); return NULL; } @@ -381,17 +430,22 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $value Value "shifted" from array - * @throws EmptyStackerException If the named stacker is empty + * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If the named stacker is empty */ protected function popFirst (string $stackerName) { - // Is the stack not yet initialized or full? - if ($this->isStackEmpty($stackerName)) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif ($this->isStackEmpty($stackerName)) { // Throw an exception - throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY); - } // END - if + throw new BadMethodCallException([$this, $stackerName], FrameworkInterface::EXCEPTION_BAD_METHOD_CALL); + } // Now, remove the last entry, we don't care about the return value here, see elseif() block above - /* NOISY-DEBUG: */ $this->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); + /* NOISY-DEBUG: */ DebugMiddleware::getSelfInstance()->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); return NULL; } @@ -400,13 +454,22 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $isFull Whether the stack is full + * @throws InvalidArgumentException If a parameter is not valid */ protected function isStackFull (string $stackerName) { - // File-based stacks will only run full if the disk space is low. + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // @TODO Please implement this, returning false + /* NOISY-DEBUG: */ DebugMiddleware::getSelfInstance()->partialStub('[' . __METHOD__ . ':' . __LINE__ . '] stackerName=' . $stackerName); $isFull = false; // Return result + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: isFull=%d - EXIT!', intval($isFull))); return $isFull; } @@ -415,38 +478,25 @@ abstract class BaseFileStack extends BaseStacker { * * @param $stackerName Name of the stack * @return $isEmpty Whether the stack is empty - * @throws NoStackerException If given stack is missing + * @throws InvalidArgumentException If a parameter is not valid + * @throws BadMethodCallException If given stack is missing */ public function isStackEmpty (string $stackerName) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + if (empty($stackerName)) { + // No empty stack name + throw new InvalidArgumentException('Parameter "stackerName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // So, is the stack empty? $isEmpty = (($this->getStackCount($stackerName)) == 0); // Return result + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: isEmpty=%d - EXIT!', intval($isEmpty))); return $isEmpty; } - /** - * Initializes given stacker - * - * @param $stackerName Name of the stack - * @param $forceReInit Force re-initialization - * @return void - * @throws UnsupportedOperationException This method is not (and maybe never will be) supported - */ - public function initStack (string $stackerName, bool $forceReInit = false) { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Initializes all stacks - * - * @return void - * @throws UnsupportedOperationException This method is not (and maybe never will be) supported - */ - public function initStacks (array $stacks, bool $forceReInit = false) { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); - } - /** * Checks whether the given stack is initialized (set in array $stackers) * @@ -455,7 +505,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public function isStackInitialized (string $stackerName) { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -465,7 +515,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public function isEndOfFileReached () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -476,7 +526,12 @@ abstract class BaseFileStack extends BaseStacker { */ public function getStackCount (string $stackerName) { // Now, simply return the found count value, this must be up-to-date then! - return $this->getIteratorInstance()->getCounter(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackerName=%s - CALLED!', $stackerName)); + $count = $this->getIteratorInstance()->getBinaryFileInstance()->getCounter(); + + // Return count + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: count=%d - EXIT!', $count)); + return $count; } /** @@ -485,30 +540,36 @@ abstract class BaseFileStack extends BaseStacker { * @return $length Minimum length for one entry/block */ public function calculateMinimumBlockLength () { - // Calulcate it - $length = - // Length of entry group - BaseBinaryFile::LENGTH_GROUP + strlen(chr(BaseBinaryFile::SEPARATOR_GROUP_HASH)) + - // Hash + value - self::getHashLength() + strlen(chr(BaseBinaryFile::SEPARATOR_HASH_VALUE)) + 1 + - // Final separator - strlen(chr(BaseBinaryFile::SEPARATOR_ENTRIES)); + // Is the value "cached"? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: CALLED!'); + if (self::$minimumBlockLength == 0) { + // Calulcate it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Calculating ...'); + self::$minimumBlockLength = + // Length of entry group + BinaryFile::LENGTH_GROUP + strlen(chr(BinaryFile::SEPARATOR_GROUP_HASH)) + + // Hash + value + self::getHashLength() + strlen(chr(BinaryFile::SEPARATOR_HASH_VALUE)) + 1 + + // Final separator + strlen(chr(BinaryFile::SEPARATOR_ENTRIES)); + } // Return it - return $length; + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: self::minimumBlockLength=%d - EXIT!', self::$minimumBlockLength)); + return self::$minimumBlockLength; } /** * 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. + * analyzeFileStructure() instead of this method. * * @return void * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public function initCountersGapsArray () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -518,7 +579,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public final function getHeaderSize () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -529,7 +590,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public final function setHeaderSize (int $headerSize) { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -539,7 +600,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public final function getHeader () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -550,7 +611,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public final function setHeader (array $header) { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -560,7 +621,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public function updateSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -570,7 +631,7 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public final function getCounter () { - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -583,21 +644,33 @@ abstract class BaseFileStack extends BaseStacker { * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ public function writeData (int $seekPosition, string $data, bool $flushHeader = true) { - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: seekPosition=%s,data[]=%s,flushHeader=%d', $seekPosition, gettype($data), intval($flushHeader))); - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + // Not supported + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); + } + + /** + * Writes at given position by seeking to it. + * + * @param $seekPosition Seek position in file + * @param $dataStream Data to be written + * @return mixed Number of writes bytes or false on error + * @throws UnsupportedOperationException This method is not (and maybe never will be) supported + */ + public function writeAtPosition (int $seekPosition, string $dataStream) { + // Not supported + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** * Writes given value to the file and returns a hash and gap position for it * - * @param $groupId Group identifier + * @param $stackName Group identifier * @param $value Value to be added to the stack * @return $data Hash and gap position * @throws UnsupportedOperationException This method is not (and maybe never will be) supported */ - public function writeValueToFile (string $groupId, $value) { - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: groupId=%s,value[%s]=%s', $groupId, gettype($value), print_r($value, true))); - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + public function writeValueToFile (string $stackName, $value) { + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -610,8 +683,7 @@ abstract class BaseFileStack extends BaseStacker { */ public function searchNextGap (int $length) { // Not supported here - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: length=%d - CALLED!', $length)); - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); + throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getBinaryFileInstance()), FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION); } /** @@ -621,52 +693,71 @@ abstract class BaseFileStack extends BaseStacker { */ public function getFileSize () { // Call iterator's method - return $this->getIteratorInstance()->getFileSize(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: CALLED!'); + $size = $this->getIteratorInstance()->getBinaryFileInstance()->getFileSize(); + + // Return size + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: size=%d - EXIT!', $size)); + return $size; } /** * Writes given raw data to the file and returns a gap position and length * - * @param $groupId Group identifier + * @param $stackName Group identifier * @param $hash Hash from encoded value * @param $encoded Encoded value to be written to the file * @return $data Gap position and length of the raw data - */ - public function writeDataToFreeGap (string $groupId, string $hash, string $encoded) { + * @throws InvalidArgumentException If a parameter has an invalid value + */ + public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) { + // Check parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash{}=0x%s,encoded()=%d - CALLED!', $stackName, bin2hex($hash), strlen($encoded))); + if (empty($stackName)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "stackName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif (empty($hash)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "hash" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } elseif (empty($encoded)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "encoded" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT); + } + // Raw data been written to the file - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: groupId=%s,hash=%s,encoded()=%d - CALLED!', $groupId, $hash, strlen($encoded))); $rawData = sprintf('%s%s%s%s%s', - $groupId, - BaseBinaryFile::SEPARATOR_GROUP_HASH, - hex2bin($hash), - BaseBinaryFile::SEPARATOR_HASH_VALUE, + $stackName, + BinaryFile::SEPARATOR_GROUP_HASH, + $hash, + BinaryFile::SEPARATOR_HASH_VALUE, $encoded ); // Search for next free gap - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: groupId=%s,hash=%s,rawData()=%d', $groupId, $hash, strlen($rawData))); - $gapPosition = $this->getIteratorInstance()->searchNextGap(strlen($rawData)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash{}=0x%s,rawData()=%d', $stackName, bin2hex($hash), strlen($rawData))); + $gapPosition = $this->getIteratorInstance()->getBinaryFileInstance()->searchNextGap(strlen($rawData)); // Gap position cannot be smaller than header length + 1 - if ($gapPosition <= $this->getIteratorInstance()->getHeaderSize()) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: gapPosition=%d', $gapPosition)); + if ($gapPosition <= $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize()) { // Improper gap position throw new UnexpectedValueException(sprintf('gapPosition[%s]=%d is not larger than headerSize=%d', gettype($gapPosition), $gapPosition, - $this->getIteratorInstance()->getHeaderSize() - )); + $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize() + ), FrameworkInterface::EXCEPTION_UNEXPECTED_VALUE); } // Then write the data at that gap - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: groupId=%s,hash=%s,gapPosition=%s', $groupId, $hash, $gapPosition)); - $this->getIteratorInstance()->writeData($gapPosition, $rawData); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash{}=0x%s,gapPosition=%s', $stackName, bin2hex($hash), $gapPosition)); + $this->getIteratorInstance()->getBinaryFileInstance()->writeData($gapPosition, $rawData); // Return gap position, hash and length of raw data - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: groupId=%s,hash=%s,rawData()=%d - EXIT!', $groupId, $hash, strlen($rawData))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash{}=0x%s,rawData()=%d - EXIT!', $stackName, bin2hex($hash), strlen($rawData))); return [ - self::ARRAY_INDEX_GAP_POSITION => $gapPosition, - self::ARRAY_INDEX_HASH => $hash, - self::ARRAY_INDEX_DATA_LENGTH => strlen($rawData), + StackableFile::ARRAY_NAME_GAP_POSITION => $gapPosition, + StackableFile::ARRAY_NAME_HASH => $hash, + StackableFile::ARRAY_NAME_DATA_LENGTH => strlen($rawData), ]; }