@Override public void write(Buffer source, long byteCount) throws IOException { if (!channel.isOpen()) throw new IllegalStateException("closed"); if (byteCount == 0) return; long remaining = byteCount; while (remaining > 0) { timeout.throwIfReached(); try (Buffer.UnsafeCursor ignored = source.readUnsafe(cursor)) { cursor.seek(0); int length = (int) Math.min(cursor.end - cursor.start, remaining); int written = channel.write(ByteBuffer.wrap(cursor.data, cursor.start, length)); remaining -= written; source.skip(written); } } }
@Override public long read(Buffer sink, long byteCount) throws IOException { if (!channel.isOpen()) throw new IllegalStateException("closed"); try (Buffer.UnsafeCursor ignored = sink.readAndWriteUnsafe(cursor)) { timeout.throwIfReached(); long oldSize = sink.size(); int length = (int) Math.min(8192, byteCount); cursor.expandBuffer(length); int read = channel.read(ByteBuffer.wrap(cursor.data, cursor.start, length)); if (read == -1) { cursor.resizeBuffer(oldSize); return -1; } else { cursor.resizeBuffer(oldSize + read); return read; } } }
@Test public synchronized void threadInterruptedOnThrowIfReached() throws Exception { Timeout timeout = new Timeout(); Thread.currentThread().interrupt(); try { timeout.throwIfReached(); fail(); } catch (InterruptedIOException expected) { assertEquals("interrupted", expected.getMessage()); assertTrue(Thread.interrupted()); } }
@Override public void throwIfReached() throws IOException { delegate.throwIfReached(); } }
@Override public long read(Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (byteCount == 0) return 0; try { timeout.throwIfReached(); Segment tail = sink.writableSegment(1); int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit); //fix bug java.lang.ArrayIndexOutOfBoundsException by huxq17 start maxToCopy = maxToCopy>tail.data.length?tail.data.length:maxToCopy; //fix bug java.lang.ArrayIndexOutOfBoundsException by huxq17 end int bytesRead = in.read(tail.data, tail.limit, maxToCopy); if (bytesRead == -1) return -1; tail.limit += bytesRead; sink.size += bytesRead; return bytesRead; } catch (AssertionError e) { if (isAndroidGetsocknameError(e)) throw new IOException(e); throw e; } }
@Override public void write(Buffer source, long byteCount) throws IOException { checkOffsetAndCount(source.size, 0, byteCount); while (byteCount > 0) { timeout.throwIfReached(); Segment head = source.head; int toCopy = (int) Math.min(byteCount, head.limit - head.pos); out.write(head.data, head.pos, toCopy); head.pos += toCopy; byteCount -= toCopy; source.size -= toCopy; if (head.pos == head.limit) { source.head = head.pop(); SegmentPool.recycle(head); } } }