]> git.mxchange.org Git - core.git/blob - framework/main/classes/iterator/file/class_FileIterator.php
Refacuring / possible WIP:
[core.git] / framework / main / classes / iterator / file / class_FileIterator.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Iterator\File;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Filesystem\File\BinaryFile;
7 use Org\Mxchange\CoreFramework\Iterator\BaseIterator;
8 use Org\Mxchange\CoreFramework\Iterator\Filesystem\SeekableWritableFileIterator;
9 use Org\Mxchange\CoreFramework\Traits\File\BinaryFileTrait;
10
11 // Import SPL stuff
12 use \BadMethodCallException;
13 use \InvalidArgumentException;
14 use \OutOfBoundsException;
15
16 /**
17  * A file iterator
18  *
19  * @author              Roland Haeder <webmaster@ship-simu.org>
20  * @version             0.0.0
21  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
22  * @license             GNU GPL 3.0 or any newer version
23  * @link                http://www.ship-simu.org
24  *
25  * This program is free software: you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation, either version 3 of the License, or
28  * (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37  */
38 class FileIterator extends BaseIterator implements SeekableWritableFileIterator {
39         // Load traits
40         use BinaryFileTrait;
41
42         /**
43          * Protected constructor
44          *
45          * @return      void
46          */
47         protected function __construct () {
48                 // Call parent constructor
49                 parent::__construct(__CLASS__);
50         }
51
52         /**
53          * Creates an instance of this class
54          *
55          * @param       $binaryFileInstance     An instance of a BinaryFile class
56          * @return      $iteratorInstance       An instance of a Iterator class
57          */
58         public final static function createFileIterator (BinaryFile $binaryFileInstance) {
59                 // Get new instance
60                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: binaryFileInstance=%s - CALLED!', $binaryFileInstance->__toString()));
61                 $iteratorInstance = new FileIterator();
62
63                 // Set the instance here
64                 $iteratorInstance->setBinaryFileInstance($binaryFileInstance);
65
66                 // Return the prepared instance
67                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: iteratorInstance=%s - EXIT!', $iteratorInstance->__toString()));
68                 return $iteratorInstance;
69         }
70
71         /**
72          * Gets currently read data
73          *
74          * @return      $current        Currently read data
75          * @throws      BadMethodCallException  If valid() is FALSE
76          */
77         public function current () {
78                 // Is condition given?
79                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
80                 if (!$this->valid()) {
81                         // Throw BMCE
82                         throw new BadMethodCallException('Current key cannot be valid, forgot to invoke valid()?');
83                 }
84
85                 // Call file instance
86                 $current = $this->getBinaryFileInstance()->current();
87
88                 // Return it
89                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: current[]=%s - EXIT!', gettype($current)));
90                 return $current;
91         }
92
93         /**
94          * Gets current seek position ("key").
95          *
96          * @return      $key    Current key in iteration
97          * @throws      BadMethodCallException  If valid() is FALSE
98          */
99         public function key () {
100                 // Is condition given?
101                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
102                 if (!$this->valid()) {
103                         // Throw BMCE
104                         throw new BadMethodCallException('Current key cannot be valid, forgot to invoke valid()?');
105                 }
106
107                 // Get key from file instance
108                 $key = $this->getBinaryFileInstance()->determineSeekPosition();
109
110                 // Return key
111                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: key[%s]=%s - EXIT!', gettype($key), $key));
112                 return $key;
113         }
114
115         /**
116          * Advances to next "file" of bytes
117          *
118          * @return      void
119          */
120         public function next () {
121                 // Call file instance
122                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
123                 $this->getBinaryFileInstance()->next();
124
125                 // Trace message
126                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
127         }
128
129         /**
130          * Rewinds to the beginning of the file
131          *
132          * @return      $status         Status of this operation
133          */
134         public function rewind () {
135                 // Call file instance
136                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
137                 $this->getBinaryFileInstance()->rewind();
138
139                 // Trace message
140                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
141         }
142
143         /**
144          * Checks wether the current entry is valid (not at the end of the file).
145          * This method will return true if an emptied (nulled) entry has been found.
146          *
147          * @return      $isValid        Whether the next entry is valid
148          */
149         public function valid () {
150                 // Call file instance
151                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
152                 $isValid = $this->getBinaryFileInstance()->valid();
153
154                 // Return flag
155                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: isValid=%d - EXIT!', intval($isValid)));
156                 return $isValid;
157         }
158
159         /**
160          * Seeks to given position
161          *
162          * @param       $seekPosition   Seek position in file
163          * @param       $whence                 Added to offset (default: only use offset to seek to)
164          * @return      $status                 Status of this operation
165          * @throws      OutOfBoundsException    If the position is not seekable
166          */
167         public function seek (int $seekPosition, int $whence = SEEK_SET) {
168                 // Validate parameter
169                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,whence=%d - CALLED!', $seekPosition, $whence));
170                 if ($seekPosition < 0) {
171                         // Throw IAE
172                         throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition));
173                 }
174
175                 // Call file instance
176                 $status = $this->getBinaryFileInstance()->seek($seekPosition, $whence);
177
178                 // Return status
179                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: status=%d - EXIT!', intval($status)));
180                 return $status;
181         }
182
183         /**
184          * Size of file stack
185          *
186          * @return      $size   Size (in bytes) of file
187          */
188         public function size () {
189                 // Call the file object
190                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
191                 $size = $this->getBinaryFileInstance()->size();
192
193                 // Return size
194                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
195                 return $size;
196         }
197
198         /**
199          * Reads given amount of bytes from file.
200          *
201          * @param       $bytes  Amount of bytes to read
202          * @return      $data   Data read from file
203          * @throws      OutOfBoundsException    If the position is not seekable
204          */
205         public function read (int $bytes = 0) {
206                 // Validate parameter
207                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: bytes=%d - CALLED!', $bytes));
208                 if ($bytes < 0) {
209                         // Throw exception
210                         throw new OutOfBoundsException(sprintf('bytes=%d is not valid', $bytes));
211                 }
212
213                 // Call file instance
214                 $data = $this->getBinaryFileInstance()->read($bytes);
215
216                 // Return data
217                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
218                 return $data;
219         }
220
221         /**
222          * Analyzes entries in index file. This will count all found (and valid)
223          * entries, mark invalid as damaged and count gaps ("fragmentation"). If
224          * only gaps are found, the file is considered as "virgin" (no entries).
225          *
226          * @return      void
227          */
228         public function analyzeFileStructure () {
229                 // Just call the file instance
230                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
231                 $this->getBinaryFileInstance()->analyzeFileStructure();
232
233                 // Trace message
234                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
235         }
236
237         /**
238          * Checks whether the file header is initialized
239          *
240          * @return      $isInitialized  Whether the file header is initialized
241          */
242         public function isFileHeaderInitialized () {
243                 // Just call the file instance
244                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
245                 $isInitialized = $this->getBinaryFileInstance()->isFileHeaderInitialized();
246
247                 // Return flag
248                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: isInitialized=%d - EXIT!', intval($isInitialized)));
249                 return $isInitialized;
250         }
251
252         /**
253          * Creates the assigned file
254          *
255          * @return      void
256          */
257         public function createFileHeader () {
258                 // Just call the file instance
259                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
260                 $this->getBinaryFileInstance()->createFileHeader();
261
262                 // Trace message
263                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
264         }
265
266         /**
267          * Pre-allocates file (if enabled) with some space for later faster write access.
268          *
269          * @param       $type   Type of the file
270          * @return      void
271          * @throws      InvalidArgumentException        If a parameter is not valid
272          */
273         public function preAllocateFile (string $type) {
274                 // Validate parameter
275                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: type=%s - CALLED!', $type));
276                 if (empty($type)) {
277                         // Throw IAE
278                         throw new InvalidArgumentException('Parameter "type" is empty');
279                 }
280
281                 // Just call the file instance
282                 $this->getBinaryFileInstance()->preAllocateFile($type);
283
284                 // Trace message
285                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
286         }
287
288         /**
289          * Initializes counter for valid entries, arrays for damaged entries and
290          * an array for gap seek positions. If you call this method on your own,
291          * please re-analyze the file structure. So you are better to call
292          * analyzeFileStructure() instead of this method.
293          *
294          * @return      void
295          */
296         public function initCountersGapsArray () {
297                 // Call file instance
298                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
299                 $this->getBinaryFileInstance()->initCountersGapsArray();
300
301                 // Trace message
302                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
303         }
304
305         /**
306          * Getter for header size
307          *
308          * @return      $totalEntries   Size of file header
309          */
310         public final function getHeaderSize () {
311                 // Call file instance
312                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
313                 $size = $this->getBinaryFileInstance()->getHeaderSize();
314
315                 // Return size
316                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
317                 return $size;
318         }
319
320         /**
321          * Setter for header size
322          *
323          * @param       $headerSize             Size of file header
324          * @return      void
325          */
326         public final function setHeaderSize (int $headerSize) {
327                 // Call file instance
328                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: headerSize=%d - CALLED!', $headerSize));
329                 $this->getBinaryFileInstance()->setHeaderSize($headerSize);
330
331                 // Trace message
332                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
333         }
334
335         /**
336          * Getter for header array
337          *
338          * @return      $header         Header array
339          */
340         public final function getHeader () {
341                 // Call file instance
342                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
343                 $header = $this->getBinaryFileInstance()->getHeader();
344
345                 // Return it
346                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: header()=%d - EXIT!', count($header)));
347                 return $header;
348         }
349
350         /**
351          * Setter for header
352          *
353          * @param       $header         Array for a file header
354          * @return      void
355          */
356         public final function setHeader (array $header) {
357                 // Call file instance
358                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: header()=%d - CALLED!', count($header)));
359                 $this->getBinaryFileInstance()->setHeader($header);
360
361                 // Trace message
362                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
363         }
364
365         /**
366          * Updates seekPosition attribute from file to avoid to much access on file.
367          *
368          * @return      void
369          */
370         public function updateSeekPosition () {
371                 // Call file instance
372                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
373                 $this->getBinaryFileInstance()->updateSeekPosition();
374
375                 // Trace message
376                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
377         }
378
379         /**
380          * Getter for total entries
381          *
382          * @return      $totalEntries   Total entries in this file
383          */
384         public final function getCounter () {
385                 // Call file instance
386                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
387                 $counter = $this->getBinaryFileInstance()->getCounter();
388
389                 // Return counter
390                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: counter=%d - EXIT!', $counter));
391                 return $counter;
392         }
393
394         /**
395          * "Getter" for file size
396          *
397          * @return      $fileSize       Size of currently loaded file
398          */
399         public function getFileSize () {
400                 // Call file instance
401                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
402                 $size = $this->getBinaryFileInstance()->getFileSize();
403
404                 // Return size
405                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: size=%d - EXIT!', $size));
406                 return $size;
407         }
408
409         /**
410          * Writes data at given position
411          *
412          * @param       $seekPosition   Seek position
413          * @param       $data                   Data to be written
414          * @param       $flushHeader    Whether to flush the header (default: flush)
415          * @return      void
416          * @throws      OutOfBoundsException    If the position is not seekable
417          * @throws      InvalidArgumentException        If a parameter is not valid
418          */
419         public function writeData (int $seekPosition, string $data, bool $flushHeader = true) {
420                 // Validate parameter
421                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,data(%d)=%s,flushHeader=%d - CALLED!', $seekPosition, strlen($data), $data, intval($flushHeader)));
422                 if ($seekPosition < 0) {
423                         // Throw exception
424                         throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid', $seekPosition));
425                 } elseif (empty($data)) {
426                         // Throw IAE
427                         throw new InvalidArgumentException('Parameter "data" is empty');
428                 }
429
430                 // Call file instance
431                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: Calling this->binaryFileInstance->writeData(%d,data()=%d,%d) ...', $seekPosition, strlen($data), intval($flushHeader)));
432                 $this->getBinaryFileInstance()->writeData($seekPosition, $data, $flushHeader);
433
434                 // Trace message
435                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: EXIT!');
436         }
437
438         /**
439          * Writes at given position by seeking to it.
440          *
441          * @param       $seekPosition   Seek position in file
442          * @param       $dataStream             Data to be written
443          * @return      mixed                   Number of writes bytes or false on error
444          * @throws      OutOfBoundsException    If the position is not seekable
445          * @throws      InvalidArgumentException        If a parameter is not valid
446          */
447         public function writeAtPosition (int $seekPosition, string $dataStream) {
448                 // Validate parameter
449                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition=%d,dataStream(%d)=%s - CALLED!', $seekPosition, strlen($dataStream), $dataStream));
450                 if ($seekPosition < 0) {
451                         // Invalid seek position
452                         throw new OutOfBoundsException(sprintf('seekPosition=%d is not valid.', $seekPosition));
453                 } elseif (empty($dataStream)) {
454                         // Empty dataStream
455                         throw new InvalidArgumentException('Parameter "dataStream" is empty');
456                 }
457
458                 // Call iterated object's method
459                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: Calling this->binaryFileInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
460                 $status = $this->getBinaryFileInstance()->writeAtPosition($seekPosition, $dataStream);
461
462                 // Return status
463                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: status[%s]=%d - EXIT!', gettype($status), $status));
464                 return $status;
465         }
466
467         /**
468          * Getter for seek position
469          *
470          * @return      $seekPosition   Current seek position (stored here in object)
471          */
472         public function getSeekPosition () {
473                 // Call file instance
474                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILE-ITERATOR: CALLED!');
475                 $seekPosition = $this->getBinaryFileInstance()->getSeekPosition();
476
477                 // Return position
478                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition[%s]=%d - EXIT!', gettype($seekPosition), $seekPosition));
479                 return $seekPosition;
480         }
481
482         /**
483          * Writes given value to the file and returns a hash and gap position for it
484          *
485          * @param       $stackName      Group identifier
486          * @param       $value          Value to be added to the stack
487          * @return      $data           Hash and gap position
488          * @throws      InvalidArgumentException        If a parameter is not valid
489          */
490         public function writeValueToFile (string $stackName, $value) {
491                 // Validate parameter
492                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,value[]=%s - CALLED!', $stackName, gettype($value)));
493                 if (empty($stackName)) {
494                         // Throw IAE
495                         throw new InvalidArgumentException('Parameter "stackName" is empty');
496                 } elseif (is_resource($value) || is_object($value)) {
497                         // Resources and objects are nothing for file-based indexes (mostly)
498                         throw new InvalidArgumentException(sprintf('value[]=%s is not supported by file-based indexes', gettype($value)));
499                 }
500
501                 // Call file instance
502                 $data = $this->getBinaryFileInstance()->writeValueToFile($stackName, $value);
503
504                 // Return data
505                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
506                 return $data;
507         }
508
509         /**
510          * Writes given raw data to the file and returns a gap position and length
511          *
512          * @param       $stackName      Group identifier
513          * @param       $hash           Hash from encoded value
514          * @param       $encoded        Encoded value to be written to the file
515          * @return      $data           Gap position and length of the raw data
516          */
517         public function writeDataToFreeGap (string $stackName, string $hash, string $encoded) {
518                 // Validate parameter
519                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: stackName=%s,hash=%s,encoded(%d)=%s - CALLED!', $stackName, $hash, strlen($encoded), $encoded));
520
521                 // Call file instance
522                 $data = $this->getBinaryFileInstance()->writeDataToFreeGap($stackName, $hash, $encoded);
523
524                 // Return data
525                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: data[]=%s - EXIT!', gettype($data)));
526                 return $data;
527         }
528
529         /**
530          * Searches for next suitable gap the given length of data can fit in
531          * including padding bytes.
532          *
533          * @param       $length                 Length of raw data
534          * @return      $seekPosition   Found next gap's seek position
535          * @throws      InvalidArgumentException        If a parameter is invalid
536          */
537         public function searchNextGap (int $length) {
538                 // Validate parameter
539                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: length=%d - CALLED!', $length));
540                 if ($length <= 0) {
541                         // Throw IAE
542                         throw new InvalidArgumentException(sprintf('length=%d is not valid', $length));
543                 }
544
545                 // Call file instance
546                 $seekPosition = $this->getBinaryFileInstance()->searchNextGap($length);
547
548                 // Return position
549                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('FILE-ITERATOR: seekPosition[%s]=%d - EXIT!', gettype($seekPosition), $seekPosition));
550                 return $seekPosition;
551         }
552
553 }