X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Fiterator%2Fio%2Fclass_FileIoIterator.php;h=9ef4801d2a25dc6ab807492ea9c4744b3056afc6;hp=1d5469220c6af91229ec0d73c5895f886ab207ec;hb=4fc380553961d8b3f21aa5a5fa3742729367ba14;hpb=bf7bc14731bd4f410f0d54d538f7c9dd35b1a12f diff --git a/inc/classes/main/iterator/io/class_FileIoIterator.php b/inc/classes/main/iterator/io/class_FileIoIterator.php index 1d546922..9ef4801d 100644 --- a/inc/classes/main/iterator/io/class_FileIoIterator.php +++ b/inc/classes/main/iterator/io/class_FileIoIterator.php @@ -23,14 +23,14 @@ */ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterator { /** - * Current absolute seek position (returned by key()) + * Back-buffer */ - private $seekPosition = -1; + private $backBuffer = ''; /** - * Total entries (read from file) + * Currently loaded block (will be returned by current()) */ - private $totalEntriesFile = -1; + private $currentBlock = ''; /** * Protected constructor @@ -45,33 +45,79 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato /** * Creates an instance of this class * - * @param $pointerInstance An instance of a FrameworkFileInputOutputPointer class + * @param $pointerInstance An instance of a InputOutputPointer class + * @param $blockInstance An instance of a CalculatableBlock class * @return $iteratorInstance An instance of a Iterator class */ - public final static function createFileIoIterator (FrameworkFileInputOutputPointer $pointerInstance) { + public final static function createFileIoIterator (InputOutputPointer $pointerInstance, CalculatableBlock $blockInstance) { // Get new instance $iteratorInstance = new FileIoIterator(); // Set the instance here $iteratorInstance->setPointerInstance($pointerInstance); + // Set the block instance here + $iteratorInstance->setBlockInstance($blockInstance); + // Return the prepared instance return $iteratorInstance; } + /** + * Initializes the back-buffer by setting it to an empty string. + * + * @return void + */ + private function initBackBuffer () { + // Simply call the setter + $this->setBackBuffer(''); + } + + /** + * Setter for backBuffer field + * + * @param $backBuffer Characters to "store" in back-buffer + * @return void + */ + private function setBackBuffer ($backBuffer) { + // Cast to string (so no arrays or objects) + $backBuffer = (string) $backBuffer; + + // ... and set it + $this->backBuffer = $backBuffer; + } + + /** + * Getter for backBuffer field + * + * @return $backBuffer Characters "stored" in back-buffer + */ + private function getBackBuffer () { + return $this->backBuffer; + } + + /** + * Setter for currentBlock field + * + * @param $currentBlock Characters to set a currently loaded block + * @return void + */ + private function setCurrentBlock ($currentBlock) { + // Cast to string (so no arrays or objects) + $currentBlock = (string) $currentBlock; + + // ... and set it + $this->currentBlock = $currentBlock; + } + /** * Gets currently read data * * @return $current Currently read data */ public function current () { - // Default is null - $current = null; - - $this->partialStub('Please implement this method.'); - // Return it - return $current; + return $this->currentBlock; } /** @@ -80,13 +126,8 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato * @return $key Current key in iteration */ public function key () { - // Default is null - $key = null; - - $this->partialStub('Please implement this method.'); - // Return it - return $key; + return $this->getPointerInstance()->determineSeekPosition(); } /** @@ -95,36 +136,142 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato * @return void */ public function next () { - $this->partialStub('Please implement this method.'); + // Is there nothing to read? + if (!$this->valid()) { + // Nothing to read + return; + } // END - if + + // First calculate minimum block length + $length = $this->getBlockInstance()->caluclateMinimumBlockLength(); + + // Short be more than zero! + assert($length > 0); + + // Wait until a entry/block separator has been found + $data = $this->getBackBuffer(); + while (($this->getPointerInstance()->isEndOfFileReached()) && (!$this->getBlockInstance()->isBlockSeparatorFound($data))) { + // Then read the block + $data .= $this->read($length); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('data()=' . strlen($data)); + } // END - if + + // EOF reached? + if ($this->getPointerInstance()->isEndOfFileReached()) { + // Then abort here silently + return; + } // END - if + + /* + * Init back-buffer which is the data that has been found beyond the + * separator. + */ + $this->initBackBuffer(); + + // Separate data + $dataArray = explode(self::getBlockSeparator(), $data); + + // Left part is the actual block, right one the back-buffer data + $this->setCurrentBlock($dataArray[0]); + $this->setBackBuffer($dataArray[1]); } /** * Rewinds to the beginning of the file * - * @return void + * @return $status Status of this operation */ public function rewind () { - $this->partialStub('Please implement this method.'); + // Call pointer instance + return $this->getPointerInstance()->rewind(); + } + + /** + * Checks wether the current entry is valid (not at the end of the file). + * This method will return TRUE if an emptied (nulled) entry has been found. + * + * @return $isValid Whether the next entry is valid + */ + public function valid () { + // First calculate minimum block length + $length = $this->getBlockInstance()->caluclateMinimumBlockLength(); + + // Short be more than zero! + assert($length > 0); + + // Get current seek position + $seekPosition = $this->key(); + + // Then try to read it + $data = $this->read($length); + + // If some bytes could be read, all is fine + $isValid = ((is_string($data)) && (strlen($data) > 0)); + + // Get header size + $headerSize = $this->getBlockInstance()->getHeaderSize(); + + // Is the seek position at or beyond the header? + if ($seekPosition >= $headerSize) { + // Seek back to old position + $this->seek($seekPosition); + } else { + // Seek directly behind the header + $this->seek($headerSize); + } + + // Return result + return $isValid; } /** * Seeks to given position * * @param $seekPosition Seek position in file - * @return void + * @return $status Status of this operation */ - public function seek ($seedPosition) { - $this->partialStub('Please implement this method. seekPosition=' . $seekPosition); + public function seek ($seekPosition) { + // Call pointer instance + return $this->getPointerInstance()->seek($seekPosition); } /** - * Checks wether the current entry is valid (not at the end of the file). - * This method will return TRUE if an emptied (nulled) entry has been found. + * Writes at given position by seeking to it. * + * @param $seekPosition Seek position in file + * @param $data Data to be written * @return void */ - public function valid () { - $this->partialStub('Please implement this method.'); + public function writeAtPosition ($seekPosition, $data) { + // First seek to it + $this->seek($seekPosition); + + // Then write the data at that position + $this->getPointerInstance()->writeToFile($data); + } + + /** + * Size of file stack + * + * @return $size Size (in bytes) of file + */ + public function size () { + // Call the pointer object + $size = $this->getPointerInstance()->size(); + + // Return result + return $size; + } + + /** + * Reads given amount of bytes from file. + * + * @param $bytes Amount of bytes to read + * @return $data Data read from file + */ + public function read ($bytes) { + // Call pointer instance + return $this->getPointerInstance()->read($bytes); } }