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