1 /* |
1 /* |
2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Sun designates this |
7 * published by the Free Software Foundation. Sun designates this |
31 import java.io.OutputStream; |
31 import java.io.OutputStream; |
32 import java.io.Reader; |
32 import java.io.Reader; |
33 import java.io.Writer; |
33 import java.io.Writer; |
34 import java.io.IOException; |
34 import java.io.IOException; |
35 import java.nio.ByteBuffer; |
35 import java.nio.ByteBuffer; |
36 import java.nio.CharBuffer; |
|
37 import java.nio.BufferOverflowException; |
|
38 import java.nio.BufferUnderflowException; |
|
39 import java.nio.charset.Charset; |
36 import java.nio.charset.Charset; |
40 import java.nio.charset.CharsetDecoder; |
37 import java.nio.charset.CharsetDecoder; |
41 import java.nio.charset.CharsetEncoder; |
38 import java.nio.charset.CharsetEncoder; |
42 import java.nio.charset.CoderResult; |
|
43 import java.nio.charset.UnsupportedCharsetException; |
39 import java.nio.charset.UnsupportedCharsetException; |
44 import java.nio.channels.spi.AbstractInterruptibleChannel; |
40 import java.nio.channels.spi.AbstractInterruptibleChannel; |
|
41 import java.util.concurrent.ExecutionException; |
45 import sun.nio.ch.ChannelInputStream; |
42 import sun.nio.ch.ChannelInputStream; |
46 import sun.nio.cs.StreamDecoder; |
43 import sun.nio.cs.StreamDecoder; |
47 import sun.nio.cs.StreamEncoder; |
44 import sun.nio.cs.StreamEncoder; |
48 |
45 |
49 |
46 |
180 public void close() throws IOException { |
177 public void close() throws IOException { |
181 ch.close(); |
178 ch.close(); |
182 } |
179 } |
183 |
180 |
184 }; |
181 }; |
|
182 } |
|
183 |
|
184 /** |
|
185 * {@note new} |
|
186 * Constructs a stream that reads bytes from the given channel. |
|
187 * |
|
188 * <p> The stream will not be buffered, and it will not support the {@link |
|
189 * InputStream#mark mark} or {@link InputStream#reset reset} methods. The |
|
190 * stream will be safe for access by multiple concurrent threads. Closing |
|
191 * the stream will in turn cause the channel to be closed. </p> |
|
192 * |
|
193 * @param ch |
|
194 * The channel from which bytes will be read |
|
195 * |
|
196 * @return A new input stream |
|
197 * |
|
198 * @since 1.7 |
|
199 */ |
|
200 public static InputStream newInputStream(final AsynchronousByteChannel ch) { |
|
201 checkNotNull(ch, "ch"); |
|
202 return new InputStream() { |
|
203 |
|
204 private ByteBuffer bb = null; |
|
205 private byte[] bs = null; // Invoker's previous array |
|
206 private byte[] b1 = null; |
|
207 |
|
208 @Override |
|
209 public synchronized int read() throws IOException { |
|
210 if (b1 == null) |
|
211 b1 = new byte[1]; |
|
212 int n = this.read(b1); |
|
213 if (n == 1) |
|
214 return b1[0] & 0xff; |
|
215 return -1; |
|
216 } |
|
217 |
|
218 @Override |
|
219 public synchronized int read(byte[] bs, int off, int len) |
|
220 throws IOException |
|
221 { |
|
222 if ((off < 0) || (off > bs.length) || (len < 0) || |
|
223 ((off + len) > bs.length) || ((off + len) < 0)) { |
|
224 throw new IndexOutOfBoundsException(); |
|
225 } else if (len == 0) |
|
226 return 0; |
|
227 |
|
228 ByteBuffer bb = ((this.bs == bs) |
|
229 ? this.bb |
|
230 : ByteBuffer.wrap(bs)); |
|
231 bb.position(off); |
|
232 bb.limit(Math.min(off + len, bb.capacity())); |
|
233 this.bb = bb; |
|
234 this.bs = bs; |
|
235 |
|
236 boolean interrupted = false; |
|
237 try { |
|
238 for (;;) { |
|
239 try { |
|
240 return ch.read(bb).get(); |
|
241 } catch (ExecutionException ee) { |
|
242 throw new IOException(ee.getCause()); |
|
243 } catch (InterruptedException ie) { |
|
244 interrupted = true; |
|
245 } |
|
246 } |
|
247 } finally { |
|
248 if (interrupted) |
|
249 Thread.currentThread().interrupt(); |
|
250 } |
|
251 } |
|
252 |
|
253 @Override |
|
254 public void close() throws IOException { |
|
255 ch.close(); |
|
256 } |
|
257 }; |
|
258 } |
|
259 |
|
260 /** |
|
261 * {@note new} |
|
262 * Constructs a stream that writes bytes to the given channel. |
|
263 * |
|
264 * <p> The stream will not be buffered. The stream will be safe for access |
|
265 * by multiple concurrent threads. Closing the stream will in turn cause |
|
266 * the channel to be closed. </p> |
|
267 * |
|
268 * @param ch |
|
269 * The channel to which bytes will be written |
|
270 * |
|
271 * @return A new output stream |
|
272 * |
|
273 * @since 1.7 |
|
274 */ |
|
275 public static OutputStream newOutputStream(final AsynchronousByteChannel ch) { |
|
276 checkNotNull(ch, "ch"); |
|
277 return new OutputStream() { |
|
278 |
|
279 private ByteBuffer bb = null; |
|
280 private byte[] bs = null; // Invoker's previous array |
|
281 private byte[] b1 = null; |
|
282 |
|
283 @Override |
|
284 public synchronized void write(int b) throws IOException { |
|
285 if (b1 == null) |
|
286 b1 = new byte[1]; |
|
287 b1[0] = (byte)b; |
|
288 this.write(b1); |
|
289 } |
|
290 |
|
291 @Override |
|
292 public synchronized void write(byte[] bs, int off, int len) |
|
293 throws IOException |
|
294 { |
|
295 if ((off < 0) || (off > bs.length) || (len < 0) || |
|
296 ((off + len) > bs.length) || ((off + len) < 0)) { |
|
297 throw new IndexOutOfBoundsException(); |
|
298 } else if (len == 0) { |
|
299 return; |
|
300 } |
|
301 ByteBuffer bb = ((this.bs == bs) |
|
302 ? this.bb |
|
303 : ByteBuffer.wrap(bs)); |
|
304 bb.limit(Math.min(off + len, bb.capacity())); |
|
305 bb.position(off); |
|
306 this.bb = bb; |
|
307 this.bs = bs; |
|
308 |
|
309 boolean interrupted = false; |
|
310 try { |
|
311 while (bb.remaining() > 0) { |
|
312 try { |
|
313 ch.write(bb).get(); |
|
314 } catch (ExecutionException ee) { |
|
315 throw new IOException(ee.getCause()); |
|
316 } catch (InterruptedException ie) { |
|
317 interrupted = true; |
|
318 } |
|
319 } |
|
320 } finally { |
|
321 if (interrupted) |
|
322 Thread.currentThread().interrupt(); |
|
323 } |
|
324 } |
|
325 |
|
326 @Override |
|
327 public void close() throws IOException { |
|
328 ch.close(); |
|
329 } |
|
330 }; |
185 } |
331 } |
186 |
332 |
187 |
333 |
188 // -- Channels from streams -- |
334 // -- Channels from streams -- |
189 |
335 |