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=1791e6150c465fef0f07bd071c044505b16ac4b8;hb=4fc380553961d8b3f21aa5a5fa3742729367ba14;hpb=86efcb137a3a9a692018ace94bbe5057d23b6825 diff --git a/inc/classes/main/iterator/io/class_FileIoIterator.php b/inc/classes/main/iterator/io/class_FileIoIterator.php index 1791e615..9ef4801d 100644 --- a/inc/classes/main/iterator/io/class_FileIoIterator.php +++ b/inc/classes/main/iterator/io/class_FileIoIterator.php @@ -21,7 +21,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class FileIoIterator extends BaseIterator implements SeekableFileIterator { +class FileIoIterator extends BaseIterator implements SeekableWritableFileIterator { + /** + * Back-buffer + */ + private $backBuffer = ''; + + /** + * Currently loaded block (will be returned by current()) + */ + private $currentBlock = ''; + /** * Protected constructor * @@ -35,33 +45,79 @@ class FileIoIterator extends BaseIterator implements SeekableFileIterator { /** * 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; } /** @@ -70,13 +126,8 @@ class FileIoIterator extends BaseIterator implements SeekableFileIterator { * @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(); } /** @@ -85,36 +136,142 @@ class FileIoIterator extends BaseIterator implements SeekableFileIterator { * @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); } }