From 79e6029823f993ec7503a399aa2fdbb95aadb2d1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Thu, 10 Dec 2020 02:37:41 +0100 Subject: [PATCH] Refacuring / possible WIP: - rewrote a lot clases and cleared up abuse of Block interface - got rid of $applicationInstance as this can be retrieved singelton - moved some files, added new BaseFileIndex class MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roland Häder --- framework/config-global.php | 2 +- .../classes/class_BaseFrameworkSystem.php | 5 +- .../classes/commands/class_BaseCommand.php | 2 +- .../html/class_HtmlConfirmCommand.php | 2 +- .../commands/html/class_HtmlHomeCommand.php | 2 +- .../html/class_HtmlLoginAreaCommand.php | 2 +- .../commands/html/class_HtmlLoginCommand.php | 2 +- .../html/class_HtmlLoginFailedCommand.php | 2 +- .../html/class_HtmlLogoutDoneCommand.php | 2 +- .../html/class_HtmlRegisterCommand.php | 2 +- .../commands/html/class_HtmlStatusCommand.php | 2 +- .../result/class_CachedDatabaseResult.php | 14 +- .../binary/class_BaseBinaryFile.php | 45 +-- .../binary/index/class_IndexFile.php | 46 ++- .../binary/stack/class_StackFile.php | 18 +- .../file_directories/class_BaseFileIo.php | 6 +- .../class_FrameworkTextFileInputPointer.php | 5 +- .../class_FrameworkFileInputOutputPointer.php | 12 +- .../main/classes/index/class_BaseIndex.php | 327 +----------------- .../index/file/class_BaseFileIndex.php | 315 +++++++++++++++++ .../stack}/class_FileStackIndex.php | 86 +---- .../iterator/file/class_FileIterator.php | 40 ++- .../output/console/class_ConsoleOutput.php | 33 -- .../output/debug/class_BaseDebugOutput.php | 2 +- .../console/class_DebugConsoleOutput.php | 33 -- .../debug/error/class_DebugErrorLogOutput.php | 33 -- .../output/debug/web/class_DebugWebOutput.php | 33 -- .../classes/output/web/class_WebOutput.php | 43 +-- .../stacker/file/class_BaseFileStack.php | 30 +- .../stacker/file/fifo/class_FiFoFileStack.php | 5 +- .../main/interfaces/index/class_Indexable.php | 7 + .../class_FileIndexer.php} | 26 +- .../file/stack/class_IndexableStack.php} | 34 +- .../main/interfaces/io/class_Streamable.php | 22 -- .../interfaces/io/class_StreamableInput.php | 23 ++ .../class_SeekableWritableFileIterator.php | 8 - .../stacker/file/class_StackableFile.php | 4 +- .../middleware/io/class_FileIoHandler.php | 2 +- 38 files changed, 536 insertions(+), 741 deletions(-) create mode 100644 framework/main/classes/index/file/class_BaseFileIndex.php rename framework/main/classes/index/{file_stack => file/stack}/class_FileStackIndex.php (57%) rename framework/main/interfaces/index/{stack/class_IndexableStack.php => file/class_FileIndexer.php} (63%) rename framework/main/{traits/index/stack/class_IndexableStackTrait.php => interfaces/index/file/stack/class_IndexableStack.php} (52%) diff --git a/framework/config-global.php b/framework/config-global.php index d22cbf83..90548cb8 100644 --- a/framework/config-global.php +++ b/framework/config-global.php @@ -386,7 +386,7 @@ $cfg->setConfigEntry('file_stack_pre_allocate_enabled', 'Y'); $cfg->setConfigEntry('file_stack_pre_allocate_count', 10000); // CFG: INDEX-INDEX-CLASS -$cfg->setConfigEntry('file_stack_index_class', 'Org\Mxchange\CoreFramework\Index\Stack\FileStackIndex'); +$cfg->setConfigEntry('file_stack_index_class', 'Org\Mxchange\CoreFramework\Index\File\Stack\FileStackIndex'); // CFG: INDEX-PRE-ALLOCATE-ENABLED $cfg->setConfigEntry('index_pre_allocate_enabled', 'Y'); diff --git a/framework/main/classes/class_BaseFrameworkSystem.php b/framework/main/classes/class_BaseFrameworkSystem.php index e9ce996f..6810e724 100644 --- a/framework/main/classes/class_BaseFrameworkSystem.php +++ b/framework/main/classes/class_BaseFrameworkSystem.php @@ -1639,11 +1639,8 @@ Loaded includes: * @return void */ protected function initWebOutputInstance () { - // Get application instance - $applicationInstance = ApplicationHelper::getSelfInstance(); - // Init web output instance - $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance)); + $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class'); // Set it locally $this->setWebOutputInstance($outputInstance); diff --git a/framework/main/classes/commands/class_BaseCommand.php b/framework/main/classes/commands/class_BaseCommand.php index 49c357b8..8eba066c 100644 --- a/framework/main/classes/commands/class_BaseCommand.php +++ b/framework/main/classes/commands/class_BaseCommand.php @@ -117,7 +117,7 @@ abstract class BaseCommand extends BaseFrameworkSystem { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName($applicationInstance->getAppShortName() . '_' . $this->getResolverInstance()->getCommandName() . '_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName($applicationInstance->getAppShortName() . '_' . $this->getResolverInstance()->getCommandName() . '_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlConfirmCommand.php b/framework/main/classes/commands/html/class_HtmlConfirmCommand.php index aeea7318..f86850e2 100644 --- a/framework/main/classes/commands/html/class_HtmlConfirmCommand.php +++ b/framework/main/classes/commands/html/class_HtmlConfirmCommand.php @@ -125,7 +125,7 @@ class HtmlConfirmCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('confirm_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('confirm_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlHomeCommand.php b/framework/main/classes/commands/html/class_HtmlHomeCommand.php index ff1a0932..c1135e67 100644 --- a/framework/main/classes/commands/html/class_HtmlHomeCommand.php +++ b/framework/main/classes/commands/html/class_HtmlHomeCommand.php @@ -110,7 +110,7 @@ class HtmlHomeCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('home_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('home_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlLoginAreaCommand.php b/framework/main/classes/commands/html/class_HtmlLoginAreaCommand.php index f5123a7a..ba9ed0f6 100644 --- a/framework/main/classes/commands/html/class_HtmlLoginAreaCommand.php +++ b/framework/main/classes/commands/html/class_HtmlLoginAreaCommand.php @@ -148,7 +148,7 @@ class HtmlLoginAreaCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('login_area_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('login_area_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlLoginCommand.php b/framework/main/classes/commands/html/class_HtmlLoginCommand.php index ce67a790..bdd662e0 100644 --- a/framework/main/classes/commands/html/class_HtmlLoginCommand.php +++ b/framework/main/classes/commands/html/class_HtmlLoginCommand.php @@ -115,7 +115,7 @@ class HtmlLoginCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('login_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('login_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlLoginFailedCommand.php b/framework/main/classes/commands/html/class_HtmlLoginFailedCommand.php index aff6ccc3..fb889681 100644 --- a/framework/main/classes/commands/html/class_HtmlLoginFailedCommand.php +++ b/framework/main/classes/commands/html/class_HtmlLoginFailedCommand.php @@ -112,7 +112,7 @@ class HtmlLoginFailedCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('login_failed_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('login_failed_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlLogoutDoneCommand.php b/framework/main/classes/commands/html/class_HtmlLogoutDoneCommand.php index 682a22a6..49763ff3 100644 --- a/framework/main/classes/commands/html/class_HtmlLogoutDoneCommand.php +++ b/framework/main/classes/commands/html/class_HtmlLogoutDoneCommand.php @@ -112,7 +112,7 @@ class HtmlLogoutDoneCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('logout_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('logout_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlRegisterCommand.php b/framework/main/classes/commands/html/class_HtmlRegisterCommand.php index fa9aa755..01128abf 100644 --- a/framework/main/classes/commands/html/class_HtmlRegisterCommand.php +++ b/framework/main/classes/commands/html/class_HtmlRegisterCommand.php @@ -116,7 +116,7 @@ class HtmlRegisterCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('register_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('register_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/commands/html/class_HtmlStatusCommand.php b/framework/main/classes/commands/html/class_HtmlStatusCommand.php index 1b42190f..3e6ae8aa 100644 --- a/framework/main/classes/commands/html/class_HtmlStatusCommand.php +++ b/framework/main/classes/commands/html/class_HtmlStatusCommand.php @@ -109,7 +109,7 @@ class HtmlStatusCommand extends BaseCommand implements Commandable { // Construct the menu in every command. We could do this in BaseCommand class. But this means // *every* command has a navigation system and that is want we don't want. - $menuInstance = ObjectFactory::createObjectByConfiguredName('status_menu_class', array($applicationInstance)); + $menuInstance = ObjectFactory::createObjectByConfiguredName('status_menu_class'); // Render the menu $menuInstance->renderMenu(); diff --git a/framework/main/classes/database/result/class_CachedDatabaseResult.php b/framework/main/classes/database/result/class_CachedDatabaseResult.php index 74766038..9b59813b 100644 --- a/framework/main/classes/database/result/class_CachedDatabaseResult.php +++ b/framework/main/classes/database/result/class_CachedDatabaseResult.php @@ -14,6 +14,7 @@ use Org\Mxchange\CoreFramework\Result\Update\UpdateableResult; // Import SPL stuff use \InvalidArgumentException; +use \OutOfBoundsException; use \SeekableIterator; /** @@ -171,15 +172,22 @@ class CachedDatabaseResult extends BaseDatabaseResult implements SearchableResul /** * Seeks for to a specified position * - * @param $index Index to seek for + * @param $seekPosition Position to seek to * @return void + * @throws OutOfBoundsException If the position is not seekable */ - public function seek (int $index) { + public function seek (int $seekPosition) { + // Validate parameter + if ($seekPosition < 0) { + // Throw exception + throw new OutOfBoundsException(sprintf('seekPositon=%d is not seekable', $seekPosition)); + } + // Rewind to beginning $this->rewind(); // Search for the entry - while (($this->currentPos < $index) && ($this->valid())) { + while (($this->currentPos < $seekPosition) && ($this->valid())) { // Continue on $this->next(); } diff --git a/framework/main/classes/file_directories/binary/class_BaseBinaryFile.php b/framework/main/classes/file_directories/binary/class_BaseBinaryFile.php index fb96ae76..95c642eb 100644 --- a/framework/main/classes/file_directories/binary/class_BaseBinaryFile.php +++ b/framework/main/classes/file_directories/binary/class_BaseBinaryFile.php @@ -6,18 +6,17 @@ namespace Org\Mxchange\CoreFramework\Filesystem\File; use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap; use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint; use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory; -use Org\Mxchange\CoreFramework\Filesystem\Block; -use Org\Mxchange\CoreFramework\Filesystem\Block\CalculatableBlock; use Org\Mxchange\CoreFramework\Filesystem\File\BaseAbstractFile; +use Org\Mxchange\CoreFramework\Index\Indexable; use Org\Mxchange\CoreFramework\Stack\File\StackableFile; -use Org\Mxchange\CoreFramework\Index\Stack\IndexableStack; -use Org\Mxchange\CoreFramework\Traits\Index\Stack\IndexableStackTrait; +use Org\Mxchange\CoreFramework\Traits\Index\IndexableTrait; use Org\Mxchange\CoreFramework\Traits\Stack\StackableTrait; // Import SPL stuff use \BadMethodCallException; use \InvalidArgumentException; use \LogicException; +use \OutOfBoundsException; use \SplFileInfo; use \UnexpectedValueException; @@ -46,7 +45,7 @@ use \UnexpectedValueException; abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { // Load traits use StackableTrait; - use IndexableStackTrait; + use IndexableTrait; /** * Separator for header data @@ -501,6 +500,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { * @param $data Data to be written * @param $flushHeader Whether to flush the header (default: flush) * @return void + * @throws OutOfBoundsException If the position is not seekable * @throws InvalidArgumentException If a parameter is invalid */ public function writeData (int $seekPosition, string $data, bool $flushHeader = true) { @@ -508,7 +508,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%s,data()=%d,flushHeader=%d - CALLED!', $seekPosition, strlen($data), intval($flushHeader))); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition)); } elseif (empty($data)) { // Empty data is invalid, too throw new InvalidArgumentException('Parameter "data" is empty'); @@ -548,6 +548,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { * @param $seekPosition Seek position in file * @param $dataStream Data to be written * @return mixed Number of writes bytes or false on error + * @throws OutOfBoundsException If the position is not seekable * @throws InvalidArgumentException If a parameter is not valid */ public function writeAtPosition (int $seekPosition, string $dataStream) { @@ -555,7 +556,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream)); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition)); } elseif (empty($dataStream)) { // Empty dataStream throw new InvalidArgumentException('Parameter "dataStream" is empty'); @@ -681,7 +682,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Pre-allocating file ...'); // Calculate minimum length for one entry and get file size - $minimumBlockLength = $this->getIndexableStackInstance()->calculateMinimumBlockLength(); + $minimumBlockLength = $this->getIndexInstance()->calculateMinimumBlockLength(); $fileSize = $this->getFileSize(); // Calulcate seek position @@ -733,14 +734,14 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { * @param $offset Offset to seek to (or used as "base" for other seeks) * @param $whence Added to offset (default: only use offset to seek to) * @return $status Status of file seek: 0 = success, -1 = failed - * @throws InvalidArgumentException If a parameter is not valid + * @throws OutOfBoundsException If the position is not seekable */ public function seek (int $offset, int $whence = SEEK_SET) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: offset=%d,whence=%d - CALLED!', $offset, $whence)); if ($offset < 0) { // No offset is smaller than zero - throw new InvalidArgumentException(sprintf('offset=%d is not valid', $offset)); + throw new OutOfBoundsException(sprintf('offset=%d is not valid', $offset)); } // Call pointer instance @@ -756,14 +757,14 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { * * @param $bytes Amount of bytes to read * @return $data Data read from file - * @throws InvalidArgumentException If a parameter is not valid + * @throws OutOfBoundsException If the position is not seekable */ public function read (int $bytes = 0) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: bytes=%d - CALLED!', $bytes)); if ($bytes < 0) { - // Throw IAE - throw new InvalidArgumentException(sprintf('bytes=%d is not valid', $bytes)); + // Throw exception + throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes)); } // Call pointer instance @@ -888,7 +889,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { // First calculate minimum block length //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: this->seekPosition=%d', $this->determineSeekPosition())); - $length = $this->getIndexableStackInstance()->calculateMinimumBlockLength(); + $length = $this->getIndexInstance()->calculateMinimumBlockLength(); //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d', $length)); // Read possibly back-buffered bytes from previous call of next(). @@ -966,7 +967,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { public function isValid () { // First calculate minimum block length //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!'); - $length = $this->getIndexableStackInstance()->calculateMinimumBlockLength(); + $length = $this->getIndexInstance()->calculateMinimumBlockLength(); // Short be more than zero! //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-BINARY-FILE: length=%d', $length)); @@ -1014,17 +1015,17 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { public function readFileHeader () { // Is index set or stack? /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!'); - if ($this->getIndexableStackInstance() instanceof IndexableStack) { + if ($this->getIndexInstance() instanceof Indexable) { // Call index instance - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->indexableStackInstance->readFileHeader() ...'); - $this->getIndexableStackInstance()->readFileHeader(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->indexInstance->readIndexHeader() ...'); + $this->getIndexInstance()->readIndexHeader(); } elseif ($this->getStackInstance() instanceof StackableFile) { // Call stacke instance - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->stackInstance->readFileHeader() ...'); - $this->getStackInstance()->readFileHeader(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: Calling this->stackInstance->readStackHeader() ...'); + $this->getStackInstance()->readStackHeader(); } else { // Bad logic? - throw new LogicException('Wether indexableStackInstance nor stackableFileInstance are set'); + throw new LogicException('Wether indexInstance nor stackInstance are set'); } // Trace message @@ -1039,7 +1040,7 @@ abstract class BaseBinaryFile extends BaseAbstractFile implements BinaryFile { public function flushFileHeader () { // Call block instance /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: CALLED!'); - $this->getIndexableStackInstance()->flushFileHeader(); + $this->getIndexInstance()->flushFileHeader(); // Trace message /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-BINARY-FILE: EXIT!'); diff --git a/framework/main/classes/file_directories/binary/index/class_IndexFile.php b/framework/main/classes/file_directories/binary/index/class_IndexFile.php index 01092713..473ba314 100644 --- a/framework/main/classes/file_directories/binary/index/class_IndexFile.php +++ b/framework/main/classes/file_directories/binary/index/class_IndexFile.php @@ -6,7 +6,7 @@ namespace Org\Mxchange\CoreFramework\Filesystem\Index; use Org\Mxchange\CoreFramework\Filesystem\File\BaseBinaryFile; use Org\Mxchange\CoreFramework\Filesystem\Index\IndexableFile; use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException; -use Org\Mxchange\CoreFramework\Index\Stack\IndexableStack; +use Org\Mxchange\CoreFramework\Index\File\Stack\Indexable; // Import SPL stuff use \SplFileInfo; @@ -48,16 +48,16 @@ class IndexFile extends BaseBinaryFile implements IndexableFile { * Creates an instance of this File class and prepares it for usage * * @param $fileInfoInstance An instance of a SplFileInfo class - * @param $indexInstance An instance of a IndexableStack class + * @param $indexInstance An instance of a Indexable class * @return $indexFileInstance An instance of an IndexableFile class */ - public final static function createIndexFile (SplFileInfo $fileInfoInstance, IndexableStack $indexInstance) { + public final static function createIndexFile (SplFileInfo $fileInfoInstance, Indexable $indexInstance) { // Get a new instance /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: fileInfoInstance[%s]=%s,indexInstance=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance, $indexInstance->__toString())); $indexFileInstance = new IndexFile(); // Set file instance here for callbacks - $indexFileInstance->setIndexableStackInstance($indexInstance); + $indexFileInstance->setIndexInstance($indexInstance); // Expand file name with .idx $indexInfoInstance = new SplFileInfo(sprintf('%s.idx', $fileInfoInstance->__toString())); @@ -73,27 +73,49 @@ class IndexFile extends BaseBinaryFile implements IndexableFile { /** * 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 If this method is called + * @throws InvalidArgumentException If a parameter is not valid */ - public function writeValueToFile (string $groupId, $value) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('INDEX-FILE: groupId=' . $groupId . ',value[' . gettype($value) . ']=' . print_r($value, true)); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); + public function writeValueToFile (string $stackName, $value) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: stackName=%s,value[]=%s - CALLED!', $stackName, gettype($value))); + if (empty($stackName)) { + // Throw IAE + throw new InvalidArgumentException('Parameter "stackName" is empty'); + } elseif (is_object($value) || is_resource($value)) { + // Not wanted here + throw new InvalidArgumentException(sprintf('value[]=%s is not stackable in files', gettype($value))); + } + + // Encode/convert the value into a "binary format" + $encoded = StringUtils::encodeData($value); + + // Get a strong hash for the "encoded" data + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: encoded=%s', $encoded)); + $hash = self::hash($encoded); + + // Then write it to the next free gap + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: hash=%s', $hash)); + $data = $this->getIndexInstance()->writeDataToFreeGap($stackName, $hash, $encoded); + + // Return info + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('INDEX-FILE: data[]=%s - EXIT!', gettype($data))); + return $data; } /** * 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 * @throws UnsupportedOperationException If this method is called */ - public function writeDataToFreeGap (string $groupId, string $hash, string $encoded) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('INDEX-FILE: groupId=' . $groupId . ',encoded()=' . strlen($encoded)); + public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) { + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('INDEX-FILE: stackName=' . $stackName . ',hash=' . $hash . ',encoded()=' . strlen($encoded)); throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); } diff --git a/framework/main/classes/file_directories/binary/stack/class_StackFile.php b/framework/main/classes/file_directories/binary/stack/class_StackFile.php index 2cd5dde0..46cc8b32 100644 --- a/framework/main/classes/file_directories/binary/stack/class_StackFile.php +++ b/framework/main/classes/file_directories/binary/stack/class_StackFile.php @@ -72,17 +72,17 @@ class StackFile extends BaseBinaryFile implements FileStacker { /** * 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 InvalidArgumentException If a parameter is not valid */ - public function writeValueToFile (string $groupId, $value) { + public function writeValueToFile (string $stackName, $value) { // Validate parameter - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('STACK-FILE: groupId=%s,value[]=%s - CALLED!', $groupId, gettype($value))); - if (empty($groupId)) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('STACK-FILE: stackName=%s,value[]=%s - CALLED!', $stackName, gettype($value))); + if (empty($stackName)) { // Throw IAE - throw new InvalidArgumentException('Parameter "groupId" is empty'); + throw new InvalidArgumentException('Parameter "stackName" is empty'); } elseif (is_object($value) || is_resource($value)) { // Not wanted here throw new InvalidArgumentException(sprintf('value[]=%s is not stackable in files', gettype($value))); @@ -95,7 +95,7 @@ class StackFile extends BaseBinaryFile implements FileStacker { $hash = self::hash($encoded); // Then write it to the next free gap - $data = $this->getStackInstance()->writeDataToFreeGap($groupId, $hash, $encoded); + $data = $this->getStackInstance()->writeDataToFreeGap($stackName, $hash, $encoded); // Return info return $data; @@ -104,14 +104,14 @@ class StackFile extends BaseBinaryFile implements FileStacker { /** * 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 * @throws UnsupportedOperationException If this method is called */ - public function writeDataToFreeGap (string $groupId, string $hash, string $encoded) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('STACK-FILE: groupId=' . $groupId . ',hash=' . $hash . ',encoded()=' . strlen($encoded)); + public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) { + self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('STACK-FILE: stackName=' . $stackName . ',hash=' . $hash . ',encoded()=' . strlen($encoded)); throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); } diff --git a/framework/main/classes/file_directories/class_BaseFileIo.php b/framework/main/classes/file_directories/class_BaseFileIo.php index c1c71662..6036db00 100644 --- a/framework/main/classes/file_directories/class_BaseFileIo.php +++ b/framework/main/classes/file_directories/class_BaseFileIo.php @@ -9,7 +9,7 @@ use Org\Mxchange\CoreFramework\Generic\NullPointerException; use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem; // Import SPL stuff -use \InvalidArgumentException; +use \OutOfBoundsException; use \SplFileObject; /** @@ -157,8 +157,8 @@ abstract class BaseFileIo extends BaseFrameworkSystem implements FilePointer, Cl // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-IO: offset=%d,whence=%d - CALLED!', $offset, $whence)); if ($offset < 0) { - // Throw IAE - throw new InvalidArgumentException(sprintf('offset=%d is not valid', $offset)); + // Throw exception + throw new OutOfBoundsException(sprintf('offset=%d is not valid', $offset)); } // Seek to position diff --git a/framework/main/classes/file_directories/input/text/class_FrameworkTextFileInputPointer.php b/framework/main/classes/file_directories/input/text/class_FrameworkTextFileInputPointer.php index eef4a749..620b2f31 100644 --- a/framework/main/classes/file_directories/input/text/class_FrameworkTextFileInputPointer.php +++ b/framework/main/classes/file_directories/input/text/class_FrameworkTextFileInputPointer.php @@ -117,14 +117,15 @@ class FrameworkTextFileInputPointer extends BaseFileIo implements InputPointer { * * @param $bytes Amount of bytes to read or whole line (only text files) * @return $data Data read from file + * @throws OutOfBoundsException If the position is not seekable * @throws NullPointerException If the file pointer instance is not set by setFileObject() - * @throws InvalidResourceException If there is no object being set + * @throws LogicException If $fileObject is not an object */ public function read (int $bytes = 0) { // Some sanity checks if ($bytes < 0) { // Cannot be below zero - throw new InvalidArgumentException(sprintf('bytes=%d is not valid', $bytes)); + throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes)); } elseif (is_null($this->getFileObject())) { // Pointer not initialized throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); diff --git a/framework/main/classes/file_directories/io/class_FrameworkFileInputOutputPointer.php b/framework/main/classes/file_directories/io/class_FrameworkFileInputOutputPointer.php index ff58e65e..ce728050 100644 --- a/framework/main/classes/file_directories/io/class_FrameworkFileInputOutputPointer.php +++ b/framework/main/classes/file_directories/io/class_FrameworkFileInputOutputPointer.php @@ -15,6 +15,7 @@ use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem; // Import SPL stuff use \InvalidArgumentException; use \SplFileInfo; +use \OutOfBoundsException; use \UnexpectedValueException; /** @@ -146,6 +147,7 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP * @param $seekPosition Seek position in file * @param $dataStream Data to be written * @return mixed Number of writes bytes or false on error + * @throws OutOfBoundsException If the position is not seekable * @throws InvalidArgumentException If a parameter is not valid */ public function writeAtPosition (int $seekPosition, string $dataStream) { @@ -153,7 +155,7 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-INPUT-OUTPUT-POINTER: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream)); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition)); } elseif (empty($dataStream)) { // Empty dataStream throw new InvalidArgumentException('Parameter "dataStream" is empty'); @@ -191,14 +193,14 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP * @param $seekPosition Seek position in file * @param $whence "Seek mode" (see http://de.php.net/fseek) * @return $status Status of this operation - * @throws InvalidArgumentException If a parameter is not valid + * @throws OutOfBoundsException If the position is not seekable */ public function seek (int $seekPosition, int $whence = SEEK_SET) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-INPUT-OUTPUT-POINTER: seekPosition=%d,whence=%d - CALLED!', $seekPosition, $whence)); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition)); } // Move the file pointer @@ -229,14 +231,14 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP * * @param $bytes Amount of bytes to read * @return $data Data read from file - * @throws InvalidArgumentException If a parameter is invalid + * @throws OutOfBoundsException If the position is not seekable */ public function read (int $bytes = 0) { // Validatre parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-INPUT-OUTPUT-POINTER: bytes=%d - CALLED!', $bytes)); if ($bytes < 0) { // Bytes cannot be lesser than zero - throw new InvalidArgumentException(sprintf('bytes=%d is not valid', $bytes)); + throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes)); } // Is $bytes bigger than zero? diff --git a/framework/main/classes/index/class_BaseIndex.php b/framework/main/classes/index/class_BaseIndex.php index 5e56d1dc..fe369b74 100644 --- a/framework/main/classes/index/class_BaseIndex.php +++ b/framework/main/classes/index/class_BaseIndex.php @@ -58,333 +58,14 @@ abstract class BaseIndex extends BaseFrameworkSystem implements Indexable { } /** - * Reads the file header + * Checks if this index has been fully and properly loaded. * - * @return void - * @throws UnexpectedValueException If header length or count of elements is invalid + * @return $isLoaded Whether this index has been loaded */ - public function readFileHeader () { - // First rewind to beginning as the header sits at the beginning ... - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: CALLED!'); - $this->getIteratorInstance()->rewind(); - - // Then read it (see constructor for calculation) - $data = $this->getIteratorInstance()->read($this->getIteratorInstance()->getHeaderSize()); - - // Have all requested bytes been read? - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getHeaderSize())); - if (strlen($data) != $this->getIteratorInstance()->getHeaderSize()) { - // Invalid header length - throw new UnexpectedValueException(sprintf('data(%d)=%s is not expected length %d', - strlen($data), - $data, - $this->getIteratorInstance()->getHeaderSize() - )); - } elseif (empty(trim($data, chr(0)))) { - // Empty file header - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: File header is empty - EXIT!'); - return; - } elseif (substr($data, -1, 1) != chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) { - // Bad last character - throw new UnexpectedValueException(sprintf('data=%s does not end with "%s"', - $data, - chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES) - )); - } - - // Okay, then remove it - $data = substr($data, 0, -1); - - // And update seek position - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->iteratorInstance->updateSeekPosition() ...'); - $this->getIteratorInstance()->updateSeekPosition(); - - /* - * Now split it: - * - * 0 => magic - * 1 => total entries - */ - $header = explode(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), $data); - - // Check if the array has only 3 elements - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: header()=%d', count($header))); - //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: header(%d)=%s', count($header), print_r($header, true))); - if (count($header) != 2) { - // Bad header - throw new UnexpectedValueException(sprintf('header()=%d is not expected value 2', count($header))); - } elseif ($header[0] !== Indexable::INDEX_MAGIC) { - // Magic must be in first element - throw new UnexpectedValueException(sprintf('header[0]=%s is not the expected magic (%s)', $header[0], Indexable::INDEX_MAGIC)); - } elseif (strlen($header[1]) != BaseBinaryFile::LENGTH_COUNT) { - // Length of total entries not matching - throw new UnexpectedValueException(sprintf('header[1](%d)=%s does not have expected length %d', strlen($header[1]), $header[1], BaseBinaryFile::LENGTH_COUNT)); - } - - // Decode count - $header[1] = hex2bin($header[1]); - - // Set it here - $this->getIteratorInstance()->setHeader($header); - + public function isIndexLoaded () { // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: EXIT!'); - } - - /** - * Flushes the file header - * - * @return void - */ - public function flushFileHeader () { - // Put all informations together /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: CALLED!'); - $header = sprintf('%s%s%s%s', - // Magic - Indexable::INDEX_MAGIC, - - // Separator header data - chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), - - // Total entries - str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getCounter()), BaseBinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT), - - // Separator header<->entries - chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES) - ); - - // Write it to disk (header is always at seek position 0) - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: Calling this->iteratorInstance->writeAtPosition(0, header=%s) ...', $header)); - $this->getIteratorInstance()->writeAtPosition(0, $header); - - // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: EXIT!'); - } - - /** - * Initializes this index - * - * @param $fileInfoInstance An instance of a SplFileInfo class - * @return void - * @todo Currently the index file is not cached, please implement a memory-handling class and if enough RAM is found, cache the whole index file. - */ - protected function initIndex (SplFileInfo $fileInfoInstance) { - // Get a file i/o pointer instance for index file - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: fileInfoInstance[%s]=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance)); - $fileInstance = ObjectFactory::createObjectByConfiguredName('index_file_class', array($fileInfoInstance, $this)); - - // Get iterator instance - $iteratorInstance = ObjectFactory::createObjectByConfiguredName('file_iterator_class', [$fileInstance]); - - // Set iterator here - $this->setIteratorInstance($iteratorInstance); - - // Calculate header size - $headerSize = ( - strlen(Indexable::INDEX_MAGIC) + - strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA)) + - BaseBinaryFile::LENGTH_COUNT + - strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) - ); - - // Set it - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: Setting headerSize=%d ...', $headerSize)); - $this->getIteratorInstance()->setHeaderSize($headerSize); - - // Init counters and gaps array - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->iteratorInstance->initCountersGapsArray() ...'); - $this->getIteratorInstance()->initCountersGapsArray(); - - // Default is not created - $created = false; - - // Is the file's header initialized? - if (!$this->getIteratorInstance()->isFileHeaderInitialized()) { - // First pre-allocate a bit - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->iteratorInstance->preAllocateFile(index) ...'); - $this->getIteratorInstance()->preAllocateFile('index'); - - // Then write file header - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->iteratorInstance->createFileHeader() ...'); - $this->getIteratorInstance()->createFileHeader(); - - // Mark as freshly created - $created = true; - } - - // Load the file header - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->readFileHeader() ...'); - $this->readFileHeader(); - - // Freshly created? - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: created=%d', intval($created))); - if (!$created) { - // Analyze file structure - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calling this->iteratorInstance->analyzeFileStructure() ...'); - $this->getIteratorInstance()->analyzeFileStructure(); - } - - // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: EXIT!'); - } - - /** - * Calculates minimum length for one entry/block - * - * @return $length Minimum length for one entry/block - */ - public function calculateMinimumBlockLength () { - // Is it "cached"? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: CALLED!'); - if (self::$minimumBlockLength == 0) { - // Calulcate it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-INDEX: Calculating ...'); - self::$minimumBlockLength = ( - // Type - BaseBinaryFile::LENGTH_TYPE + strlen(chr(BaseBinaryFile::SEPARATOR_TYPE_POSITION)) + - // Position - BaseBinaryFile::LENGTH_POSITION + strlen(chr(BaseBinaryFile::SEPARATOR_ENTRIES)) - ); - } - - // Return it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-INDEX: self::minimumBlockLength=%d - EXIT!', self::$minimumBlockLength)); - return self::$minimumBlockLength; - } - - /** - * Determines whether the EOF has been reached - * - * @return $isEndOfFileReached Whether the EOF has been reached - * @throws UnsupportedOperationException If this method is called - */ - public function isEndOfFileReached () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * 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 - * 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); - } - - /** - * Getter for header size - * - * @return $totalEntries Size of file header - * @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); - } - - /** - * Setter for header size - * - * @param $headerSize Size of file header - * @return void - * @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); - } - - /** - * Getter for header array - * - * @return $totalEntries Size of file header - * @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); - } - - /** - * Setter for header - * - * @param $header Array for a file header - * @return void - * @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); - } - - /** - * Updates seekPosition attribute from file to avoid to much access on file. - * - * @return void - * @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); - } - - /** - * Getter for total entries - * - * @return $totalEntries Total entries in this file - * @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); - } - - /** - * "Getter" for file size - * - * @return $fileSize Size of currently loaded file - */ - public function getFileSize () { - // Call iterator's method - return $this->getIteratorInstance()->getFileSize(); - } - - /** - * Writes data at given position - * - * @param $seekPosition Seek position - * @param $data Data to be written - * @param $flushHeader Whether to flush the header (default: flush) - * @return void - * @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('seekPosition=%s,data[]=%s,flushHeader=%d - CALLED!', $seekPosition, gettype($data), intval($flushHeader))); - throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Writes given value to the file and returns a hash and gap position for it - * - * @param $groupId Group identifier - * @param $value Value to be added to the stack - * @return $data Hash and gap position - * @throws UnsupportedOperationException If this method is called - */ - public function writeValueToFile (string $groupId, $value) { - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('groupId=%s,value[%s]=%s - CALLED!', $groupId, gettype($value), print_r($value, true))); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Writes given raw data to the file and returns a gap position and length - * - * @param $groupId 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) { - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('groupId=%s,hash=%s,encoded()=%d - CALLED!', $groupId, $hash, strlen($encoded))); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); + /* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, true))); } } diff --git a/framework/main/classes/index/file/class_BaseFileIndex.php b/framework/main/classes/index/file/class_BaseFileIndex.php new file mode 100644 index 00000000..70887505 --- /dev/null +++ b/framework/main/classes/index/file/class_BaseFileIndex.php @@ -0,0 +1,315 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +abstract class BaseFileIndex extends BaseIndex implements FileIndexer { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Reads the file header + * + * @return void + * @throws UnexpectedValueException If header length or count of elements is invalid + */ + public function readIndexHeader () { + // First rewind to beginning as the header sits at the beginning ... + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!'); + $this->getIteratorInstance()->rewind(); + + // Then read it (see constructor for calculation) + $data = $this->getIteratorInstance()->read($this->getIteratorInstance()->getHeaderSize()); + + // Have all requested bytes been read? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getHeaderSize())); + if (strlen($data) != $this->getIteratorInstance()->getHeaderSize()) { + // Invalid header length + throw new UnexpectedValueException(sprintf('data(%d)=%s is not expected length %d', + strlen($data), + $data, + $this->getIteratorInstance()->getHeaderSize() + )); + } elseif (empty(trim($data, chr(0)))) { + // Empty file header + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: File header is empty - EXIT!'); + return; + } elseif (substr($data, -1, 1) != chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) { + // Bad last character + throw new UnexpectedValueException(sprintf('data=%s does not end with "%s"', + $data, + chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES) + )); + } + + // Okay, then remove it + $data = substr($data, 0, -1); + + // And update seek position + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->updateSeekPosition() ...'); + $this->getIteratorInstance()->updateSeekPosition(); + + /* + * Now split it: + * + * 0 => magic + * 1 => total entries + */ + $header = explode(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), $data); + + // Check if the array has only 3 elements + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: header()=%d', count($header))); + //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: header(%d)=%s', count($header), print_r($header, true))); + if (count($header) != 2) { + // Bad header + throw new UnexpectedValueException(sprintf('header()=%d is not expected value 2', count($header))); + } elseif ($header[0] !== Indexable::INDEX_MAGIC) { + // Magic must be in first element + throw new UnexpectedValueException(sprintf('header[0]=%s is not the expected magic (%s)', $header[0], Indexable::INDEX_MAGIC)); + } elseif (strlen($header[1]) != BaseBinaryFile::LENGTH_COUNT) { + // Length of total entries not matching + throw new UnexpectedValueException(sprintf('header[1](%d)=%s does not have expected length %d', strlen($header[1]), $header[1], BaseBinaryFile::LENGTH_COUNT)); + } + + // Decode count + $header[1] = hex2bin($header[1]); + + // Set it here + $this->getIteratorInstance()->setHeader($header); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: EXIT!'); + } + + /** + * Flushes the file header + * + * @return void + */ + public function flushFileHeader () { + // Put all informations together + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!'); + $header = sprintf('%s%s%s%s', + // Magic + Indexable::INDEX_MAGIC, + + // Separator header data + chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), + + // Total entries + str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getCounter()), BaseBinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT), + + // Separator header<->entries + chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES) + ); + + // Write it to disk (header is always at seek position 0) + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(0, header=%s) ...', $header)); + $this->getIteratorInstance()->writeAtPosition(0, $header); + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: EXIT!'); + } + + /** + * Initializes this index + * + * @param $fileInfoInstance An instance of a SplFileInfo class + * @return void + * @todo Currently the index file is not cached, please implement a memory-handling class and if enough RAM is found, cache the whole index file. + */ + protected function initIndex (SplFileInfo $fileInfoInstance) { + // Get a file i/o pointer instance for index file + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: fileInfoInstance[%s]=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance)); + $fileInstance = ObjectFactory::createObjectByConfiguredName('index_file_class', array($fileInfoInstance, $this)); + + // Get iterator instance + $iteratorInstance = ObjectFactory::createObjectByConfiguredName('file_iterator_class', [$fileInstance]); + + // Set iterator here + $this->setIteratorInstance($iteratorInstance); + + // Calculate header size + $headerSize = ( + strlen(Indexable::INDEX_MAGIC) + + strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA)) + + BaseBinaryFile::LENGTH_COUNT + + strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) + ); + + // Set it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Setting headerSize=%d ...', $headerSize)); + $this->getIteratorInstance()->setHeaderSize($headerSize); + + // Init counters and gaps array + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->initCountersGapsArray() ...'); + $this->getIteratorInstance()->initCountersGapsArray(); + + // Default is not created + $created = false; + + // Is the file's header initialized? + if (!$this->getIteratorInstance()->isFileHeaderInitialized()) { + // First pre-allocate a bit + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->preAllocateFile(index) ...'); + $this->getIteratorInstance()->preAllocateFile('index'); + + // Then write file header + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->createFileHeader() ...'); + $this->getIteratorInstance()->createFileHeader(); + + // Mark as freshly created + $created = true; + } + + // Load the file header + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->readIndexHeader() ...'); + $this->readIndexHeader(); + + // Freshly created? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: created=%d', intval($created))); + if (!$created) { + // Analyze file structure + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->analyzeFileStructure() ...'); + $this->getIteratorInstance()->analyzeFileStructure(); + } + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: EXIT!'); + } + + /** + * Calculates minimum length for one entry/block + * + * @return $length Minimum length for one entry/block + */ + public function calculateMinimumBlockLength () { + // Is it "cached"? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!'); + if (self::$minimumBlockLength == 0) { + // Calulcate it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calculating ...'); + self::$minimumBlockLength = ( + // Type + BaseBinaryFile::LENGTH_TYPE + strlen(chr(BaseBinaryFile::SEPARATOR_TYPE_POSITION)) + + // Position + BaseBinaryFile::LENGTH_POSITION + strlen(chr(BaseBinaryFile::SEPARATOR_ENTRIES)) + ); + } + + // Return it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: self::minimumBlockLength=%d - EXIT!', self::$minimumBlockLength)); + return self::$minimumBlockLength; + } + + /** + * "Getter" for file size + * + * @return $fileSize Size of currently loaded file + */ + public function getFileSize () { + // Call iterator's method + return $this->getIteratorInstance()->getFileSize(); + } + + /** + * Searches for next suitable gap the given length of data can fit in + * including padding bytes. + * + * @param $length Length of raw data + * @return $seekPosition Found next gap's seek position + * @throws InvalidArgumentException If the parameter is not valid + * @todo Unfinished work + */ + public function searchNextGap (int $length) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: length=%d - CALLED!', $length)); + if ($length <= 0) { + // Throw IAE + throw new InvalidArgumentException(sprintf('length=%d is not valid', $length)); + } + + // Partial stub! + $this->partialStub('length=' . $length); + } + + /** + * 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 OutOfBoundsException If the position is not seekable + * @throws InvalidArgumentException If a parameter is not valid + */ + public function writeAtPosition (int $seekPosition, string $dataStream) { + // Validate parameter + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream)); + if ($seekPosition < 0) { + // Invalid seek position + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition)); + } elseif (empty($dataStream)) { + // Empty dataStream + throw new InvalidArgumentException('Parameter "dataStream" is empty'); + } + + // Call iterated object's method + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream)); + $status = $this->getIteratorInstance()->writeAtPosition($seekPosition, $dataStream); + + // Return status + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: status[%s]=%d - EXIT!', gettype($status), $status)); + return $status; + } + + /** + * Checks if this index has been fully and properly loaded. + * + * @return $isLoaded Whether this index has been loaded + */ + public function isIndexLoaded () { + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!'); + /* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, true))); + } + +} diff --git a/framework/main/classes/index/file_stack/class_FileStackIndex.php b/framework/main/classes/index/file/stack/class_FileStackIndex.php similarity index 57% rename from framework/main/classes/index/file_stack/class_FileStackIndex.php rename to framework/main/classes/index/file/stack/class_FileStackIndex.php index 5e399b80..db2e7d4a 100644 --- a/framework/main/classes/index/file_stack/class_FileStackIndex.php +++ b/framework/main/classes/index/file/stack/class_FileStackIndex.php @@ -1,14 +1,14 @@ . */ -class FileStackIndex extends BaseIndex implements IndexableStack, Registerable { +class FileStackIndex extends BaseFileIndex implements IndexableStack, Registerable { /** * Protected constructor * @@ -70,18 +70,18 @@ class FileStackIndex extends BaseIndex implements IndexableStack, Registerable { /** * Adds given data's hash to an index file * - * @param $groupId Name of stack to add hash for + * @param $stackName Name of stack to add hash for * @param $data Hash and gap position to be added to the index * @return void * @throws InvalidArgumentException If a parameter is not valid * @throws UnexpectedValueException If an invalid gap position is being returned */ - public function addHashedDataToIndex (string $groupId, array $data) { + public function addHashedDataToIndex (string $stackName, array $data) { // Validate parameter - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: groupId=%s,data()=%d - CALLED!', $groupId, count($data))); - if (empty($groupId)) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,data()=%d - CALLED!', $stackName, count($data))); + if (empty($stackName)) { // Throw IAE - throw new InvalidArgumentException('Parameter "groupId" is empty'); + throw new InvalidArgumentException('Parameter "stackName" is empty'); } elseif (count($data) == 0) { // Throw it again throw new InvalidArgumentException('Parameter "data" is an empty array'); @@ -98,7 +98,7 @@ class FileStackIndex extends BaseIndex implements IndexableStack, Registerable { // Raw data been written to the file $rawData = sprintf('%s%s%s%s%s%s%s', - $groupId, + $stackName, Indexable::SEPARATOR_GROUP_HASH, hex2bin($data[StackableFile::ARRAY_NAME_HASH]), Indexable::SEPARATOR_HASH_GAP_POSITION, @@ -108,11 +108,11 @@ class FileStackIndex extends BaseIndex implements IndexableStack, Registerable { ); // Search for next free gap - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: groupId=%s,hash=%s,rawData()=%d', $groupId, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,rawData()=%d', $stackName, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); $gapPosition = $this->getIteratorInstance()->searchNextGap(strlen($rawData)); // Gap position cannot be smaller or equal than header length - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: groupId=%s,hash=%s,gapPosition=%s', $groupId, $data[StackableFile::ARRAY_NAME_HASH], $gapPosition)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,gapPosition=%s', $stackName, $data[StackableFile::ARRAY_NAME_HASH], $gapPosition)); if ($gapPosition <= ($this->getIteratorInstance()->getHeaderSize() + 1)) { // Not valid gap position returned throw new UnexpectedValueException(sprintf('gapPosition[%s]=%d is smaller or equal headerSize+1=%d', gettype($gapPosition), $gapPosition, ($this->getIteratorInstance()->getHeaderSize() + 1))); @@ -123,67 +123,7 @@ class FileStackIndex extends BaseIndex implements IndexableStack, Registerable { $this->getIteratorInstance()->writeData($gapPosition, $rawData); // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: groupId=%s,hash=%s,rawData()=%d - EXIT!', $groupId, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); - } - - /** - * Searches for next suitable gap the given length of data can fit in - * including padding bytes. - * - * @param $length Length of raw data - * @return $seekPosition Found next gap's seek position - * @throws InvalidArgumentException If the parameter is not valid - * @todo Unfinished work - */ - public function searchNextGap (int $length) { - // Validate parameter - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: length=%d - CALLED!', $length)); - if ($length <= 0) { - // Throw IAE - throw new InvalidArgumentException(sprintf('length=%d is not valid', $length)); - } - - // Partial stub! - $this->partialStub('length=' . $length); - } - - /** - * 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 InvalidArgumentException If a parameter is not valid - */ - public function writeAtPosition (int $seekPosition, string $dataStream) { - // Validate parameter - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream)); - if ($seekPosition < 0) { - // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition)); - } elseif (empty($dataStream)) { - // Empty dataStream - throw new InvalidArgumentException('Parameter "dataStream" is empty'); - } - - // Call iterated object's method - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: Calling this->iteratorInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream)); - $status = $this->getIteratorInstance()->writeAtPosition($seekPosition, $dataStream); - - // Return status - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: status[%s]=%d - EXIT!', gettype($status), $status)); - return $status; - } - - /** - * Checks if this index file has been fully and properly loaded. - * - * @return $isLoaded Whether this index file has been loaded - */ - public function isIndexFileLoaded () { - // Trace message - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-STACK-INDEX: CALLED!'); - /* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, true))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-STACK-INDEX: stackName=%s,hash=%s,rawData()=%d - EXIT!', $stackName, $data[StackableFile::ARRAY_NAME_HASH], strlen($rawData))); } } diff --git a/framework/main/classes/iterator/file/class_FileIterator.php b/framework/main/classes/iterator/file/class_FileIterator.php index 0163ffed..50a69ed9 100644 --- a/framework/main/classes/iterator/file/class_FileIterator.php +++ b/framework/main/classes/iterator/file/class_FileIterator.php @@ -11,6 +11,7 @@ use Org\Mxchange\CoreFramework\Traits\File\BinaryFileTrait; // Import SPL stuff use \BadMethodCallException; use \InvalidArgumentException; +use \OutOfBoundsException; /** * A file iterator @@ -161,14 +162,14 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator * @param $seekPosition Seek position in file * @param $whence Added to offset (default: only use offset to seek to) * @return $status Status of this operation - * @throws InvalidArgumentException If a parameter is not valid + * @throws OutOfBoundsException If the position is not seekable */ public function seek (int $seekPosition, int $whence = SEEK_SET) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,whence=%d - CALLED!', $seekPosition, $whence)); if ($seekPosition < 0) { // Throw IAE - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition)); } // Call file instance @@ -199,13 +200,14 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator * * @param $bytes Amount of bytes to read * @return $data Data read from file + * @throws OutOfBoundsException If the position is not seekable */ public function read (int $bytes = 0) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: bytes=%d - CALLED!', $bytes)); if ($bytes < 0) { - // Throw IAE - throw new InvalidArgumentException(sprintf('bytes=%d is not valid', $bytes)); + // Throw exception + throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes)); } // Call file instance @@ -411,16 +413,17 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator * @param $data Data to be written * @param $flushHeader Whether to flush the header (default: flush) * @return void + * @throws OutOfBoundsException If the position is not seekable * @throws InvalidArgumentException If a parameter is not valid */ public function writeData (int $seekPosition, string $data, bool $flushHeader = true) { // Validate parameter //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,data(%d)=%s,flushHeader=%d - CALLED!', $seekPosition, strlen($data), $data, intval($flushHeader))); if ($seekPosition < 0) { - // Throw IAE - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid', $seekPosition)); + // Throw exception + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition)); } elseif (empty($data)) { - // Throw it again + // Throw IAE throw new InvalidArgumentException('Parameter "data" is empty'); } @@ -438,6 +441,7 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator * @param $seekPosition Seek position in file * @param $dataStream Data to be written * @return mixed Number of writes bytes or false on error + * @throws OutOfBoundsException If the position is not seekable * @throws InvalidArgumentException If a parameter is not valid */ public function writeAtPosition (int $seekPosition, string $dataStream) { @@ -445,7 +449,7 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream)); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid.', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition)); } elseif (empty($dataStream)) { // Empty dataStream throw new InvalidArgumentException('Parameter "dataStream" is empty'); @@ -478,24 +482,24 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator /** * 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 InvalidArgumentException If a parameter is not valid */ - public function writeValueToFile (string $groupId, $value) { + public function writeValueToFile (string $stackName, $value) { // Validate parameter - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: groupId=%s,value[]=%s - CALLED!', $groupId, gettype($value))); - if (empty($groupId)) { + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,value[]=%s - CALLED!', $stackName, gettype($value))); + if (empty($stackName)) { // Throw IAE - throw new InvalidArgumentException('Parameter "groupId" is empty'); + throw new InvalidArgumentException('Parameter "stackName" is empty'); } elseif (is_resource($value) || is_object($value)) { // Resources and objects are nothing for file-based indexes (mostly) throw new InvalidArgumentException(sprintf('value[]=%s is not supported by file-based indexes', gettype($value))); } // Call file instance - $data = $this->getBinaryFileInstance()->writeValueToFile($groupId, $value); + $data = $this->getBinaryFileInstance()->writeValueToFile($stackName, $value); // Return data //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data))); @@ -505,17 +509,17 @@ class FileIterator extends BaseIterator implements SeekableWritableFileIterator /** * 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) { + public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) { // Validate parameter - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: groupId=%s,hash=%s,encoded(%d)=%s - CALLED!', $groupId, $hash, strlen($encoded), $encoded)); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,hash=%s,encoded(%d)=%s - CALLED!', $stackName, $hash, strlen($encoded), $encoded)); // Call file instance - $data = $this->getBinaryFileInstance()->writeDataToFreeGap($groupId, $hash, $encoded); + $data = $this->getBinaryFileInstance()->writeDataToFreeGap($stackName, $hash, $encoded); // Return data //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data))); diff --git a/framework/main/classes/output/console/class_ConsoleOutput.php b/framework/main/classes/output/console/class_ConsoleOutput.php index 1b11c51a..aaaf9435 100644 --- a/framework/main/classes/output/console/class_ConsoleOutput.php +++ b/framework/main/classes/output/console/class_ConsoleOutput.php @@ -99,37 +99,4 @@ class ConsoleOutput extends BaseOutput implements OutputStreamer { print trim($outStream) . PHP_EOL; } - /** - * Determines seek position - * - * @return $seekPosition Current seek position - * @throws UnsupportedOperationException If this method is called - */ - public function determineSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - * @throws UnsupportedOperationException If this method is called - */ - public function seek (int $offset, int $whence = SEEK_SET) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONSOLE-OUTPUT: offset=' . $offset . ',whence=' . $whence); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - * @throws UnsupportedOperationException If this method is called - */ - public function size () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - } diff --git a/framework/main/classes/output/debug/class_BaseDebugOutput.php b/framework/main/classes/output/debug/class_BaseDebugOutput.php index 3d743227..14bfb516 100644 --- a/framework/main/classes/output/debug/class_BaseDebugOutput.php +++ b/framework/main/classes/output/debug/class_BaseDebugOutput.php @@ -50,7 +50,7 @@ abstract class BaseDebugOutput extends BaseOutput { * @param $loggerClassName Class name this output class is being used for logging * @return void */ - public final function setLoggerClassName ($loggerClassName) { + public final function setLoggerClassName (string $loggerClassName) { $this->loggerClassName = $loggerClassName; } diff --git a/framework/main/classes/output/debug/console/class_DebugConsoleOutput.php b/framework/main/classes/output/debug/console/class_DebugConsoleOutput.php index 8f7d19f6..a43b7674 100644 --- a/framework/main/classes/output/debug/console/class_DebugConsoleOutput.php +++ b/framework/main/classes/output/debug/console/class_DebugConsoleOutput.php @@ -106,37 +106,4 @@ class DebugConsoleOutput extends BaseDebugOutput implements Debugger, OutputStre throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); } - /** - * Determines seek position - * - * @return $seekPosition Current seek position - * @throws UnsupportedOperationException If this method is called - */ - public function determineSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - * @throws UnsupportedOperationException If this method is called - */ - public function seek (int $offset, int $whence = SEEK_SET) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DEBUG-CONSOLE-OUTPUT: offset=' . $offset . ',whence=' . $whence); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - * @throws UnsupportedOperationException If this method is called - */ - public function size () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - } diff --git a/framework/main/classes/output/debug/error/class_DebugErrorLogOutput.php b/framework/main/classes/output/debug/error/class_DebugErrorLogOutput.php index 7903b910..5690466e 100644 --- a/framework/main/classes/output/debug/error/class_DebugErrorLogOutput.php +++ b/framework/main/classes/output/debug/error/class_DebugErrorLogOutput.php @@ -104,37 +104,4 @@ class DebugErrorLogOutput extends BaseDebugOutput implements Debugger, OutputStr throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); } - /** - * Determines for seek position - * - * @return $seekPosition Current seek position - * @throws UnsupportedOperationException If this method is called - */ - public function determineSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - * @throws UnsupportedOperationException If this method is called - */ - public function seek (int $offset, int $whence = SEEK_SET) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DEBUG-ERROR-LOG-OUTPUT: offset=' . $offset . ',whence=' . $whence); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - * @throws UnsupportedOperationException If this method is called - */ - public function size () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - } diff --git a/framework/main/classes/output/debug/web/class_DebugWebOutput.php b/framework/main/classes/output/debug/web/class_DebugWebOutput.php index e2656b1d..598f06d6 100644 --- a/framework/main/classes/output/debug/web/class_DebugWebOutput.php +++ b/framework/main/classes/output/debug/web/class_DebugWebOutput.php @@ -93,37 +93,4 @@ class DebugWebOutput extends BaseDebugOutput implements Debugger, OutputStreamer throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); } - /** - * Determines seek position - * - * @return $seekPosition Current seek position - * @throws UnsupportedOperationException If this method is called - */ - public function determineSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - * @throws UnsupportedOperationException If this method is called - */ - public function seek (int $offset, int $whence = SEEK_SET) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DEBUG-WEB-OUTPUT: offset=' . $offset . ',whence=' . $whence); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - * @throws UnsupportedOperationException If this method is called - */ - public function size () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - } diff --git a/framework/main/classes/output/web/class_WebOutput.php b/framework/main/classes/output/web/class_WebOutput.php index 6abfc10f..01d14239 100644 --- a/framework/main/classes/output/web/class_WebOutput.php +++ b/framework/main/classes/output/web/class_WebOutput.php @@ -5,7 +5,6 @@ namespace Org\Mxchange\CoreFramework\Output; // Import framework stuff use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap; use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException; -use Org\Mxchange\CoreFramework\Manager\ManageableApplication; use Org\Mxchange\CoreFramework\Output\BaseOutput; use Org\Mxchange\CoreFramework\Registry\Registerable; use Org\Mxchange\CoreFramework\Stream\Output\OutputStreamer; @@ -52,10 +51,9 @@ class WebOutput extends BaseOutput implements OutputStreamer, Registerable { /** * Create a new web output system and set the content type * - * @param $applicationInstance An instance of a ManageableApplication class - * @return $debugInstance An instance of this middleware class + * @return $webInstance An instance of an OutputStreamer class */ - public static final function createWebOutput (ManageableApplication $applicationInstance) { + public static final function createWebOutput () { // Is the self-instance already set? if (is_null(self::$webInstance)) { // Get a new instance and set it @@ -68,8 +66,8 @@ class WebOutput extends BaseOutput implements OutputStreamer, Registerable { if (!empty($contentType)) { // Set the header FrameworkBootstrap::getResponseInstance()->addHeader('Content-type', $contentType); - } // END - if - } // END - if + } + } // Return instance return self::$webInstance; @@ -86,37 +84,4 @@ class WebOutput extends BaseOutput implements OutputStreamer, Registerable { print(stripslashes($outStream)); } - /** - * Determines seek position - * - * @return $seekPosition Current seek position - * @throws UnsupportedOperationException If this method is called - */ - public function determineSeekPosition () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - * @throws UnsupportedOperationException If this method is called - */ - public function seek (int $offset, int $whence = SEEK_SET) { - self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('WEB-OUTPUT: offset=' . $offset . ',whence=' . $whence); - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - * @throws UnsupportedOperationException If this method is called - */ - public function size () { - throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION); - } - } diff --git a/framework/main/classes/stacker/file/class_BaseFileStack.php b/framework/main/classes/stacker/file/class_BaseFileStack.php index 66345fd7..6b4a8bfb 100644 --- a/framework/main/classes/stacker/file/class_BaseFileStack.php +++ b/framework/main/classes/stacker/file/class_BaseFileStack.php @@ -72,7 +72,7 @@ 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('BASE-FILE-STACK: CALLED!'); $this->getIteratorInstance()->rewind(); @@ -254,8 +254,8 @@ abstract class BaseFileStack extends BaseStacker { } // Load the file header - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Calling this->readFileHeader() ...'); - $this->readFileHeader(); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Calling this->readStackHeader() ...'); + $this->readStackHeader(); /* * Get stack index instance. This can be used for faster @@ -269,8 +269,8 @@ abstract class BaseFileStack extends BaseStacker { $this->setIndexInstance($indexInstance); // Is the index loaded correctly and the stack file is just created? - /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Calling this->indexInstance->isIndexFileLoaded() ...'); - if (!$this->getIndexInstance()->isIndexFileLoaded()) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-STACK: Calling 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 @@ -649,13 +649,13 @@ abstract class BaseFileStack extends BaseStacker { /** * 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))); + public function writeValueToFile (string $stackName, $value) { + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,value[%s]=%s', $stackName, gettype($value), print_r($value, true))); throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION); } @@ -691,16 +691,16 @@ abstract class BaseFileStack extends BaseStacker { /** * 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) { + public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) { // 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))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash=%s,encoded()=%d - CALLED!', $stackName, $hash, strlen($encoded))); $rawData = sprintf('%s%s%s%s%s', - $groupId, + $stackName, BaseBinaryFile::SEPARATOR_GROUP_HASH, hex2bin($hash), BaseBinaryFile::SEPARATOR_HASH_VALUE, @@ -708,7 +708,7 @@ abstract class BaseFileStack extends BaseStacker { ); // 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))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash=%s,rawData()=%d', $stackName, $hash, strlen($rawData))); $gapPosition = $this->getIteratorInstance()->searchNextGap(strlen($rawData)); // Gap position cannot be smaller than header length + 1 @@ -723,11 +723,11 @@ abstract class BaseFileStack extends BaseStacker { } // 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)); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-STACK: stackName=%s,hash=%s,gapPosition=%s', $stackName, $hash, $gapPosition)); $this->getIteratorInstance()->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=%s,rawData()=%d - EXIT!', $stackName, $hash, strlen($rawData))); return [ self::ARRAY_NAME_GAP_POSITION => $gapPosition, self::ARRAY_NAME_HASH => $hash, diff --git a/framework/main/classes/stacker/file/fifo/class_FiFoFileStack.php b/framework/main/classes/stacker/file/fifo/class_FiFoFileStack.php index 42eab523..16a5f263 100644 --- a/framework/main/classes/stacker/file/fifo/class_FiFoFileStack.php +++ b/framework/main/classes/stacker/file/fifo/class_FiFoFileStack.php @@ -10,6 +10,7 @@ use Org\Mxchange\CoreFramework\Stack\File\StackableFile; // Import SPL stuff use \InvalidArgumentException; +use \OutOfBoundsException; use \SplFileInfo; /** @@ -162,14 +163,14 @@ class FiFoFileStack extends BaseFileStack implements StackableFile, Calculatable * @param $seekPosition Seek position in file * @param $whence Added to offset (default: only use offset to seek to) * @return $status Status of this operation - * @throws InvalidArgumentException If a parameter is invalid + * @throws OutOfBoundsException If the position is not seekable */ public function seek (int $seekPosition, int $whence = SEEK_SET) { // Validate parameter /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FIFO-FILE-STACK: seekPosition=%d,whence=%d - CALLED!', $seekPosition, $whence)); if ($seekPosition < 0) { // Invalid seek position - throw new InvalidArgumentException(sprintf('seekPosition=%d is not valid', $seekPosition)); + throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition)); } // @TODO Unfinished method or invoke inner iterator's method? diff --git a/framework/main/interfaces/index/class_Indexable.php b/framework/main/interfaces/index/class_Indexable.php index d09095a2..5eba1b56 100644 --- a/framework/main/interfaces/index/class_Indexable.php +++ b/framework/main/interfaces/index/class_Indexable.php @@ -48,4 +48,11 @@ interface Indexable extends FrameworkInterface { */ const SEPARATOR_GAP_LENGTH = 0x03; + /** + * Checks whether the index has been fully loaded (and parsed) + * + * @return $isLoaded Whether the index has been loaded + */ + function isIndexLoaded (); + } diff --git a/framework/main/interfaces/index/stack/class_IndexableStack.php b/framework/main/interfaces/index/file/class_FileIndexer.php similarity index 63% rename from framework/main/interfaces/index/stack/class_IndexableStack.php rename to framework/main/interfaces/index/file/class_FileIndexer.php index 2576ce5a..9a90b360 100644 --- a/framework/main/interfaces/index/stack/class_IndexableStack.php +++ b/framework/main/interfaces/index/file/class_FileIndexer.php @@ -1,13 +1,12 @@ * @version 0.0.0 @@ -28,7 +27,7 @@ use Org\Mxchange\CoreFramework\Index\Indexable; * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -interface IndexableStack extends Indexable, CalculatableBlock { +interface FileIndexer extends Indexable { /** * Adds given data's hash to the index file * @@ -40,10 +39,23 @@ interface IndexableStack extends Indexable, CalculatableBlock { function addHashedDataToIndex (string $stackName, array $data); /** - * Checks whether the index' file has been fully loaded (and parsed) + * Searches for next suitable gap the given length of data can fit in + * including padding bytes. * - * @return $isLoaded Whether the index' file has been loaded + * @param $length Length of raw data + * @return $seekPosition Found next gap's seek position + * @throws InvalidArgumentException If the parameter is not valid */ - function isIndexFileLoaded (); + function searchNextGap (int $length); + + /** + * 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 InvalidArgumentException If a parameter is not valid + */ + function writeAtPosition (int $seekPosition, string $dataStream); } diff --git a/framework/main/traits/index/stack/class_IndexableStackTrait.php b/framework/main/interfaces/index/file/stack/class_IndexableStack.php similarity index 52% rename from framework/main/traits/index/stack/class_IndexableStackTrait.php rename to framework/main/interfaces/index/file/stack/class_IndexableStack.php index 15e46ac7..be0a44cb 100644 --- a/framework/main/traits/index/stack/class_IndexableStackTrait.php +++ b/framework/main/interfaces/index/file/stack/class_IndexableStack.php @@ -1,12 +1,13 @@ * @version 0.0.0 @@ -25,31 +26,8 @@ use Org\Mxchange\CoreFramework\Index\Stack\IndexableStack; * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ -trait IndexableStackTrait { - /** - * An instance of an IndexableStack class - */ - private $indexInstance = NULL; - - /** - * Setter for IndexableStack instance - * - * @param $indexInstance An instance of an IndexableStack class - * @return void - */ - protected final function setIndexableStackInstance (IndexableStack $indexInstance) { - $this->indexInstance = $indexInstance; - } - - /** - * Getter for IndexableStack instance - * - * @return $indexInstance An instance of an IndexableStack class - */ - public final function getIndexableStackInstance () { - return $this->indexInstance; - } +interface IndexableStack extends FileIndexer { } diff --git a/framework/main/interfaces/io/class_Streamable.php b/framework/main/interfaces/io/class_Streamable.php index 3fe663d3..a9dede2e 100644 --- a/framework/main/interfaces/io/class_Streamable.php +++ b/framework/main/interfaces/io/class_Streamable.php @@ -28,27 +28,5 @@ use Org\Mxchange\CoreFramework\Generic\FrameworkInterface; * along with this program. If not, see . */ interface Streamable extends FrameworkInterface { - /** - * Determines seek position - * - * @return $seekPosition Current seek position - */ - function determineSeekPosition (); - - /** - * Seek to given offset (default) or other possibilities as fseek() gives. - * - * @param $offset Offset to seek to (or used as "base" for other seeks) - * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed - */ - function seek (int $offset, int $whence = SEEK_SET); - - /** - * Size of file stack - * - * @return $size Size (in bytes) of file - */ - function size (); } diff --git a/framework/main/interfaces/io/class_StreamableInput.php b/framework/main/interfaces/io/class_StreamableInput.php index 49e4a9d9..400509ab 100644 --- a/framework/main/interfaces/io/class_StreamableInput.php +++ b/framework/main/interfaces/io/class_StreamableInput.php @@ -28,5 +28,28 @@ use Org\Mxchange\CoreFramework\Stream\Streamable; * along with this program. If not, see . */ interface StreamableInput extends Streamable { + /** + * Determines seek position + * + * @return $seekPosition Current seek position + */ + function determineSeekPosition (); + + /** + * Seek to given offset (default) or other possibilities as fseek() gives. + * + * @param $offset Offset to seek to (or used as "base" for other seeks) + * @param $whence Added to offset (default: only use offset to seek to) + * @return void + * @throws OutOfBoundsException If the position is not seekable + */ + function seek (int $offset, int $whence = SEEK_SET); + + /** + * Size of file stack + * + * @return $size Size (in bytes) of file + */ + function size (); } diff --git a/framework/main/interfaces/iterator/file/class_SeekableWritableFileIterator.php b/framework/main/interfaces/iterator/file/class_SeekableWritableFileIterator.php index 21ad59ef..64e49f53 100644 --- a/framework/main/interfaces/iterator/file/class_SeekableWritableFileIterator.php +++ b/framework/main/interfaces/iterator/file/class_SeekableWritableFileIterator.php @@ -29,14 +29,6 @@ use \SeekableIterator; * along with this program. If not, see . */ interface SeekableWritableFileIterator extends SeekableIterator { - /** - * Seeks to given position - * - * @param $seekPosition Seek position in file - * @return $status Status of this operation - */ - function seek (int $seekPosition); - /** * Size of file stack * diff --git a/framework/main/interfaces/stacker/file/class_StackableFile.php b/framework/main/interfaces/stacker/file/class_StackableFile.php index f01e8b3d..2d8094b1 100644 --- a/framework/main/interfaces/stacker/file/class_StackableFile.php +++ b/framework/main/interfaces/stacker/file/class_StackableFile.php @@ -64,14 +64,14 @@ interface StackableFile extends Stackable { function size (); /** - * Reads the file header + * Reads the stack's file header * * @return void * @todo To hard assertions here, better rewrite them to exceptions * @throws UnexpectedValueException If header is not proper length * @throws InvalidMagicException If a bad magic was found */ - function readFileHeader (); + function readStackHeader (); /** * Flushes the file header diff --git a/framework/main/middleware/io/class_FileIoHandler.php b/framework/main/middleware/io/class_FileIoHandler.php index dfdcd79e..2b0aa9bc 100644 --- a/framework/main/middleware/io/class_FileIoHandler.php +++ b/framework/main/middleware/io/class_FileIoHandler.php @@ -154,7 +154,7 @@ class FileIoHandler extends BaseMiddleware implements IoHandler { * * @param $offset Offset to seek to (or used as "base" for other seeks) * @param $whence Added to offset (default: only use offset to seek to) - * @return $status Status of file seek: 0 = success, -1 = failed + * @return void */ public function seek (int $offset, int $whence = SEEK_SET) { $this->partialStub('offset=' . $offset . ',whence=' . $whence); -- 2.39.2