OSDN Git Service

Add new source files
[armadillo/armadillo1.git] / src / jp / sfjp / armadillo / io / RewindableInputStream.java
1 package jp.sfjp.armadillo.io;
2
3 import java.io.*;
4
5 public final class RewindableInputStream extends PushbackInputStream {
6
7     private byte[] buffer;
8     private int limit;
9
10     public RewindableInputStream(InputStream is, int size) {
11         super(is, size);
12         this.buffer = new byte[size];
13         this.limit = 0;
14     }
15
16     public int rewind(int length) throws IOException {
17         if (limit < length)
18             throw new IOException("length=" + length + ", but limit=" + limit);
19         int offset = limit - length;
20         unread(buffer, offset, length);
21         limit = offset;
22         return length;
23     }
24
25     private void add(byte[] bytes, int offset, int length) {
26         if (length > buffer.length) {
27             limit = length;
28             buffer = new byte[length];
29             System.arraycopy(bytes, 0, buffer, 0, length);
30         }
31         else {
32             int rest = limit + length - buffer.length;
33             if (rest > 0) {
34                 limit -= rest;
35                 System.arraycopy(buffer, rest, buffer, 0, limit);
36             }
37             System.arraycopy(bytes, offset, buffer, limit, length);
38             limit += length;
39         }
40     }
41
42     @Override
43     public int read() throws IOException {
44         int read = super.read();
45         if (read != -1)
46             add(new byte[]{(byte)(read & 0xFF)}, 0, 1);
47         return read;
48     }
49
50     @Override
51     public int read(byte[] b, int off, int len) throws IOException {
52         int readLength = super.read(b, off, len);
53         assert readLength != 0 : "Read Zero";
54         if (readLength > 0)
55             add(b, off, readLength);
56         return readLength;
57     }
58
59     @Override
60     public long skip(long n) throws IOException {
61         long skipped = 0;
62         long length = n;
63         if (length >= buffer.length) {
64             if (length > buffer.length) {
65                 length -= buffer.length;
66                 skipped += super.skip(length);
67             }
68             length = buffer.length;
69         }
70         assert length <= Integer.MAX_VALUE;
71         int rest = (int)length;
72         skipped += read(new byte[rest]);
73         return skipped;
74     }
75
76     @Override
77     public int available() throws IOException {
78         return buffer.length;
79     }
80
81 }