1/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8010837 8011136
27 * @summary Test if available returns correct value when skipping beyond
28 *          the end of a file.
29 * @author Dan Xu
30 */
31
32import java.io.BufferedWriter;
33import java.io.File;
34import java.io.FileInputStream;
35import java.io.IOException;
36import java.nio.charset.Charset;
37import java.nio.file.Files;
38import java.nio.file.Path;
39
40public class NegativeAvailable {
41
42    public static void main(String[] args) throws IOException {
43        final int SIZE = 10;
44        final int SKIP = 5;
45        final int NEGATIVE_SKIP = -5;
46
47        // Create a temporary file with size of 10 bytes.
48        Path tmp = Files.createTempFile(null, null);
49        try (BufferedWriter writer =
50            Files.newBufferedWriter(tmp, Charset.defaultCharset())) {
51            for (int i = 0; i < SIZE; i++) {
52                writer.write('1');
53            }
54        }
55
56        File tempFile = tmp.toFile();
57        try (FileInputStream fis = new FileInputStream(tempFile)) {
58            if (tempFile.length() != SIZE) {
59                throw new RuntimeException("unexpected file size = "
60                                           + tempFile.length());
61            }
62            long space = skipBytes(fis, SKIP, SIZE);
63            space = skipBytes(fis, NEGATIVE_SKIP, space);
64            space = skipBytes(fis, SKIP, space);
65            space = skipBytes(fis, SKIP, space);
66            space = skipBytes(fis, SKIP, space);
67            space = skipBytes(fis, NEGATIVE_SKIP, space);
68            space = skipBytes(fis, NEGATIVE_SKIP, space);
69        }
70        Files.deleteIfExists(tmp);
71    }
72
73    /**
74     *  Skip toSkip number of bytes and return the remaining bytes of the file.
75     */
76    private static long skipBytes(FileInputStream fis, int toSkip, long space)
77            throws IOException {
78        long skip = fis.skip(toSkip);
79        if (skip != toSkip) {
80            throw new RuntimeException("skip() returns " + skip
81                                       + " but expected " + toSkip);
82        }
83        long newSpace = space - toSkip;
84        long remaining = newSpace > 0 ? newSpace : 0;
85        int avail = fis.available();
86        if (avail != remaining) {
87            throw new RuntimeException("available() returns " + avail
88                                       + " but expected " + remaining);
89        }
90
91        System.out.println("Skipped " + skip + " bytes "
92                           + " available() returns " + avail);
93        return newSpace;
94    }
95}
96