*/
const LENGTH_TYPE = 20;
+ //***** Array elements for 'gaps' array *****
+
+ /**
+ * Start of gap
+ */
+ const GAPS_INDEX_START = 'start';
+
+ /**
+ * End of gap
+ */
+ const GAPS_INDEX_END = 'end';
+
/**
* Length of output from hash()
*/
*
* @return void
*/
- protected function initCountersGapsArray () {
+ public function initCountersGapsArray () {
// Init counter and seek position
$this->setCounter(0);
$this->setSeekPosition(0);
* @param $headerSize Size of file header
* @return void
*/
- protected final function setHeaderSize ($headerSize) {
+ public final function setHeaderSize ($headerSize) {
// Set it
$this->headerSize = $headerSize;
}
*
* @return void
*/
- protected function rewineUpdateSeekPosition () {
+ protected function rewindUpdateSeekPosition () {
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
// flushFileHeader must be callable
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
}
+ /**
+ * Marks the currently loaded block as empty (with length of the block)
+ *
+ * @param $length Length of the block
+ * @return void
+ */
+ protected function markCurrentBlockAsEmpty ($length) {
+ // Get current seek position
+ $currentPosition = $this->key();
+
+ // Now add it as gap entry
+ array_push($this->gaps, array(
+ self::GAPS_INDEX_START => ($currentPosition - $length),
+ self::GAPS_INDEX_END => $currentPosition,
+ ));
+ }
+
/**
* Checks whether the file header is initialized
*
$this->flushFileHeader();
// Rewind seek position (to beginning of file) and update/flush file header
- $this->rewineUpdateSeekPosition();
+ $this->rewindUpdateSeekPosition();
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
}
$this->writeData($seekPosition, chr(0));
// Rewind seek position (to beginning of file) and update/flush file header
- $this->rewineUpdateSeekPosition();
+ $this->rewindUpdateSeekPosition();
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
}
* Advances to next "block" of bytes
*
* @return void
- * @todo This method will load large but empty files in a whole
*/
public function next () {
// Is there nothing to read?
// Short be more than zero!
assert($length > 0);
- // Wait until a entry/block separator has been found
+ // Read possibly back-buffered bytes from previous call of next().
$data = $this->getBackBuffer();
+
+ /*
+ * Read until a entry/block separator has been found. The next read
+ * "block" may not fit, so this loop will continue until the EOB or EOF
+ * has been reached whatever comes first.
+ */
while ((!$this->isEndOfFileReached()) && (!self::isBlockSeparatorFound($data))) {
- // Then read the block
- $data .= $this->read($length);
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('data()=' . strlen($data));
+ // Then read the next possible block
+ $block = $this->read($length);
+
+ // Is it all empty?
+ if (strlen(trim($block)) == 0) {
+ // Mark this block as empty
+ $this->markCurrentBlockAsEmpty($length);
+
+ // Skip to next block
+ continue;
+ } // END - if
+
+ // At this block then
+ $data .= $block;
+
+ // A debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d] data()=%s', __FUNCTION__, __LINE__, strlen($data)));
} // END - if
// EOF reached?
if ($this->isEndOfFileReached()) {
- // Set whole data as current block
+ // Set whole data as current read block
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('Calling setCurrentBlock(' . strlen($data) . ') ...');
$this->setCurrentBlock($data);