2689 |
02 Oct 06 |
nicklas |
1 |
/** |
2689 |
02 Oct 06 |
nicklas |
$Id$ |
2689 |
02 Oct 06 |
nicklas |
3 |
|
3675 |
16 Aug 07 |
jari |
Copyright (C) 2006, 2007 Nicklas Nordborg |
2689 |
02 Oct 06 |
nicklas |
5 |
|
2689 |
02 Oct 06 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
2689 |
02 Oct 06 |
nicklas |
Available at http://base.thep.lu.se/ |
2689 |
02 Oct 06 |
nicklas |
8 |
|
2689 |
02 Oct 06 |
nicklas |
BASE is free software; you can redistribute it and/or |
2689 |
02 Oct 06 |
nicklas |
modify it under the terms of the GNU General Public License |
4479 |
05 Sep 08 |
jari |
as published by the Free Software Foundation; either version 3 |
2689 |
02 Oct 06 |
nicklas |
of the License, or (at your option) any later version. |
2689 |
02 Oct 06 |
nicklas |
13 |
|
2689 |
02 Oct 06 |
nicklas |
BASE is distributed in the hope that it will be useful, |
2689 |
02 Oct 06 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
2689 |
02 Oct 06 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2689 |
02 Oct 06 |
nicklas |
GNU General Public License for more details. |
2689 |
02 Oct 06 |
nicklas |
18 |
|
2689 |
02 Oct 06 |
nicklas |
You should have received a copy of the GNU General Public License |
4515 |
11 Sep 08 |
jari |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
2689 |
02 Oct 06 |
nicklas |
21 |
*/ |
2689 |
02 Oct 06 |
nicklas |
22 |
package net.sf.basedb.util; |
2689 |
02 Oct 06 |
nicklas |
23 |
|
2689 |
02 Oct 06 |
nicklas |
24 |
import java.io.IOException; |
2689 |
02 Oct 06 |
nicklas |
25 |
import java.io.InputStream; |
2689 |
02 Oct 06 |
nicklas |
26 |
import java.io.OutputStream; |
2689 |
02 Oct 06 |
nicklas |
27 |
|
2689 |
02 Oct 06 |
nicklas |
28 |
/** |
2689 |
02 Oct 06 |
nicklas |
This class can be used to split an input stream into one or more |
2689 |
02 Oct 06 |
nicklas |
additional output streams. When data is read from this input stream |
2689 |
02 Oct 06 |
nicklas |
the bytes are also written to the specified output streams with one of the |
2689 |
02 Oct 06 |
nicklas |
{@link java.io.OutputStream#write(int)} or |
2689 |
02 Oct 06 |
nicklas |
{@link java.io.OutputStream#write(byte[], int, int)} methods. |
2689 |
02 Oct 06 |
nicklas |
34 |
|
2689 |
02 Oct 06 |
nicklas |
@author nicklas |
2689 |
02 Oct 06 |
nicklas |
@version 2.0 |
2689 |
02 Oct 06 |
nicklas |
@base.modified $Date$ |
2689 |
02 Oct 06 |
nicklas |
38 |
*/ |
2689 |
02 Oct 06 |
nicklas |
39 |
public class InputStreamSplitter |
2689 |
02 Oct 06 |
nicklas |
40 |
extends InputStream |
2689 |
02 Oct 06 |
nicklas |
41 |
{ |
2689 |
02 Oct 06 |
nicklas |
42 |
|
3606 |
27 Jul 07 |
nicklas |
43 |
private int numRead; |
3606 |
27 Jul 07 |
nicklas |
44 |
|
2689 |
02 Oct 06 |
nicklas |
45 |
/** |
2689 |
02 Oct 06 |
nicklas |
The source input stream to read from. |
2689 |
02 Oct 06 |
nicklas |
47 |
*/ |
2689 |
02 Oct 06 |
nicklas |
48 |
private final InputStream in; |
2689 |
02 Oct 06 |
nicklas |
49 |
|
2689 |
02 Oct 06 |
nicklas |
50 |
/** |
2689 |
02 Oct 06 |
nicklas |
Streams to copy the data to. |
2689 |
02 Oct 06 |
nicklas |
52 |
*/ |
2689 |
02 Oct 06 |
nicklas |
53 |
private final OutputStream[] copyTo; |
2689 |
02 Oct 06 |
nicklas |
54 |
|
2689 |
02 Oct 06 |
nicklas |
55 |
/** |
3606 |
27 Jul 07 |
nicklas |
If the {@link #skip(long)} method should copy |
3606 |
27 Jul 07 |
nicklas |
to the output streams or no. |
2689 |
02 Oct 06 |
nicklas |
58 |
*/ |
3606 |
27 Jul 07 |
nicklas |
59 |
private final boolean copySkipped; |
2689 |
02 Oct 06 |
nicklas |
60 |
|
2689 |
02 Oct 06 |
nicklas |
61 |
/** |
3606 |
27 Jul 07 |
nicklas |
If the remainder of the input stream should be copied |
3606 |
27 Jul 07 |
nicklas |
if it is closed before the end. |
3606 |
27 Jul 07 |
nicklas |
64 |
*/ |
3606 |
27 Jul 07 |
nicklas |
65 |
private final boolean readToEnd; |
3606 |
27 Jul 07 |
nicklas |
66 |
|
3606 |
27 Jul 07 |
nicklas |
67 |
/** |
3606 |
27 Jul 07 |
nicklas |
Create a new input stream splitter. Skipped bytes are not copied |
3606 |
27 Jul 07 |
nicklas |
and the remainder of the stream is not copied if closed. |
2689 |
02 Oct 06 |
nicklas |
@param in The input stream to read from |
2689 |
02 Oct 06 |
nicklas |
@param copyTo The output streams to copy data to |
2689 |
02 Oct 06 |
nicklas |
72 |
*/ |
2689 |
02 Oct 06 |
nicklas |
73 |
public InputStreamSplitter(InputStream in, OutputStream... copyTo) |
2689 |
02 Oct 06 |
nicklas |
74 |
{ |
3606 |
27 Jul 07 |
nicklas |
75 |
this(in, false, false, copyTo); |
3606 |
27 Jul 07 |
nicklas |
76 |
} |
3606 |
27 Jul 07 |
nicklas |
77 |
|
3606 |
27 Jul 07 |
nicklas |
78 |
/** |
3606 |
27 Jul 07 |
nicklas |
Create a new input stream splitter. Skipped bytes are not copied |
3606 |
27 Jul 07 |
nicklas |
and the remainder of the stream is not copied if closed. |
4034 |
05 Dec 07 |
martin |
@param in The input stream to read from. Null is not allowed |
4034 |
05 Dec 07 |
martin |
@param copySkipped TRUE if skipped bytes should be copied, FALSE otherwise |
4034 |
05 Dec 07 |
martin |
@param readToEnd If the remainder of the input stream should be copied |
4034 |
05 Dec 07 |
martin |
if it is closed before the end |
4034 |
05 Dec 07 |
martin |
@param copyTo The output streams to copy data to. Null is not allowed |
3606 |
27 Jul 07 |
nicklas |
@since 2.4 |
3606 |
27 Jul 07 |
nicklas |
87 |
*/ |
3606 |
27 Jul 07 |
nicklas |
88 |
public InputStreamSplitter(InputStream in, boolean copySkipped, boolean readToEnd, OutputStream... copyTo) |
3606 |
27 Jul 07 |
nicklas |
89 |
{ |
2689 |
02 Oct 06 |
nicklas |
90 |
if (in == null) throw new NullPointerException("in"); |
2689 |
02 Oct 06 |
nicklas |
91 |
if (copyTo == null) throw new NullPointerException("copyTo"); |
2689 |
02 Oct 06 |
nicklas |
92 |
this.in = in; |
2689 |
02 Oct 06 |
nicklas |
93 |
this.copyTo = copyTo; |
3606 |
27 Jul 07 |
nicklas |
94 |
this.copySkipped = copySkipped; |
3606 |
27 Jul 07 |
nicklas |
95 |
this.readToEnd = readToEnd; |
2689 |
02 Oct 06 |
nicklas |
96 |
} |
3606 |
27 Jul 07 |
nicklas |
97 |
|
2689 |
02 Oct 06 |
nicklas |
98 |
/* |
2689 |
02 Oct 06 |
nicklas |
From the InputStream class |
2689 |
02 Oct 06 |
nicklas |
100 |
------------------------------------------- |
2689 |
02 Oct 06 |
nicklas |
101 |
*/ |
2689 |
02 Oct 06 |
nicklas |
102 |
@Override |
2689 |
02 Oct 06 |
nicklas |
103 |
public int available() |
2689 |
02 Oct 06 |
nicklas |
104 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
105 |
{ |
2689 |
02 Oct 06 |
nicklas |
106 |
return in.available(); |
2689 |
02 Oct 06 |
nicklas |
107 |
} |
2689 |
02 Oct 06 |
nicklas |
108 |
@Override |
2689 |
02 Oct 06 |
nicklas |
109 |
public void close() |
2689 |
02 Oct 06 |
nicklas |
110 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
111 |
{ |
3606 |
27 Jul 07 |
nicklas |
112 |
if (readToEnd) |
3606 |
27 Jul 07 |
nicklas |
113 |
{ |
3606 |
27 Jul 07 |
nicklas |
114 |
FileUtil.read(this); |
3606 |
27 Jul 07 |
nicklas |
115 |
} |
2689 |
02 Oct 06 |
nicklas |
116 |
in.close(); |
3606 |
27 Jul 07 |
nicklas |
117 |
for (OutputStream out : copyTo) |
3606 |
27 Jul 07 |
nicklas |
118 |
{ |
3606 |
27 Jul 07 |
nicklas |
119 |
out.flush(); |
3606 |
27 Jul 07 |
nicklas |
120 |
} |
2689 |
02 Oct 06 |
nicklas |
121 |
} |
2689 |
02 Oct 06 |
nicklas |
122 |
@Override |
2689 |
02 Oct 06 |
nicklas |
123 |
public synchronized void mark(int readlimit) |
3606 |
27 Jul 07 |
nicklas |
124 |
{} |
2689 |
02 Oct 06 |
nicklas |
125 |
@Override |
2689 |
02 Oct 06 |
nicklas |
126 |
public boolean markSupported() |
2689 |
02 Oct 06 |
nicklas |
127 |
{ |
3606 |
27 Jul 07 |
nicklas |
128 |
return false; |
2689 |
02 Oct 06 |
nicklas |
129 |
} |
3606 |
27 Jul 07 |
nicklas |
130 |
@Override |
2689 |
02 Oct 06 |
nicklas |
131 |
public int read() |
2689 |
02 Oct 06 |
nicklas |
132 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
133 |
{ |
2689 |
02 Oct 06 |
nicklas |
134 |
int result = in.read(); |
3606 |
27 Jul 07 |
nicklas |
135 |
if (result >= 0) |
3606 |
27 Jul 07 |
nicklas |
136 |
{ |
3606 |
27 Jul 07 |
nicklas |
137 |
++numRead; |
3606 |
27 Jul 07 |
nicklas |
138 |
copy(result); |
3606 |
27 Jul 07 |
nicklas |
139 |
} |
2689 |
02 Oct 06 |
nicklas |
140 |
return result; |
2689 |
02 Oct 06 |
nicklas |
141 |
} |
2689 |
02 Oct 06 |
nicklas |
142 |
@Override |
2689 |
02 Oct 06 |
nicklas |
143 |
public int read(byte[] b, int off, int len) |
2689 |
02 Oct 06 |
nicklas |
144 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
145 |
{ |
2689 |
02 Oct 06 |
nicklas |
146 |
int result = in.read(b, off, len); |
3606 |
27 Jul 07 |
nicklas |
147 |
if (result > 0) |
3606 |
27 Jul 07 |
nicklas |
148 |
{ |
3606 |
27 Jul 07 |
nicklas |
149 |
numRead += result; |
3606 |
27 Jul 07 |
nicklas |
150 |
copy(b, off, result); |
3606 |
27 Jul 07 |
nicklas |
151 |
} |
2689 |
02 Oct 06 |
nicklas |
152 |
return result; |
2689 |
02 Oct 06 |
nicklas |
153 |
} |
2689 |
02 Oct 06 |
nicklas |
154 |
@Override |
2689 |
02 Oct 06 |
nicklas |
155 |
public int read(byte[] b) |
2689 |
02 Oct 06 |
nicklas |
156 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
157 |
{ |
2689 |
02 Oct 06 |
nicklas |
158 |
return read(b, 0, b.length); |
2689 |
02 Oct 06 |
nicklas |
159 |
} |
2689 |
02 Oct 06 |
nicklas |
160 |
@Override |
2689 |
02 Oct 06 |
nicklas |
161 |
public synchronized void reset() |
2689 |
02 Oct 06 |
nicklas |
162 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
163 |
{ |
3606 |
27 Jul 07 |
nicklas |
164 |
throw new IOException("reset/mark is not supported"); |
2689 |
02 Oct 06 |
nicklas |
165 |
} |
2689 |
02 Oct 06 |
nicklas |
166 |
@Override |
2689 |
02 Oct 06 |
nicklas |
167 |
public long skip(long n) |
2689 |
02 Oct 06 |
nicklas |
168 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
169 |
{ |
3606 |
27 Jul 07 |
nicklas |
170 |
long result = 0; |
3606 |
27 Jul 07 |
nicklas |
171 |
if (copySkipped) |
3606 |
27 Jul 07 |
nicklas |
172 |
{ |
3606 |
27 Jul 07 |
nicklas |
// This will call the read(byte[], int, int) method |
3606 |
27 Jul 07 |
nicklas |
174 |
result = super.skip(n); |
3606 |
27 Jul 07 |
nicklas |
175 |
} |
3606 |
27 Jul 07 |
nicklas |
176 |
else |
3606 |
27 Jul 07 |
nicklas |
177 |
{ |
5384 |
13 Aug 10 |
nicklas |
178 |
result = in.skip(n); |
3606 |
27 Jul 07 |
nicklas |
179 |
} |
2689 |
02 Oct 06 |
nicklas |
180 |
return result; |
2689 |
02 Oct 06 |
nicklas |
181 |
} |
2689 |
02 Oct 06 |
nicklas |
182 |
// ------------------------------------------- |
2689 |
02 Oct 06 |
nicklas |
183 |
|
2689 |
02 Oct 06 |
nicklas |
184 |
/** |
3606 |
27 Jul 07 |
nicklas |
Get the number of bytes that has been read or skipped |
3606 |
27 Jul 07 |
nicklas |
from the input stream. |
3606 |
27 Jul 07 |
nicklas |
@since 2.4 |
3606 |
27 Jul 07 |
nicklas |
188 |
*/ |
3606 |
27 Jul 07 |
nicklas |
189 |
public long getNumRead() |
3606 |
27 Jul 07 |
nicklas |
190 |
{ |
3606 |
27 Jul 07 |
nicklas |
191 |
return numRead; |
3606 |
27 Jul 07 |
nicklas |
192 |
} |
3606 |
27 Jul 07 |
nicklas |
193 |
|
3606 |
27 Jul 07 |
nicklas |
194 |
/** |
2689 |
02 Oct 06 |
nicklas |
Write data to all output streams. |
2689 |
02 Oct 06 |
nicklas |
196 |
*/ |
2689 |
02 Oct 06 |
nicklas |
197 |
private void copy(int b) |
2689 |
02 Oct 06 |
nicklas |
198 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
199 |
{ |
2689 |
02 Oct 06 |
nicklas |
200 |
for (OutputStream out : copyTo) |
2689 |
02 Oct 06 |
nicklas |
201 |
{ |
2689 |
02 Oct 06 |
nicklas |
202 |
out.write(b); |
2689 |
02 Oct 06 |
nicklas |
203 |
} |
2689 |
02 Oct 06 |
nicklas |
204 |
} |
2689 |
02 Oct 06 |
nicklas |
205 |
|
2689 |
02 Oct 06 |
nicklas |
206 |
/** |
2689 |
02 Oct 06 |
nicklas |
Write data to all output streams. |
2689 |
02 Oct 06 |
nicklas |
208 |
*/ |
2689 |
02 Oct 06 |
nicklas |
209 |
private void copy(byte[] b, int off, int len) |
2689 |
02 Oct 06 |
nicklas |
210 |
throws IOException |
2689 |
02 Oct 06 |
nicklas |
211 |
{ |
2689 |
02 Oct 06 |
nicklas |
212 |
for (OutputStream out : copyTo) |
2689 |
02 Oct 06 |
nicklas |
213 |
{ |
2689 |
02 Oct 06 |
nicklas |
214 |
out.write(b, off, len); |
2689 |
02 Oct 06 |
nicklas |
215 |
} |
2689 |
02 Oct 06 |
nicklas |
216 |
} |
2689 |
02 Oct 06 |
nicklas |
217 |
|
2689 |
02 Oct 06 |
nicklas |
218 |
} |