// Import framework stuff
use Org\Mxchange\CoreFramework\Filesystem\File\BinaryFile;
use Org\Mxchange\CoreFramework\Iterator\BaseIterator;
-use Org\Mxchange\CoreFramework\Iterator\Filesystem\SeekableWritableFileIterator;
use Org\Mxchange\CoreFramework\Traits\File\BinaryFileTrait;
// Import SPL stuff
use \BadMethodCallException;
use \InvalidArgumentException;
use \OutOfBoundsException;
+use \SeekableIterator;
/**
* A file iterator
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-class FileIterator extends BaseIterator implements SeekableWritableFileIterator {
+class FileIterator extends BaseIterator implements SeekableIterator {
// Load traits
use BinaryFileTrait;
* Seeks to given position
*
* @param $seekPosition Seek position in file
- * @param $whence Added to offset (default: only use offset to seek to)
- * @return $status Status of this operation
+ * @return void
* @throws OutOfBoundsException If the position is not seekable
*/
- public function seek (int $seekPosition, int $whence = SEEK_SET) {
+ public function seek (int $seekPosition) {
// Validate parameter
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,whence=%d - CALLED!', $seekPosition, $whence));
if ($seekPosition < 0) {
}
// Call file instance
- $status = $this->getBinaryFileInstance()->seek($seekPosition, $whence);
-
- // Return status
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: status=%d - EXIT!', intval($status)));
- return $status;
- }
-
- /**
- * Size of file stack
- *
- * @return $size Size (in bytes) of file
- */
- public function size () {
- // Call the file object
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $size = $this->getBinaryFileInstance()->size();
-
- // Return size
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
- return $size;
- }
-
- /**
- * Reads given amount of bytes from file.
- *
- * @param $bytes Amount of bytes to read
- * @return $data Data read from file
- * @throws OutOfBoundsException If the position is not seekable
- */
- public function read (int $bytes = 0) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: bytes=%d - CALLED!', $bytes));
- if ($bytes < 0) {
- // Throw exception
- throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes));
- }
-
- // Call file instance
- $data = $this->getBinaryFileInstance()->read($bytes);
-
- // Return data
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
- return $data;
- }
-
- /**
- * Analyzes entries in index file. This will count all found (and valid)
- * entries, mark invalid as damaged and count gaps ("fragmentation"). If
- * only gaps are found, the file is considered as "virgin" (no entries).
- *
- * @return void
- */
- public function analyzeFileStructure () {
- // Just call the file instance
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $this->getBinaryFileInstance()->analyzeFileStructure();
-
- // Trace message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Checks whether the file header is initialized
- *
- * @return $isInitialized Whether the file header is initialized
- */
- public function isFileHeaderInitialized () {
- // Just call the file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $isInitialized = $this->getBinaryFileInstance()->isFileHeaderInitialized();
-
- // Return flag
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: isInitialized=%d - EXIT!', intval($isInitialized)));
- return $isInitialized;
- }
-
- /**
- * Creates the assigned file
- *
- * @return void
- */
- public function createFileHeader () {
- // Just call the file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $this->getBinaryFileInstance()->createFileHeader();
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Pre-allocates file (if enabled) with some space for later faster write access.
- *
- * @param $type Type of the file
- * @return void
- * @throws InvalidArgumentException If a parameter is not valid
- */
- public function preAllocateFile (string $type) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: type=%s - CALLED!', $type));
- if (empty($type)) {
- // Throw IAE
- throw new InvalidArgumentException('Parameter "type" is empty');
- }
-
- // Just call the file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: Calling this->binaryFileInstance->preAllocateFile(%s) ...', $type));
- $this->getBinaryFileInstance()->preAllocateFile($type);
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Initializes counter for valid entries, arrays for damaged entries and
- * an array for gap seek positions. If you call this method on your own,
- * please re-analyze the file structure. So you are better to call
- * analyzeFileStructure() instead of this method.
- *
- * @return void
- */
- public function initCountersGapsArray () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $this->getBinaryFileInstance()->initCountersGapsArray();
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Getter for header size
- *
- * @return $totalEntries Size of file header
- */
- public final function getHeaderSize () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $size = $this->getBinaryFileInstance()->getHeaderSize();
-
- // Return size
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
- return $size;
- }
-
- /**
- * Setter for header size
- *
- * @param $headerSize Size of file header
- * @return void
- */
- public final function setHeaderSize (int $headerSize) {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: headerSize=%d - CALLED!', $headerSize));
- $this->getBinaryFileInstance()->setHeaderSize($headerSize);
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Getter for header array
- *
- * @return $header Header array
- */
- public final function getHeader () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $header = $this->getBinaryFileInstance()->getHeader();
-
- // Return it
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: header()=%d - EXIT!', count($header)));
- return $header;
- }
-
- /**
- * Setter for header
- *
- * @param $header Array for a file header
- * @return void
- */
- public final function setHeader (array $header) {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: header()=%d - CALLED!', count($header)));
- $this->getBinaryFileInstance()->setHeader($header);
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Updates seekPosition attribute from file to avoid to much access on file.
- *
- * @return void
- */
- public function updateSeekPosition () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $this->getBinaryFileInstance()->updateSeekPosition();
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
- }
-
- /**
- * Getter for total entries
- *
- * @return $totalEntries Total entries in this file
- */
- public final function getCounter () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $counter = $this->getBinaryFileInstance()->getCounter();
-
- // Return counter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: counter=%d - EXIT!', $counter));
- return $counter;
- }
-
- /**
- * "Getter" for file size
- *
- * @return $fileSize Size of currently loaded file
- */
- public function getFileSize () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $size = $this->getBinaryFileInstance()->getFileSize();
-
- // Return size
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
- return $size;
- }
-
- /**
- * Writes data at given position
- *
- * @param $seekPosition Seek position
- * @param $data Data to be written
- * @param $flushHeader Whether to flush the header (default: flush)
- * @return void
- * @throws OutOfBoundsException If the position is not seekable
- * @throws InvalidArgumentException If a parameter is not valid
- */
- public function writeData (int $seekPosition, string $data, bool $flushHeader = true) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,data(%d)=%s,flushHeader=%d - CALLED!', $seekPosition, strlen($data), $data, intval($flushHeader)));
- if ($seekPosition < 0) {
- // Throw exception
- throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition));
- } elseif (empty($data)) {
- // Throw IAE
- throw new InvalidArgumentException('Parameter "data" is empty');
- }
-
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: Calling this->binaryFileInstance->writeData(%d,data()=%d,%d) ...', $seekPosition, strlen($data), intval($flushHeader)));
- $this->getBinaryFileInstance()->writeData($seekPosition, $data, $flushHeader);
+ $this->getBinaryFileInstance()->seek($seekPosition);
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
}
- /**
- * Writes at given position by seeking to it.
- *
- * @param $seekPosition Seek position in file
- * @param $dataStream Data to be written
- * @return mixed Number of writes bytes or false on error
- * @throws OutOfBoundsException If the position is not seekable
- * @throws InvalidArgumentException If a parameter is not valid
- */
- public function writeAtPosition (int $seekPosition, string $dataStream) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream));
- if ($seekPosition < 0) {
- // Invalid seek position
- throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition));
- } elseif (empty($dataStream)) {
- // Empty dataStream
- throw new InvalidArgumentException('Parameter "dataStream" is empty');
- }
-
- // Call iterated object's method
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: Calling this->binaryFileInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
- $status = $this->getBinaryFileInstance()->writeAtPosition($seekPosition, $dataStream);
-
- // Return status
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: status[%s]=%d - EXIT!', gettype($status), $status));
- return $status;
- }
-
- /**
- * Getter for seek position
- *
- * @return $seekPosition Current seek position (stored here in object)
- */
- public function getSeekPosition () {
- // Call file instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $seekPosition = $this->getBinaryFileInstance()->getSeekPosition();
-
- // Return position
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition[%s]=%d - EXIT!', gettype($seekPosition), $seekPosition));
- return $seekPosition;
- }
-
- /**
- * Writes given value to the file and returns a hash and gap position for it
- *
- * @param $stackName Group identifier
- * @param $value Value to be added to the stack
- * @return $data Hash and gap position
- * @throws InvalidArgumentException If a parameter is not valid
- */
- public function writeValueToFile (string $stackName, $value) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,value[]=%s - CALLED!', $stackName, gettype($value)));
- if (empty($stackName)) {
- // Throw IAE
- throw new InvalidArgumentException('Parameter "stackName" is empty');
- } elseif (is_resource($value) || is_object($value)) {
- // Resources and objects are nothing for file-based indexes (mostly)
- throw new InvalidArgumentException(sprintf('value[]=%s is not supported by file-based indexes', gettype($value)));
- }
-
- // Call file instance
- $data = $this->getBinaryFileInstance()->writeValueToFile($stackName, $value);
-
- // Return data
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
- return $data;
- }
-
- /**
- * Writes given raw data to the file and returns a gap position and length
- *
- * @param $stackName Group identifier
- * @param $hash Hash from encoded value
- * @param $encoded Encoded value to be written to the file
- * @return $data Gap position and length of the raw data
- */
- public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,hash=%s,encoded(%d)=%s - CALLED!', $stackName, $hash, strlen($encoded), $encoded));
-
- // Call file instance
- $data = $this->getBinaryFileInstance()->writeDataToFreeGap($stackName, $hash, $encoded);
-
- // Return data
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
- return $data;
- }
-
- /**
- * Searches for next suitable gap the given length of data can fit in
- * including padding bytes.
- *
- * @param $length Length of raw data
- * @return $seekPosition Found next gap's seek position
- * @throws InvalidArgumentException If a parameter is invalid
- */
- public function searchNextGap (int $length) {
- // Validate parameter
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: length=%d - CALLED!', $length));
- if ($length <= 0) {
- // Throw IAE
- throw new InvalidArgumentException(sprintf('length=%d is not valid', $length));
- }
-
- // Call file instance
- $seekPosition = $this->getBinaryFileInstance()->searchNextGap($length);
-
- // Return position
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition[%s]=%d - EXIT!', gettype($seekPosition), $seekPosition));
- return $seekPosition;
- }
-
- /**
- * Checks whether the abstracted file only contains gaps by counting all
- * gaps' bytes together and compare it to total length.
- *
- * @return $isGapsOnly Whether the abstracted file only contains gaps
- */
- public function isFileGapsOnly () {
- // Call file instance
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
- $isGapsOnly = $this->getBinaryFileInstance()->isFileGapsOnly();
-
- // Return position
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: isGapsOnly=%d - EXIT!', $isGapsOnly));
- return $isGapsOnly;
- }
-
}