source: josm/trunk/src/org/tukaani/xz/SimpleInputStream.java@ 14039

Last change on this file since 14039 was 13350, checked in by stoecker, 7 years ago

see #15816 - add XZ support

File size: 4.1 KB
Line 
1/*
2 * SimpleInputStream
3 *
4 * Author: Lasse Collin <lasse.collin@tukaani.org>
5 *
6 * This file has been put into the public domain.
7 * You can do whatever you want with this file.
8 */
9
10package org.tukaani.xz;
11
12import java.io.InputStream;
13import java.io.IOException;
14import org.tukaani.xz.simple.SimpleFilter;
15
16class SimpleInputStream extends InputStream {
17 private static final int FILTER_BUF_SIZE = 4096;
18
19 private InputStream in;
20 private final SimpleFilter simpleFilter;
21
22 private final byte[] filterBuf = new byte[FILTER_BUF_SIZE];
23 private int pos = 0;
24 private int filtered = 0;
25 private int unfiltered = 0;
26
27 private boolean endReached = false;
28 private IOException exception = null;
29
30 private final byte[] tempBuf = new byte[1];
31
32 static int getMemoryUsage() {
33 return 1 + FILTER_BUF_SIZE / 1024;
34 }
35
36 SimpleInputStream(InputStream in, SimpleFilter simpleFilter) {
37 // Check for null because otherwise null isn't detect
38 // in this constructor.
39 if (in == null)
40 throw new NullPointerException();
41
42 // The simpleFilter argument comes from this package
43 // so it is known to be non-null already.
44 assert simpleFilter != null;
45
46 this.in = in;
47 this.simpleFilter = simpleFilter;
48 }
49
50 public int read() throws IOException {
51 return read(tempBuf, 0, 1) == -1 ? -1 : (tempBuf[0] & 0xFF);
52 }
53
54 public int read(byte[] buf, int off, int len) throws IOException {
55 if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
56 throw new IndexOutOfBoundsException();
57
58 if (len == 0)
59 return 0;
60
61 if (in == null)
62 throw new XZIOException("Stream closed");
63
64 if (exception != null)
65 throw exception;
66
67 try {
68 int size = 0;
69
70 while (true) {
71 // Copy filtered data into the caller-provided buffer.
72 int copySize = Math.min(filtered, len);
73 System.arraycopy(filterBuf, pos, buf, off, copySize);
74 pos += copySize;
75 filtered -= copySize;
76 off += copySize;
77 len -= copySize;
78 size += copySize;
79
80 // If end of filterBuf was reached, move the pending data to
81 // the beginning of the buffer so that more data can be
82 // copied into filterBuf on the next loop iteration.
83 if (pos + filtered + unfiltered == FILTER_BUF_SIZE) {
84 System.arraycopy(filterBuf, pos, filterBuf, 0,
85 filtered + unfiltered);
86 pos = 0;
87 }
88
89 if (len == 0 || endReached)
90 return size > 0 ? size : -1;
91
92 assert filtered == 0;
93
94 // Get more data into the temporary buffer.
95 int inSize = FILTER_BUF_SIZE - (pos + filtered + unfiltered);
96 inSize = in.read(filterBuf, pos + filtered + unfiltered,
97 inSize);
98
99 if (inSize == -1) {
100 // Mark the remaining unfiltered bytes to be ready
101 // to be copied out.
102 endReached = true;
103 filtered = unfiltered;
104 unfiltered = 0;
105 } else {
106 // Filter the data in filterBuf.
107 unfiltered += inSize;
108 filtered = simpleFilter.code(filterBuf, pos, unfiltered);
109 assert filtered <= unfiltered;
110 unfiltered -= filtered;
111 }
112 }
113 } catch (IOException e) {
114 exception = e;
115 throw e;
116 }
117 }
118
119 public int available() throws IOException {
120 if (in == null)
121 throw new XZIOException("Stream closed");
122
123 if (exception != null)
124 throw exception;
125
126 return filtered;
127 }
128
129 public void close() throws IOException {
130 if (in != null) {
131 try {
132 in.close();
133 } finally {
134 in = null;
135 }
136 }
137 }
138}
Note: See TracBrowser for help on using the repository browser.