* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
interface InputOutputPointer extends InputPointer, OutputPointer {
+ /**
+ * Rewinds to the beginning of the file
+ *
+ * @return void
+ */
+ function rewind ();
+
+ /**
+ * Seeks to given position
+ *
+ * @param $seekPosition Seek position in file
+ * @param $whence "Seek mode" (see http://de.php.net/fseek)
+ * @return void
+ */
+ function seek ($seekPosition, $whence = SEEK_SET);
}
// [EOF]
* @return $size Size (in bytes) of file
*/
function size ();
+
+ /**
+ * Writes at given position by seeking to it.
+ *
+ * @param $seekPosition Seek position in file
+ * @param $data Data to be written
+ * @return void
+ */
+ function writeAtPosition ($seedPosition, $data);
}
// [EOF]
}
// Write data to the file pointer and return written bytes
- return fwrite($this->getPointer(), $dataStream);
+ return fwrite($this->getPointer(), $dataStream, strlen($dataStream));
+ }
+
+ /**
+ * Rewinds to the beginning of the file
+ *
+ * @return void
+ */
+ public function rewind () {
+ // Rewind the pointer
+ assert(rewind($this->getPointer() === 1);
+ }
+
+ /**
+ * Seeks to given position
+ *
+ * @param $seekPosition Seek position in file
+ * @param $whence "Seek mode" (see http://de.php.net/fseek)
+ * @return void
+ */
+ public function seek ($seekPosition, $whence = SEEK_SET) {
+ // Move the file pointer
+ assert(fseek($this->getPointerInstance(), $seekPosition, $whence) === 0);
}
}
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class FileIoIterator extends BaseIterator implements SeekableWritableFileIterator {
- /**
- * Current absolute seek position (returned by key())
- */
- private $seekPosition = FALSE;
-
- /**
- * Total entries (read from file)
- */
- private $totalEntriesFile = FALSE;
-
/**
* Protected constructor
*
* @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()->getSeekPosition();
}
/**
* @return void
*/
public function rewind () {
- $this->partialStub('Please implement this method.');
+ // Call pointer instance
+ $this->getPointerInstance()->rewind();
}
/**
* @param $seekPosition Seek position in file
* @return void
*/
- public function seek ($seedPosition) {
- $this->partialStub('Please implement this method. seekPosition=' . $seekPosition);
+ public function seek ($seekPosition) {
+ // Call pointer instance
+ $this->getPointerInstance()->seek($seekPosition);
+ }
+
+ /**
+ * Writes at given position by seeking to it.
+ *
+ * @param $seekPosition Seek position in file
+ * @param $data Data to be written
+ * @return void
+ */
+ public function writeAtPosition ($seedPosition, $data) {
+ // First seek to it
+ $this->seek($seekPosition);
+
+ // Then write the data at that position
+ $this->getPointerInstance()->writeToFile($data);
}
/**
*/
const COUNT_POSITION = 20;
+ /**
+ * Counter for total entries
+ */
+ private $totalEntries = 0;
+
+ /**
+ * Current seek position
+ */
+ private $seekPosition = 0;
+
/**
* Protected constructor
*
parent::__construct($className);
}
+ /**
+ * Getter for total entries
+ *
+ * @return $totalEntries Total entries in this stack
+ */
+ private function getCounter () {
+ // Get it
+ return $this->totalEntries;
+ }
+
+ /**
+ * Increment counter
+ *
+ * @return void
+ */
+ private function incrementCounter () {
+ // Get it
+ $this->totalEntries++;
+ }
+
+ /**
+ * Getter for seek position
+ *
+ * @return $seekPosition Current seek position (stored here in object)
+ */
+ private function getSeekPosition () {
+ // Get it
+ return $this->seekPosition;
+ }
+
+ /**
+ * Setter for seek position
+ *
+ * @param $seekPosition Current seek position (stored here in object)
+ * @return void
+ */
+ private function setSeekPosition ($seekPosition) {
+ // And set it
+ $this->seekPosition = $seekPosition;
+ }
+
+ /**
+ * Updates seekPosition attribute from file to avoid to much access on file.
+ *
+ * @return void
+ */
+ private function updateSeekPosition () {
+ // Get key (= seek position)
+ $seekPosition = $this->getIteratorInstance()->key();
+
+ // And set it here
+ $this->setSeekPosition($seekPosition);
+ }
+
/**
* Checks whether the file header is initialized
*
// The file's header should not be initialized here
assert(!$this->isFileHeaderInitialized());
- // Init counter
- $this->getIteratorInstance()->initCounter();
-
// Flush file header
$this->flushFileHeader();
}
chr(self::SEPARATOR_MAGIC_COUNT),
// Total entries (will be zero) and pad it to 20 chars
- str_pad($this->dec2hex($this->getIteratorInstance()->getCount()), self::COUNT_LENGTH, '0', STR_PAD_LEFT),
+ str_pad($this->dec2hex($this->getCounter()), self::COUNT_LENGTH, '0', STR_PAD_LEFT),
// Position (will be zero)
str_pad($this->dec2hex(0, 2), self::COUNT_POSITION, '0', STR_PAD_LEFT),
chr(self::SEPARATOR_SEEK_POS_ENTRIES)
);
- // Write it to disk
+ // Write it to disk (header is always at seek position 0)
$this->getIteratorInstance()->writeAtPosition(0, $header);
+
+ // Update seek position
+ $this->updateSeekPosition();
}
/**