--- old/test/jdk/java/io/InputStream/Skip.java 2018-10-24 12:46:30.000000000 -0700 +++ new/test/jdk/java/io/InputStream/Skip.java 2018-10-24 12:46:30.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,24 +21,22 @@ * questions. */ +/** + * @test + * @bug 4016710 6516099 + * @summary check for correct implementation of InputStream.skip{NBytes} + */ -/* @test - @bug 4016710 - @summary check for correct implementation of InputStream.skip - */ - -import java.io.*; - - -public class Skip{ +import java.io.EOFException; +import java.io.InputStream; +import java.io.IOException; - private static void dotest(InputStream in , int curpos , - long total , long toskip , long expected) - throws Exception - { +public class Skip { + private static final int EOF = -1; + private static void dotest(InputStream in, int curpos, long total, + long toskip, long expected) throws Exception { try { - System.err.println("\n\nCurrently at pos = " + curpos + "\nTotal bytes in the Stream = " + total + "\nNumber of bytes to skip = " + toskip + @@ -50,20 +48,49 @@ System.err.println("actual number skipped: "+ skipped); if ((skipped < 0) || (skipped > expected)) { - throw new RuntimeException("Unexpected number of bytes skipped"); + throw new RuntimeException("Unexpected byte count skipped"); } - } catch (IOException e) { - System.err.println("IOException is thrown - possible result"); + System.err.println("IOException is thrown: " + e); } catch (Throwable e) { - throw new RuntimeException("Unexpected "+e+" is thrown!"); + throw new RuntimeException("Unexpected " + e + " is thrown!"); } + } + + private static void dotestExact(MyInputStream in, int curpos, long total, + long toskip) throws Exception { + try { + System.err.println("\n\nCurrently at pos = " + curpos + + "\nTotal bytes in the Stream = " + total + + "\nNumber of bytes to skip = " + toskip); + + try { + long pos = in.position(); + assert pos == curpos : pos + " != " + curpos; + in.skipNBytes(toskip); + if (in.position() != pos + (toskip < 0 ? 0 : toskip)) { + throw new RuntimeException((in.position() - pos) + + " bytes skipped; expected " + toskip); + } + } catch (EOFException eofe) { + if (!(toskip > 0 && + (curpos == EOF || (curpos + toskip > total)))) { + throw new RuntimeException("Unexpected EOFException", eofe); + } + System.err.println("Caught expected EOFException"); + + return; + } + } catch (IOException e) { + System.err.println("IOException is thrown: " + e); + } catch (Throwable e) { + throw new RuntimeException("Unexpected " + e + " is thrown!"); + } } public static void main( String argv[] ) throws Exception { - - MyInputStream in = new MyInputStream(11); + MyInputStream in = new MyInputStream(false, 11); /* test for negative skip */ dotest(in, 0, 11, -23, 0); @@ -72,19 +99,20 @@ dotest(in, 0, 11, 20, 11); /* check for skip after EOF */ - dotest(in, -1, 11, 20, 0); + dotest(in, EOF, 11, 20, 0); + + in = new MyInputStream(false, 9000); - in = new MyInputStream(9000); /* check for skip equal to the read chunk size in InputStream.java */ dotest(in, 0, 9000, 2048, 2048); - /* check for skip greater than the read chunk size in InputStream.java */ + /* check for skip larger than the read chunk size in InputStream.java */ dotest(in, 2048, 9000, 5000, 5000); /* check for skip beyond EOF starting from before EOF */ dotest(in, 7048, 9000, 5000, 1952); - in = new MyInputStream(5000); + in = new MyInputStream(false, 5000); /* check for multiple chunk reads */ dotest(in, 0, 5000, 6000, 5000); @@ -98,23 +126,46 @@ * dotest(in, 0, total, toskip, toskip); */ - } + /* tests for skipping an exact number of bytes */ + + final int length = 16; + in = new MyInputStream(true, length); + + /* test for negative skip */ + dotestExact(in, 0, length, -23); + /* test for zero skip */ + dotestExact(in, 0, length, 0); + + /* test for skip before EOF in first half of stream */ + dotestExact(in, 0, length, length/2); + + /* test for skip before EOF in second half of stream */ + dotestExact(in, length/2, length, length/4); + + /* check for skip beyond EOF starting from before EOF */ + dotestExact(in, 3*length/4, length, length/2); + + /* check for skip from / after EOF */ + dotestExact(in, EOF, 11, 1); + } } class MyInputStream extends InputStream { + private static final int EOF = -1; - private int readctr = 0; - private long endoffile; + private final boolean hasBadSkip; + private final long endoffile; + private long readctr = 0; - public MyInputStream(long endoffile) { + public MyInputStream(boolean hasBadSkip, long endoffile) { + this.hasBadSkip = hasBadSkip; this.endoffile = endoffile; } public int read() { - if (readctr == endoffile) { - return -1; + return EOF; } else { readctr++; @@ -123,4 +174,19 @@ } public int available() { return 0; } + + public long position() { return readctr == endoffile ? EOF : readctr; } + + public long skip(long n) throws IOException { + if (hasBadSkip && n > 0 && + readctr > endoffile / 2 && readctr != endoffile) { + long ns = n / 2; + System.out.format("Bad skip(%d): position %d, skipped %d%n", + n, readctr, ns); + n = ns; + } + + // InputStream skip implementation. + return super.skip(n); + } }