X-Git-Url: https://git.mxchange.org/?p=core.git;a=blobdiff_plain;f=inc%2Fclasses%2Fmain%2Fiterator%2Fio%2Fclass_FileIoIterator.php;h=20d351f5e694d09b43376e8d1badc8b6f7368dfa;hp=3437d1165902af54a1cc557527ec90cdd924844a;hb=4af01023fc4b9ffc4c7174264dbff53966aecc91;hpb=a863937b246c06e143d147fe4108543056971472 diff --git a/inc/classes/main/iterator/io/class_FileIoIterator.php b/inc/classes/main/iterator/io/class_FileIoIterator.php index 3437d116..20d351f5 100644 --- a/inc/classes/main/iterator/io/class_FileIoIterator.php +++ b/inc/classes/main/iterator/io/class_FileIoIterator.php @@ -22,6 +22,16 @@ * along with this program. If not, see . */ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterator { + /** + * Back-buffer + */ + private $backBuffer = ''; + + /** + * Currently loaded block (will be returned by current()) + */ + private $currentBlock = ''; + /** * Protected constructor * @@ -36,32 +46,78 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato * Creates an instance of this 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 (InputOutputPointer $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,7 +136,53 @@ 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()) { + // Set whole data as current block + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('Calling setCurrentBlock(' . strlen($data) . ') ...'); + $this->setCurrentBlock($data); + + // Then abort here silently + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('EOF reached.'); + 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); + + // This array must contain two elements + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('dataArray=' . print_r($dataArray, TRUE)); + assert(count($dataArray) == 2); + + // Left part is the actual block, right one the back-buffer data + $this->setCurrentBlock($dataArray[0]); + $this->setBackBuffer($dataArray[1]); } /** @@ -97,10 +199,38 @@ class FileIoIterator extends BaseIterator implements SeekableWritableFileIterato * Checks wether the current entry is valid (not at the end of the file). * This method will return TRUE if an emptied (nulled) entry has been found. * - * @return void + * @return $isValid Whether the next entry is valid */ public function valid () { - $this->partialStub('Please implement this method.'); + // 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; } /**