24
24
import net .lecousin .framework .io .text .BufferedReadableCharacterStream ;
25
25
import net .lecousin .framework .mutable .Mutable ;
26
26
import net .lecousin .framework .mutable .MutableInteger ;
27
+ import net .lecousin .framework .mutable .MutableLong ;
27
28
import net .lecousin .framework .progress .WorkProgress ;
28
29
import net .lecousin .framework .util .Pair ;
29
30
import net .lecousin .framework .util .RunnableWithParameter ;
@@ -365,7 +366,8 @@ public Integer run() throws IOException {
365
366
/**
366
367
* Implement a synchronous skip using a synchronous read.
367
368
*/
368
- public static long skipSync (IO .Readable io , long n ) throws IOException {
369
+ public static long skipSyncByReading (IO .Readable io , long n ) throws IOException {
370
+ if (n <= 0 ) return 0 ;
369
371
int l = n > 65536 ? 65536 : (int )n ;
370
372
ByteBuffer b = ByteBuffer .allocate (l );
371
373
long total = 0 ;
@@ -384,16 +386,57 @@ public static long skipSync(IO.Readable io, long n) throws IOException {
384
386
* Implement an asynchronous skip using a task calling a synchronous skip.
385
387
* This must be used only if the synchronous skip is using only CPU.
386
388
*/
387
- public static Task <Long ,IOException > skipAsync (IO .Readable io , long n , RunnableWithParameter <Pair <Long ,IOException >> ondone ) {
389
+ public static AsyncWork <Long ,IOException > skipAsyncUsingSync (IO .Readable io , long n , RunnableWithParameter <Pair <Long ,IOException >> ondone ) {
390
+ // TODO this should be skipAsyncUsingSync, then we should implement a real skipAsync
388
391
Task <Long ,IOException > task = new Task .Cpu <Long ,IOException >("Skipping bytes" , io .getPriority (), ondone ) {
389
392
@ Override
390
393
public Long run () throws IOException {
391
- long total = skipSync (io , n );
394
+ long total = skipSyncByReading (io , n );
392
395
return Long .valueOf (total );
393
396
}
394
397
};
395
398
task .start ();
396
- return task ;
399
+ return task .getSynch ();
400
+ }
401
+
402
+ public static AsyncWork <Long , IOException > skipAsyncByReading (IO .Readable io , long n , RunnableWithParameter <Pair <Long ,IOException >> ondone ) {
403
+ if (n <= 0 ) {
404
+ if (ondone != null ) ondone .run (new Pair <>(Long .valueOf (0 ), null ));
405
+ return new AsyncWork <>(Long .valueOf (0 ), null );
406
+ }
407
+ ByteBuffer b = ByteBuffer .allocate (n > 65536 ? 65536 : (int )n );
408
+ MutableLong done = new MutableLong (0 );
409
+ AsyncWork <Long , IOException > result = new AsyncWork <>();
410
+ io .readAsync (b ).listenInline (new AsyncWorkListener <Integer , IOException >() {
411
+ @ Override
412
+ public void ready (Integer nb ) {
413
+ int read = nb .intValue ();
414
+ if (read <= 0 ) {
415
+ if (ondone != null ) ondone .run (new Pair <>(Long .valueOf (done .get ()), null ));
416
+ result .unblockSuccess (Long .valueOf (done .get ()));
417
+ return ;
418
+ }
419
+ done .add (nb .intValue ());
420
+ if (done .get () == n ) {
421
+ if (ondone != null ) ondone .run (new Pair <>(Long .valueOf (n ), null ));
422
+ result .unblockSuccess (Long .valueOf (n ));
423
+ return ;
424
+ }
425
+ b .clear ();
426
+ if (n - done .get () < b .remaining ())
427
+ b .limit ((int )(n - done .get ()));
428
+ io .readAsync (b ).listenInline (this );
429
+ }
430
+ @ Override
431
+ public void error (IOException error ) {
432
+ result .error (error );
433
+ }
434
+ @ Override
435
+ public void cancelled (CancelException event ) {
436
+ result .cancel (event );
437
+ }
438
+ });
439
+ return result ;
397
440
}
398
441
399
442
/**
0 commit comments