From b2420242161a6098e28a3bf1809c0bed26771ebc Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sun, 13 Apr 2014 14:23:21 -0400 Subject: [PATCH] Switch to Okio. This depends on a new method, Buffer.copy() not included in Okio 0.5. We may need to wait for an Okio 0.6 before merging this. --- .../okhttp/mockwebserver/MockWebServer.java | 4 +- .../com/squareup/okhttp/curl/MainTest.java | 4 +- okhttp-tests/pom.xml | 1 - .../java/com/squareup/okhttp/RequestTest.java | 4 +- .../internal/spdy/HpackDraft05Test.java | 54 +- .../internal/spdy/Http20Draft09Test.java | 66 +- .../okhttp/internal/spdy/MockSpdyPeer.java | 4 +- .../okhttp/internal/spdy/Spdy3Test.java | 16 +- .../internal/spdy/SpdyConnectionTest.java | 38 +- okhttp/pom.xml | 1 - .../com/squareup/okhttp/OkHttpClient.java | 2 +- .../okhttp/internal/DiskLruCache.java | 4 +- .../com/squareup/okhttp/internal/Util.java | 8 +- .../okhttp/internal/http/HttpConnection.java | 41 +- .../okhttp/internal/http/RetryableSink.java | 12 +- .../okhttp/internal/http/SpdyTransport.java | 14 +- .../okhttp/internal/spdy/FrameWriter.java | 6 +- .../okhttp/internal/spdy/HpackDraft05.java | 6 +- .../okhttp/internal/spdy/Http20Draft09.java | 21 +- .../internal/spdy/NameValueBlockReader.java | 11 +- .../squareup/okhttp/internal/spdy/Spdy3.java | 12 +- .../okhttp/internal/spdy/SpdyConnection.java | 6 +- .../okhttp/internal/spdy/SpdyStream.java | 24 +- okio/pom.xml | 29 - okio/src/main/java/okio/Base64.java | 148 ---- okio/src/main/java/okio/BufferedSink.java | 72 -- okio/src/main/java/okio/BufferedSource.java | 114 --- okio/src/main/java/okio/ByteString.java | 211 ----- okio/src/main/java/okio/Deadline.java | 58 -- okio/src/main/java/okio/DeflaterSink.java | 138 ---- okio/src/main/java/okio/GzipSource.java | 200 ----- okio/src/main/java/okio/InflaterSource.java | 124 --- okio/src/main/java/okio/OkBuffer.java | 745 ------------------ okio/src/main/java/okio/Okio.java | 135 ---- okio/src/main/java/okio/RealBufferedSink.java | 191 ----- .../main/java/okio/RealBufferedSource.java | 205 ----- okio/src/main/java/okio/Segment.java | 135 ---- okio/src/main/java/okio/SegmentPool.java | 61 -- okio/src/main/java/okio/Sink.java | 69 -- okio/src/main/java/okio/Source.java | 81 -- okio/src/main/java/okio/Util.java | 71 -- okio/src/test/java/okio/ByteStringTest.java | 182 ----- okio/src/test/java/okio/DeflaterSinkTest.java | 141 ---- okio/src/test/java/okio/GzipSourceTest.java | 234 ------ .../test/java/okio/InflaterSourceTest.java | 115 --- okio/src/test/java/okio/MockSink.java | 70 -- .../java/okio/OkBufferReadUtf8LineTest.java | 22 - okio/src/test/java/okio/OkBufferTest.java | 682 ---------------- okio/src/test/java/okio/OkioTest.java | 81 -- okio/src/test/java/okio/ReadUtf8LineTest.java | 68 -- .../test/java/okio/RealBufferedSinkTest.java | 215 ----- .../RealBufferedSourceReadUtf8LineTest.java | 41 - .../java/okio/RealBufferedSourceTest.java | 208 ----- pom.xml | 7 +- 54 files changed, 181 insertions(+), 5031 deletions(-) delete mode 100644 okio/pom.xml delete mode 100644 okio/src/main/java/okio/Base64.java delete mode 100644 okio/src/main/java/okio/BufferedSink.java delete mode 100644 okio/src/main/java/okio/BufferedSource.java delete mode 100644 okio/src/main/java/okio/ByteString.java delete mode 100644 okio/src/main/java/okio/Deadline.java delete mode 100644 okio/src/main/java/okio/DeflaterSink.java delete mode 100644 okio/src/main/java/okio/GzipSource.java delete mode 100644 okio/src/main/java/okio/InflaterSource.java delete mode 100644 okio/src/main/java/okio/OkBuffer.java delete mode 100644 okio/src/main/java/okio/Okio.java delete mode 100644 okio/src/main/java/okio/RealBufferedSink.java delete mode 100644 okio/src/main/java/okio/RealBufferedSource.java delete mode 100644 okio/src/main/java/okio/Segment.java delete mode 100644 okio/src/main/java/okio/SegmentPool.java delete mode 100644 okio/src/main/java/okio/Sink.java delete mode 100644 okio/src/main/java/okio/Source.java delete mode 100644 okio/src/main/java/okio/Util.java delete mode 100644 okio/src/test/java/okio/ByteStringTest.java delete mode 100644 okio/src/test/java/okio/DeflaterSinkTest.java delete mode 100644 okio/src/test/java/okio/GzipSourceTest.java delete mode 100644 okio/src/test/java/okio/InflaterSourceTest.java delete mode 100644 okio/src/test/java/okio/MockSink.java delete mode 100644 okio/src/test/java/okio/OkBufferReadUtf8LineTest.java delete mode 100644 okio/src/test/java/okio/OkBufferTest.java delete mode 100644 okio/src/test/java/okio/OkioTest.java delete mode 100644 okio/src/test/java/okio/ReadUtf8LineTest.java delete mode 100644 okio/src/test/java/okio/RealBufferedSinkTest.java delete mode 100644 okio/src/test/java/okio/RealBufferedSourceReadUtf8LineTest.java delete mode 100644 okio/src/test/java/okio/RealBufferedSourceTest.java diff --git a/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java b/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java index 5a8357bd8..16df7f9ac 100644 --- a/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java +++ b/mockwebserver/src/main/java/com/squareup/okhttp/mockwebserver/MockWebServer.java @@ -63,9 +63,9 @@ import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import okio.Buffer; import okio.BufferedSink; import okio.ByteString; -import okio.OkBuffer; import okio.Okio; import static com.squareup.okhttp.mockwebserver.SocketPolicy.DISCONNECT_AT_START; @@ -695,7 +695,7 @@ public final class MockWebServer { } spdyHeaders.add(new Header(headerParts[0], headerParts[1])); } - OkBuffer body = new OkBuffer(); + Buffer body = new Buffer(); if (response.getBody() != null) { body.write(response.getBody()); } diff --git a/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java b/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java index 6a5b97298..d7fdffd0b 100644 --- a/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java +++ b/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java @@ -17,7 +17,7 @@ package com.squareup.okhttp.curl; import com.squareup.okhttp.Request; import java.io.IOException; -import okio.OkBuffer; +import okio.Buffer; import org.junit.Test; import static com.squareup.okhttp.curl.Main.fromArgs; @@ -85,7 +85,7 @@ public class MainTest { private static String bodyAsString(Request.Body body) { try { - OkBuffer buffer = new OkBuffer(); + Buffer buffer = new Buffer(); body.writeTo(buffer); return new String(buffer.readByteString(buffer.size()).toByteArray(), body.contentType().charset()); diff --git a/okhttp-tests/pom.xml b/okhttp-tests/pom.xml index 7c1573df0..ed270e2ac 100644 --- a/okhttp-tests/pom.xml +++ b/okhttp-tests/pom.xml @@ -16,7 +16,6 @@ com.squareup.okio okio - ${project.version} com.squareup.okhttp diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/RequestTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/RequestTest.java index 08f304e3a..d8870fcde 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/RequestTest.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/RequestTest.java @@ -19,7 +19,7 @@ import com.squareup.okhttp.internal.Util; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import okio.OkBuffer; +import okio.Buffer; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -74,7 +74,7 @@ public final class RequestTest { } private String bodyToHex(Request.Body body) throws IOException { - OkBuffer buffer = new OkBuffer(); + Buffer buffer = new Buffer(); body.writeTo(buffer); return buffer.readByteString(buffer.size()).hex(); } diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft05Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft05Test.java index 42ddcabc3..492057eb9 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft05Test.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/HpackDraft05Test.java @@ -18,8 +18,8 @@ package com.squareup.okhttp.internal.spdy; import java.io.IOException; import java.util.Arrays; import java.util.List; +import okio.Buffer; import okio.ByteString; -import okio.OkBuffer; import org.junit.Before; import org.junit.Test; @@ -30,9 +30,9 @@ import static org.junit.Assert.assertTrue; public class HpackDraft05Test { - private final OkBuffer bytesIn = new OkBuffer(); + private final Buffer bytesIn = new Buffer(); private HpackDraft05.Reader hpackReader; - private OkBuffer bytesOut = new OkBuffer(); + private Buffer bytesOut = new Buffer(); private HpackDraft05.Writer hpackWriter; @Before public void reset() { @@ -66,7 +66,7 @@ public class HpackDraft05Test { * Ensure the larger header content is not lost. */ @Test public void tooLargeToHPackIsStillEmitted() throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); out.writeByte(0x00); // Literal indexed out.writeByte(0x0a); // Literal name (len = 10) @@ -87,7 +87,7 @@ public class HpackDraft05Test { /** Oldest entries are evicted to support newer ones. */ @Test public void testEviction() throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); out.writeByte(0x00); // Literal indexed out.writeByte(0x0a); // Literal name (len = 10) @@ -138,7 +138,7 @@ public class HpackDraft05Test { /** Header table backing array is initially 8 long, let's ensure it grows. */ @Test public void dynamicallyGrowsBeyond64Entries() throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); for (int i = 0; i < 256; i++) { out.writeByte(0x00); // Literal indexed @@ -160,7 +160,7 @@ public class HpackDraft05Test { } @Test public void huffmanDecodingSupported() throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); out.writeByte(0x04); // == Literal indexed == // Indexed name (idx = 4) -> :path @@ -188,7 +188,7 @@ public class HpackDraft05Test { * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-05#appendix-E.1.1 */ @Test public void readLiteralHeaderFieldWithIndexing() throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); out.writeByte(0x00); // Literal indexed out.writeByte(0x0a); // Literal name (len = 10) @@ -217,7 +217,7 @@ public class HpackDraft05Test { @Test public void literalHeaderFieldWithoutIndexingNewName() throws IOException { List
headerBlock = headerEntries("custom-key", "custom-header"); - OkBuffer expectedBytes = new OkBuffer(); + Buffer expectedBytes = new Buffer(); expectedBytes.writeByte(0x40); // Not indexed expectedBytes.writeByte(0x0a); // Literal name (len = 10) @@ -244,7 +244,7 @@ public class HpackDraft05Test { @Test public void literalHeaderFieldWithoutIndexingIndexedName() throws IOException { List
headerBlock = headerEntries(":path", "/sample/path"); - OkBuffer expectedBytes = new OkBuffer(); + Buffer expectedBytes = new Buffer(); expectedBytes.writeByte(0x44); // == Literal not indexed == // Indexed name (idx = 4) -> :path expectedBytes.writeByte(0x0c); // Literal value (len = 12) @@ -369,7 +369,7 @@ public class HpackDraft05Test { * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-05#appendix-E.2 */ @Test public void readRequestExamplesWithoutHuffman() throws IOException { - OkBuffer out = firstRequestWithoutHuffman(); + Buffer out = firstRequestWithoutHuffman(); bytesIn.write(out, out.size()); hpackReader.readHeaders(); hpackReader.emitReferenceSet(); @@ -388,8 +388,8 @@ public class HpackDraft05Test { checkReadThirdRequestWithoutHuffman(); } - private OkBuffer firstRequestWithoutHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer firstRequestWithoutHuffman() { + Buffer out = new Buffer(); out.writeByte(0x82); // == Indexed - Add == // idx = 2 -> :method: GET @@ -439,8 +439,8 @@ public class HpackDraft05Test { ":authority", "www.example.com"), hpackReader.getAndReset()); } - private OkBuffer secondRequestWithoutHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer secondRequestWithoutHuffman() { + Buffer out = new Buffer(); out.writeByte(0x1b); // == Literal indexed == // Indexed name (idx = 27) -> cache-control @@ -490,8 +490,8 @@ public class HpackDraft05Test { "cache-control", "no-cache"), hpackReader.getAndReset()); } - private OkBuffer thirdRequestWithoutHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer thirdRequestWithoutHuffman() { + Buffer out = new Buffer(); out.writeByte(0x80); // == Empty reference set == out.writeByte(0x85); // == Indexed - Add == @@ -571,7 +571,7 @@ public class HpackDraft05Test { * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-05#appendix-E.3 */ @Test public void readRequestExamplesWithHuffman() throws IOException { - OkBuffer out = firstRequestWithHuffman(); + Buffer out = firstRequestWithHuffman(); bytesIn.write(out, out.size()); hpackReader.readHeaders(); hpackReader.emitReferenceSet(); @@ -590,8 +590,8 @@ public class HpackDraft05Test { checkReadThirdRequestWithHuffman(); } - private OkBuffer firstRequestWithHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer firstRequestWithHuffman() { + Buffer out = new Buffer(); out.writeByte(0x82); // == Indexed - Add == // idx = 2 -> :method: GET @@ -646,8 +646,8 @@ public class HpackDraft05Test { ":authority", "www.example.com"), hpackReader.getAndReset()); } - private OkBuffer secondRequestWithHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer secondRequestWithHuffman() { + Buffer out = new Buffer(); out.writeByte(0x1b); // == Literal indexed == // Indexed name (idx = 27) -> cache-control @@ -701,8 +701,8 @@ public class HpackDraft05Test { "cache-control", "no-cache"), hpackReader.getAndReset()); } - private OkBuffer thirdRequestWithHuffman() { - OkBuffer out = new OkBuffer(); + private Buffer thirdRequestWithHuffman() { + Buffer out = new Buffer(); out.writeByte(0x80); // == Empty reference set == out.writeByte(0x85); // == Indexed - Add == @@ -848,12 +848,12 @@ public class HpackDraft05Test { assertEquals(ByteString.EMPTY, newReader(byteStream(0)).readByteString(false)); } - private HpackDraft05.Reader newReader(OkBuffer source) { + private HpackDraft05.Reader newReader(Buffer source) { return new HpackDraft05.Reader(false, 4096, source); } - private OkBuffer byteStream(int... bytes) { - return new OkBuffer().write(intArrayToByteArray(bytes)); + private Buffer byteStream(int... bytes) { + return new Buffer().write(intArrayToByteArray(bytes)); } private void checkEntry(Header entry, String name, String value, int size) { diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft09Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft09Test.java index 248ea094c..6e7ca8a6d 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft09Test.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Http20Draft09Test.java @@ -19,9 +19,9 @@ import com.squareup.okhttp.internal.Util; import java.io.IOException; import java.util.Arrays; import java.util.List; +import okio.Buffer; import okio.BufferedSource; import okio.ByteString; -import okio.OkBuffer; import org.junit.Test; import static com.squareup.okhttp.internal.Util.headerEntries; @@ -34,7 +34,7 @@ public class Http20Draft09Test { static final int expectedStreamId = 15; @Test public void unknownFrameTypeIgnored() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); frame.writeShort(4); // has a 4-byte field frame.writeByte(99); // type 99 @@ -51,11 +51,11 @@ public class Http20Draft09Test { @Test public void onlyOneLiteralHeadersFrame() throws IOException { final List
sentHeaders = headerEntries("name", "value"); - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); // Write the headers frame, specifying no more frames are expected. { - OkBuffer headerBytes = literalHeaders(sentHeaders); + Buffer headerBytes = literalHeaders(sentHeaders); frame.writeShort((int) headerBytes.size()); frame.writeByte(Http20Draft09.TYPE_HEADERS); frame.writeByte(Http20Draft09.FLAG_END_HEADERS | Http20Draft09.FLAG_END_STREAM); @@ -84,12 +84,12 @@ public class Http20Draft09Test { } @Test public void headersWithPriority() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final List
sentHeaders = headerEntries("name", "value"); { // Write the headers frame, specifying priority flag and value. - OkBuffer headerBytes = literalHeaders(sentHeaders); + Buffer headerBytes = literalHeaders(sentHeaders); frame.writeShort((int) (headerBytes.size() + 4)); frame.writeByte(Http20Draft09.TYPE_HEADERS); frame.writeByte(Http20Draft09.FLAG_END_HEADERS | Http20Draft09.FLAG_PRIORITY); @@ -121,10 +121,10 @@ public class Http20Draft09Test { /** Headers are compressed, then framed. */ @Test public void headersFrameThenContinuation() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); // Decoding the first header will cross frame boundaries. - OkBuffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux")); + Buffer headerBlock = literalHeaders(headerEntries("foo", "barrr", "baz", "qux")); { // Write the first headers frame. frame.writeShort((int) (headerBlock.size() / 2)); frame.writeByte(Http20Draft09.TYPE_HEADERS); @@ -162,7 +162,7 @@ public class Http20Draft09Test { } @Test public void pushPromise() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final int expectedPromisedStreamId = 11; @@ -174,7 +174,7 @@ public class Http20Draft09Test { ); { // Write the push promise frame, specifying the associated stream ID. - OkBuffer headerBytes = literalHeaders(pushPromise); + Buffer headerBytes = literalHeaders(pushPromise); frame.writeShort((int) (headerBytes.size() + 4)); frame.writeByte(Http20Draft09.TYPE_PUSH_PROMISE); frame.writeByte(Http20Draft09.FLAG_END_PUSH_PROMISE); @@ -198,7 +198,7 @@ public class Http20Draft09Test { /** Headers are compressed, then framed. */ @Test public void pushPromiseThenContinuation() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final int expectedPromisedStreamId = 11; @@ -210,7 +210,7 @@ public class Http20Draft09Test { ); // Decoding the first header will cross frame boundaries. - OkBuffer headerBlock = literalHeaders(pushPromise); + Buffer headerBlock = literalHeaders(pushPromise); int firstFrameLength = (int) (headerBlock.size() - 1); { // Write the first headers frame. frame.writeShort(firstFrameLength + 4); @@ -243,7 +243,7 @@ public class Http20Draft09Test { } @Test public void readRstStreamFrame() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); frame.writeShort(4); frame.writeByte(Http20Draft09.TYPE_RST_STREAM); @@ -263,7 +263,7 @@ public class Http20Draft09Test { } @Test public void readSettingsFrame() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final int reducedTableSizeBytes = 16; @@ -289,7 +289,7 @@ public class Http20Draft09Test { } @Test public void pingRoundTrip() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final int expectedPayload1 = 7; final int expectedPayload2 = 8; @@ -317,7 +317,7 @@ public class Http20Draft09Test { } @Test public void maxLengthDataFrame() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final byte[] expectedData = new byte[16383]; Arrays.fill(expectedData, (byte) 2); @@ -330,7 +330,7 @@ public class Http20Draft09Test { frame.write(expectedData); // Check writer sends the same bytes. - assertEquals(frame, sendDataFrame(new OkBuffer().write(expectedData))); + assertEquals(frame, sendDataFrame(new Buffer().write(expectedData))); FrameReader fr = new Http20Draft09.Reader(frame, 4096, false); @@ -350,7 +350,7 @@ public class Http20Draft09Test { @Test public void tooLargeDataFrame() throws IOException { try { - sendDataFrame(new OkBuffer().write(new byte[0x1000000])); + sendDataFrame(new Buffer().write(new byte[0x1000000])); fail(); } catch (IllegalArgumentException e) { assertEquals("FRAME_SIZE_ERROR length > 16383: 16777216", e.getMessage()); @@ -358,7 +358,7 @@ public class Http20Draft09Test { } @Test public void windowUpdateRoundTrip() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final long expectedWindowSizeIncrement = 0x7fffffff; @@ -400,7 +400,7 @@ public class Http20Draft09Test { } @Test public void goAwayWithoutDebugDataRoundTrip() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final ErrorCode expectedError = ErrorCode.PROTOCOL_ERROR; @@ -428,7 +428,7 @@ public class Http20Draft09Test { } @Test public void goAwayWithDebugDataRoundTrip() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final ErrorCode expectedError = ErrorCode.PROTOCOL_ERROR; final ByteString expectedData = ByteString.encodeUtf8("abcdefgh"); @@ -458,7 +458,7 @@ public class Http20Draft09Test { } @Test public void frameSizeError() throws IOException { - Http20Draft09.Writer writer = new Http20Draft09.Writer(new OkBuffer(), true); + Http20Draft09.Writer writer = new Http20Draft09.Writer(new Buffer(), true); try { writer.frameHeader(16384, Http20Draft09.TYPE_DATA, Http20Draft09.FLAG_NONE, 0); @@ -469,7 +469,7 @@ public class Http20Draft09Test { } @Test public void streamIdHasReservedBit() throws IOException { - Http20Draft09.Writer writer = new Http20Draft09.Writer(new OkBuffer(), true); + Http20Draft09.Writer writer = new Http20Draft09.Writer(new Buffer(), true); try { int streamId = 3; @@ -481,34 +481,34 @@ public class Http20Draft09Test { } } - private OkBuffer literalHeaders(List
sentHeaders) throws IOException { - OkBuffer out = new OkBuffer(); + private Buffer literalHeaders(List
sentHeaders) throws IOException { + Buffer out = new Buffer(); new HpackDraft05.Writer(out).writeHeaders(sentHeaders); return out; } - private OkBuffer sendPingFrame(boolean ack, int payload1, int payload2) throws IOException { - OkBuffer out = new OkBuffer(); + private Buffer sendPingFrame(boolean ack, int payload1, int payload2) throws IOException { + Buffer out = new Buffer(); new Http20Draft09.Writer(out, true).ping(ack, payload1, payload2); return out; } - private OkBuffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) + private Buffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); new Http20Draft09.Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData); return out; } - private OkBuffer sendDataFrame(OkBuffer data) throws IOException { - OkBuffer out = new OkBuffer(); + private Buffer sendDataFrame(Buffer data) throws IOException { + Buffer out = new Buffer(); new Http20Draft09.Writer(out, true).dataFrame(expectedStreamId, Http20Draft09.FLAG_NONE, data, (int) data.size()); return out; } - private OkBuffer windowUpdate(long windowSizeIncrement) throws IOException { - OkBuffer out = new OkBuffer(); + private Buffer windowUpdate(long windowSizeIncrement) throws IOException { + Buffer out = new Buffer(); new Http20Draft09.Writer(out, true).windowUpdate(expectedStreamId, windowSizeIncrement); return out; } diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java index fd6007ddf..f43efa9ce 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/MockSpdyPeer.java @@ -30,9 +30,9 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; +import okio.Buffer; import okio.BufferedSource; import okio.ByteString; -import okio.OkBuffer; import okio.Okio; /** Replays prerecorded outgoing frames and records incoming frames. */ @@ -40,7 +40,7 @@ public final class MockSpdyPeer implements Closeable { private int frameCount = 0; private boolean client = false; private Variant variant = new Spdy3(); - private final OkBuffer bytesOut = new OkBuffer(); + private final Buffer bytesOut = new Buffer(); private FrameWriter frameWriter = variant.newWriter(bytesOut, client); private final List outFrames = new ArrayList(); private final BlockingQueue inFrames = new LinkedBlockingQueue(); diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Spdy3Test.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Spdy3Test.java index 1904b908f..c902773c9 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Spdy3Test.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/Spdy3Test.java @@ -17,8 +17,8 @@ package com.squareup.okhttp.internal.spdy; import com.squareup.okhttp.internal.Util; import java.io.IOException; +import okio.Buffer; import okio.ByteString; -import okio.OkBuffer; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -29,7 +29,7 @@ public class Spdy3Test { @Test public void tooLargeDataFrame() throws IOException { try { - sendDataFrame(new OkBuffer().write(new byte[0x1000000])); + sendDataFrame(new Buffer().write(new byte[0x1000000])); fail(); } catch (IllegalArgumentException e) { assertEquals("FRAME_TOO_LARGE max size is 16Mib: " + 0x1000000L, e.getMessage()); @@ -53,7 +53,7 @@ public class Spdy3Test { } @Test public void goAwayRoundTrip() throws IOException { - OkBuffer frame = new OkBuffer(); + Buffer frame = new Buffer(); final ErrorCode expectedError = ErrorCode.PROTOCOL_ERROR; @@ -83,18 +83,18 @@ public class Spdy3Test { }); } - private void sendDataFrame(OkBuffer source) throws IOException { - Spdy3.Writer writer = new Spdy3.Writer(new OkBuffer(), true); + private void sendDataFrame(Buffer source) throws IOException { + Spdy3.Writer writer = new Spdy3.Writer(new Buffer(), true); writer.sendDataFrame(expectedStreamId, 0, source, (int) source.size()); } private void windowUpdate(long increment) throws IOException { - new Spdy3.Writer(new OkBuffer(), true).windowUpdate(expectedStreamId, increment); + new Spdy3.Writer(new Buffer(), true).windowUpdate(expectedStreamId, increment); } - private OkBuffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) + private Buffer sendGoAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) throws IOException { - OkBuffer out = new OkBuffer(); + Buffer out = new Buffer(); new Spdy3.Writer(out, true).goAway(lastGoodStreamId, errorCode, debugData); return out; } diff --git a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java index 2ef127e99..0ea345c8e 100644 --- a/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java +++ b/okhttp-tests/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java @@ -23,10 +23,10 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; import okio.ByteString; -import okio.OkBuffer; import okio.Okio; import okio.Source; import org.junit.After; @@ -67,7 +67,7 @@ public final class SpdyConnectionTest { peer.acceptFrame(); // SYN_STREAM peer.sendFrame() .synReply(false, 1, headerEntries("a", "android")); - peer.sendFrame().data(true, 1, new OkBuffer().writeUtf8("robot")); + peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot")); peer.acceptFrame(); // DATA peer.play(); @@ -436,7 +436,7 @@ public final class SpdyConnectionTest { @Test public void bogusDataFrameDoesNotDisruptConnection() throws Exception { // write the mocking script - peer.sendFrame().data(true, 41, new OkBuffer().writeUtf8("bogus")); + peer.sendFrame().data(true, 41, new Buffer().writeUtf8("bogus")); peer.acceptFrame(); // RST_STREAM peer.sendFrame().ping(false, 2, 0); peer.acceptFrame(); // PING @@ -575,7 +575,7 @@ public final class SpdyConnectionTest { BufferedSink out = Okio.buffer(stream.getSink()); in.close(); try { - in.read(new OkBuffer(), 1); + in.read(new Buffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream closed", expected.getMessage()); @@ -619,7 +619,7 @@ public final class SpdyConnectionTest { BufferedSink out = Okio.buffer(stream.getSink()); source.close(); try { - source.read(new OkBuffer(), 1); + source.read(new Buffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream closed", expected.getMessage()); @@ -651,7 +651,7 @@ public final class SpdyConnectionTest { // write the mocking script peer.acceptFrame(); // SYN_STREAM peer.sendFrame().synReply(false, 1, headerEntries("b", "banana")); - peer.sendFrame().data(true, 1, new OkBuffer().writeUtf8("square")); + peer.sendFrame().data(true, 1, new Buffer().writeUtf8("square")); peer.play(); // play it back @@ -685,7 +685,7 @@ public final class SpdyConnectionTest { assertEquals(headerEntries("a", "android"), stream.getResponseHeaders()); connection.ping().roundTripTime(); // Ensure that the 2nd SYN REPLY has been received. try { - stream.getSource().read(new OkBuffer(), 1); + stream.getSource().read(new Buffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream was reset: STREAM_IN_USE", expected.getMessage()); @@ -738,8 +738,8 @@ public final class SpdyConnectionTest { // write the mocking script peer.acceptFrame(); // SYN_STREAM peer.sendFrame().synReply(false, 1, headerEntries("a", "android")); - peer.sendFrame().data(true, 1, new OkBuffer().writeUtf8("robot")); - peer.sendFrame().data(true, 1, new OkBuffer().writeUtf8("c3po")); // Ignored. + peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot")); + peer.sendFrame().data(true, 1, new Buffer().writeUtf8("c3po")); // Ignored. peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded. peer.acceptFrame(); // PING peer.play(); @@ -763,7 +763,7 @@ public final class SpdyConnectionTest { // write the mocking script peer.acceptFrame(); // SYN_STREAM peer.sendFrame().synReply(false, 1, headerEntries("b", "banana")); - peer.sendFrame().data(false, 1, new OkBuffer().write(new byte[64 * 1024 + 1])); + peer.sendFrame().data(false, 1, new Buffer().write(new byte[64 * 1024 + 1])); peer.sendFrame().ping(false, 2, 0); // Ping just to make sure the stream was fastforwarded. peer.acceptFrame(); // PING peer.play(); @@ -946,7 +946,7 @@ public final class SpdyConnectionTest { assertEquals("stream was reset: CANCEL", expected.getMessage()); } try { - stream.getSource().read(new OkBuffer(), 1); + stream.getSource().read(new Buffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream was reset: CANCEL", expected.getMessage()); @@ -991,7 +991,7 @@ public final class SpdyConnectionTest { Source source = stream.getSource(); long startNanos = System.nanoTime(); try { - source.read(new OkBuffer(), 1); + source.read(new Buffer(), 1); fail(); } catch (IOException expected) { } @@ -1094,7 +1094,7 @@ public final class SpdyConnectionTest { assertEquals(0, stream.unacknowledgedBytesRead); assertEquals(headerEntries("a", "android"), stream.getResponseHeaders()); Source in = stream.getSource(); - OkBuffer buffer = new OkBuffer(); + Buffer buffer = new Buffer(); while (in.read(buffer, 1024) != -1) { if (buffer.size() == 3 * windowUpdateThreshold) break; } @@ -1115,8 +1115,8 @@ public final class SpdyConnectionTest { } } - private OkBuffer data(int byteCount) { - return new OkBuffer().write(new byte[byteCount]); + private Buffer data(int byteCount) { + return new Buffer().write(new byte[byteCount]); } @Test public void serverSendsEmptyDataClientDoesntSendWindowUpdate() throws Exception { @@ -1140,7 +1140,7 @@ public final class SpdyConnectionTest { // Play it back. SpdyConnection connection = connection(peer, variant); SpdyStream client = connection.newStream(headerEntries("b", "banana"), false, true); - assertEquals(-1, client.getSource().read(new OkBuffer(), 1)); + assertEquals(-1, client.getSource().read(new Buffer(), 1)); // Verify the peer received what was expected. MockSpdyPeer.InFrame synStream = peer.takeFrame(); @@ -1416,7 +1416,7 @@ public final class SpdyConnectionTest { // write the mocking script peer.acceptFrame(); // SYN_STREAM peer.sendFrame(ByteString.decodeBase64(frame).toByteArray()); - peer.sendFrame().data(true, 1, new OkBuffer().writeUtf8("robot")); + peer.sendFrame().data(true, 1, new Buffer().writeUtf8("robot")); peer.acceptFrame(); // DATA peer.play(); @@ -1479,7 +1479,7 @@ public final class SpdyConnectionTest { SpdyConnection connection = connectionBuilder(peer, HTTP_20_DRAFT_09) .pushObserver(observer).build(); SpdyStream client = connection.newStream(headerEntries("b", "banana"), false, true); - assertEquals(-1, client.getSource().read(new OkBuffer(), 1)); + assertEquals(-1, client.getSource().read(new Buffer(), 1)); // verify the peer received what was expected assertEquals(TYPE_HEADERS, peer.takeFrame().type); @@ -1565,7 +1565,7 @@ public final class SpdyConnectionTest { } private void assertStreamData(String expected, Source source) throws IOException { - OkBuffer buffer = new OkBuffer(); + Buffer buffer = new Buffer(); while (source.read(buffer, Long.MAX_VALUE) != -1) { } String actual = buffer.readUtf8(buffer.size()); diff --git a/okhttp/pom.xml b/okhttp/pom.xml index c7e3ec4bd..48531cde3 100644 --- a/okhttp/pom.xml +++ b/okhttp/pom.xml @@ -16,7 +16,6 @@ com.squareup.okio okio - ${project.version} diff --git a/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java b/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java index bb4be687a..60a44868b 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java +++ b/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java @@ -45,7 +45,7 @@ import okio.ByteString; * OkHttpClient for all of their HTTP requests - benefiting from a shared * response cache, thread pool, connection re-use, etc. * - * Instances of OkHttpClient are intended to be fully configured before they're + *

Instances of OkHttpClient are intended to be fully configured before they're * shared - once shared they should be treated as immutable and can safely be used * to concurrently open new connections. If required, threads can call * {@link #clone()} to make a shallow copy of the OkHttpClient that can be diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/DiskLruCache.java b/okhttp/src/main/java/com/squareup/okhttp/internal/DiskLruCache.java index 7f4fa1106..118332369 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/DiskLruCache.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/DiskLruCache.java @@ -34,9 +34,9 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; -import okio.OkBuffer; import okio.Okio; /** @@ -657,7 +657,7 @@ public final class DiskLruCache implements Closeable { } private static String inputStreamToString(InputStream in) throws IOException { - OkBuffer buffer = Util.readFully(Okio.source(in)); + Buffer buffer = Util.readFully(Okio.source(in)); return buffer.readUtf8(buffer.size()); } diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/Util.java b/okhttp/src/main/java/com/squareup/okhttp/internal/Util.java index 51e04e845..7eec1ea87 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/Util.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/Util.java @@ -38,7 +38,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadFactory; import okio.ByteString; -import okio.OkBuffer; +import okio.Buffer; import okio.Source; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -210,8 +210,8 @@ public final class Util { } /** Returns the remainder of 'source' as a buffer, closing it when done. */ - public static OkBuffer readFully(Source source) throws IOException { - OkBuffer result = new OkBuffer(); + public static Buffer readFully(Source source) throws IOException { + Buffer result = new Buffer(); while (source.read(result, 2048) != -1) { } source.close(); @@ -222,7 +222,7 @@ public final class Util { public static boolean skipAll(Source in, int timeoutMillis) throws IOException { // TODO: Implement deadlines everywhere so they can do this work. long startNanos = System.nanoTime(); - OkBuffer skipBuffer = new OkBuffer(); + Buffer skipBuffer = new Buffer(); while (NANOSECONDS.toMillis(System.nanoTime() - startNanos) < timeoutMillis) { long read = in.read(skipBuffer, 2048); if (read == -1) return true; // Successfully exhausted the stream. diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java index 718d4719a..6d9fd5184 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java @@ -28,13 +28,13 @@ import java.net.CacheRequest; import java.net.ProtocolException; import java.net.Socket; import java.net.SocketTimeoutException; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; -import okio.Deadline; -import okio.OkBuffer; import okio.Okio; import okio.Sink; import okio.Source; +import okio.Timeout; import static com.squareup.okhttp.internal.Util.checkOffsetAndCount; import static com.squareup.okhttp.internal.http.StatusLine.HTTP_CONTINUE; @@ -277,11 +277,11 @@ public final class HttpConnection { this.bytesRemaining = bytesRemaining; } - @Override public Sink deadline(Deadline deadline) { - return this; // TODO: honor deadline. + @Override public Timeout timeout() { + return sink.timeout(); } - @Override public void write(OkBuffer source, long byteCount) throws IOException { + @Override public void write(Buffer source, long byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); checkOffsetAndCount(source.size(), 0, byteCount); if (byteCount > bytesRemaining) { @@ -322,11 +322,11 @@ public final class HttpConnection { private boolean closed; - @Override public Sink deadline(Deadline deadline) { - return this; // TODO: honor deadline. + @Override public Timeout timeout() { + return sink.timeout(); } - @Override public void write(OkBuffer source, long byteCount) throws IOException { + @Override public void write(Buffer source, long byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); if (byteCount == 0) return; @@ -377,9 +377,9 @@ public final class HttpConnection { } /** Copy the last {@code byteCount} bytes of {@code source} to the cache body. */ - protected final void cacheWrite(OkBuffer source, long byteCount) throws IOException { + protected final void cacheWrite(Buffer source, long byteCount) throws IOException { if (cacheBody != null) { - Okio.copy(source, source.size() - byteCount, byteCount, cacheBody); + source.copyTo(cacheBody, source.size() - byteCount, byteCount); } } @@ -437,7 +437,7 @@ public final class HttpConnection { } } - @Override public long read(OkBuffer sink, long byteCount) + @Override public long read(Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); @@ -457,9 +457,8 @@ public final class HttpConnection { return read; } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } @Override public void close() throws IOException { @@ -486,7 +485,7 @@ public final class HttpConnection { } @Override public long read( - OkBuffer sink, long byteCount) throws IOException { + Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (!hasMoreChunks) return -1; @@ -530,9 +529,8 @@ public final class HttpConnection { } } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } @Override public void close() throws IOException { @@ -552,7 +550,7 @@ public final class HttpConnection { super(cacheRequest); } - @Override public long read(OkBuffer sink, long byteCount) + @Override public long read(Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); @@ -568,9 +566,8 @@ public final class HttpConnection { return read; } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } @Override public void close() throws IOException { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RetryableSink.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/RetryableSink.java index b8f53a3d8..27e9470f6 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/RetryableSink.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/RetryableSink.java @@ -18,9 +18,9 @@ package com.squareup.okhttp.internal.http; import java.io.IOException; import java.net.ProtocolException; +import okio.Buffer; import okio.BufferedSink; -import okio.Deadline; -import okio.OkBuffer; +import okio.Timeout; import okio.Sink; import static com.squareup.okhttp.internal.Util.checkOffsetAndCount; @@ -33,7 +33,7 @@ import static com.squareup.okhttp.internal.Util.checkOffsetAndCount; final class RetryableSink implements Sink { private boolean closed; private final int limit; - private final OkBuffer content = new OkBuffer(); + private final Buffer content = new Buffer(); public RetryableSink(int limit) { this.limit = limit; @@ -52,7 +52,7 @@ final class RetryableSink implements Sink { } } - @Override public void write(OkBuffer source, long byteCount) throws IOException { + @Override public void write(Buffer source, long byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); checkOffsetAndCount(source.size(), 0, byteCount); if (limit != -1 && content.size() > limit - byteCount) { @@ -64,8 +64,8 @@ final class RetryableSink implements Sink { @Override public void flush() throws IOException { } - @Override public Sink deadline(Deadline deadline) { - return this; + @Override public Timeout timeout() { + return Timeout.NONE; } public long contentLength() throws IOException { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java index 9db9643f1..277828aa7 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java @@ -34,12 +34,11 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Set; +import okio.Buffer; import okio.ByteString; -import okio.Deadline; -import okio.OkBuffer; -import okio.Okio; import okio.Sink; import okio.Source; +import okio.Timeout; import static com.squareup.okhttp.internal.spdy.Header.RESPONSE_STATUS; import static com.squareup.okhttp.internal.spdy.Header.TARGET_AUTHORITY; @@ -262,7 +261,7 @@ public final class SpdyTransport implements Transport { this.cacheRequest = cacheRequest; } - @Override public long read(OkBuffer sink, long byteCount) + @Override public long read(Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); @@ -278,15 +277,14 @@ public final class SpdyTransport implements Transport { } if (cacheBody != null) { - Okio.copy(sink, sink.size() - read, read, cacheBody); + sink.copyTo(cacheBody, sink.size() - read, read); } return read; } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } @Override public void close() throws IOException { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/FrameWriter.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/FrameWriter.java index f96c2aa09..661e00931 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/FrameWriter.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/FrameWriter.java @@ -19,7 +19,7 @@ package com.squareup.okhttp.internal.spdy; import java.io.Closeable; import java.io.IOException; import java.util.List; -import okio.OkBuffer; +import okio.Buffer; /** Writes transport frames for SPDY/3 or HTTP/2. */ public interface FrameWriter extends Closeable { @@ -60,9 +60,9 @@ public interface FrameWriter extends Closeable { * * @param source the buffer to draw bytes from. May be null if byteCount is 0. */ - void data(boolean outFinished, int streamId, OkBuffer source, int byteCount) throws IOException; + void data(boolean outFinished, int streamId, Buffer source, int byteCount) throws IOException; - void data(boolean outFinished, int streamId, OkBuffer source) throws IOException; + void data(boolean outFinished, int streamId, Buffer source) throws IOException; /** Write okhttp's settings to the peer. */ void settings(Settings okHttpSettings) throws IOException; diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java index 645f162ce..ccc68a674 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java @@ -8,9 +8,9 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import okio.Buffer; import okio.BufferedSource; import okio.ByteString; -import okio.OkBuffer; import okio.Okio; import okio.Source; @@ -396,9 +396,9 @@ final class HpackDraft05 { } static final class Writer { - private final OkBuffer out; + private final Buffer out; - Writer(OkBuffer out) { + Writer(Buffer out) { this.out = out; } diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java index a88b747ef..1c3e7f39b 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java @@ -18,12 +18,12 @@ package com.squareup.okhttp.internal.spdy; import com.squareup.okhttp.Protocol; import java.io.IOException; import java.util.List; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; import okio.ByteString; -import okio.Deadline; -import okio.OkBuffer; import okio.Source; +import okio.Timeout; /** * Read and write http/2 v09 frames. @@ -291,14 +291,14 @@ public final class Http20Draft09 implements Variant { static final class Writer implements FrameWriter { private final BufferedSink sink; private final boolean client; - private final OkBuffer hpackBuffer; + private final Buffer hpackBuffer; private final HpackDraft05.Writer hpackWriter; private boolean closed; Writer(BufferedSink sink, boolean client) { this.sink = sink; this.client = client; - this.hpackBuffer = new OkBuffer(); + this.hpackBuffer = new Buffer(); this.hpackWriter = new HpackDraft05.Writer(hpackBuffer); } @@ -388,12 +388,12 @@ public final class Http20Draft09 implements Variant { sink.flush(); } - @Override public synchronized void data(boolean outFinished, int streamId, OkBuffer source) + @Override public synchronized void data(boolean outFinished, int streamId, Buffer source) throws IOException { data(outFinished, streamId, source, (int) source.size()); } - @Override public synchronized void data(boolean outFinished, int streamId, OkBuffer source, + @Override public synchronized void data(boolean outFinished, int streamId, Buffer source, int byteCount) throws IOException { if (closed) throw new IOException("closed"); byte flags = FLAG_NONE; @@ -401,7 +401,7 @@ public final class Http20Draft09 implements Variant { dataFrame(streamId, flags, source, byteCount); } - void dataFrame(int streamId, byte flags, OkBuffer buffer, int byteCount) throws IOException { + void dataFrame(int streamId, byte flags, Buffer buffer, int byteCount) throws IOException { byte type = TYPE_DATA; frameHeader(byteCount, type, flags, streamId); if (byteCount > 0) { @@ -508,7 +508,7 @@ public final class Http20Draft09 implements Variant { this.source = source; } - @Override public long read(OkBuffer sink, long byteCount) throws IOException { + @Override public long read(Buffer sink, long byteCount) throws IOException { while (left == 0) { if ((flags & FLAG_END_HEADERS) != 0) return -1; readContinuationHeader(); @@ -521,9 +521,8 @@ public final class Http20Draft09 implements Variant { return read; } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } @Override public void close() throws IOException { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java index 293d817a1..053426b07 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java @@ -5,13 +5,13 @@ import java.util.ArrayList; import java.util.List; import java.util.zip.DataFormatException; import java.util.zip.Inflater; +import okio.Buffer; import okio.BufferedSource; import okio.ByteString; -import okio.Deadline; import okio.InflaterSource; -import okio.OkBuffer; import okio.Okio; import okio.Source; +import okio.Timeout; /** * Reads a SPDY/3 Name/Value header block. This class is made complicated by the @@ -37,7 +37,7 @@ class NameValueBlockReader { // block. We cut the inflater off at its source because we can't predict the // ratio of compressed bytes to uncompressed bytes. Source throttleSource = new Source() { - @Override public long read(OkBuffer sink, long byteCount) + @Override public long read(Buffer sink, long byteCount) throws IOException { if (compressedLimit == 0) return -1; // Out of data for the current block. long read = source.read(sink, Math.min(byteCount, compressedLimit)); @@ -50,9 +50,8 @@ class NameValueBlockReader { source.close(); } - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; + @Override public Timeout timeout() { + return source.timeout(); } }; diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java index a71bc6f5f..9bf963cd5 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java @@ -22,11 +22,11 @@ import java.io.UnsupportedEncodingException; import java.net.ProtocolException; import java.util.List; import java.util.zip.Deflater; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; import okio.ByteString; import okio.DeflaterSink; -import okio.OkBuffer; import okio.Okio; /** @@ -292,7 +292,7 @@ final class Spdy3 implements Variant { /** Write spdy/3 frames. */ static final class Writer implements FrameWriter { private final BufferedSink sink; - private final OkBuffer headerBlockBuffer; + private final Buffer headerBlockBuffer; private final BufferedSink headerBlockOut; private final boolean client; private boolean closed; @@ -303,7 +303,7 @@ final class Spdy3 implements Variant { Deflater deflater = new Deflater(); deflater.setDictionary(DICTIONARY); - headerBlockBuffer = new OkBuffer(); + headerBlockBuffer = new Buffer(); headerBlockOut = Okio.buffer(new DeflaterSink(headerBlockBuffer, deflater)); } @@ -388,18 +388,18 @@ final class Spdy3 implements Variant { sink.flush(); } - @Override public synchronized void data(boolean outFinished, int streamId, OkBuffer source) + @Override public synchronized void data(boolean outFinished, int streamId, Buffer source) throws IOException { data(outFinished, streamId, source, (int) source.size()); } - @Override public synchronized void data(boolean outFinished, int streamId, OkBuffer source, + @Override public synchronized void data(boolean outFinished, int streamId, Buffer source, int byteCount) throws IOException { int flags = (outFinished ? FLAG_FIN : 0); sendDataFrame(streamId, flags, source, byteCount); } - void sendDataFrame(int streamId, int flags, OkBuffer buffer, int byteCount) + void sendDataFrame(int streamId, int flags, Buffer buffer, int byteCount) throws IOException { if (closed) throw new IOException("closed"); if (byteCount > 0xffffffL) { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java index da7c4e174..20ecc7cf5 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java @@ -33,10 +33,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; import okio.ByteString; -import okio.OkBuffer; import okio.Okio; import static com.squareup.okhttp.internal.spdy.Settings.DEFAULT_INITIAL_WINDOW_SIZE; @@ -287,7 +287,7 @@ public final class SpdyConnection implements Closeable { * will not block. The only use case for zero {@code byteCount} is closing * a flushed output stream. */ - public void writeData(int streamId, boolean outFinished, OkBuffer buffer, long byteCount) + public void writeData(int streamId, boolean outFinished, Buffer buffer, long byteCount) throws IOException { if (byteCount == 0) { // Empty data frames are not flow-controlled. frameWriter.data(outFinished, streamId, buffer, 0); @@ -809,7 +809,7 @@ public final class SpdyConnection implements Closeable { */ private void pushDataLater(final int streamId, final BufferedSource source, final int byteCount, final boolean inFinished) throws IOException { - final OkBuffer buffer = new OkBuffer(); + final Buffer buffer = new Buffer(); source.require(byteCount); // Eagerly read the frame before firing client thread. source.read(buffer, byteCount); if (buffer.size() != byteCount) throw new IOException(buffer.size() + " != " + byteCount); diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java index 0fcde2dbb..5c459174c 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java @@ -22,11 +22,11 @@ import java.io.InterruptedIOException; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.List; +import okio.Buffer; import okio.BufferedSource; -import okio.Deadline; -import okio.OkBuffer; import okio.Sink; import okio.Source; +import okio.Timeout; import static com.squareup.okhttp.internal.spdy.Settings.DEFAULT_INITIAL_WINDOW_SIZE; @@ -338,10 +338,10 @@ public final class SpdyStream { */ private final class SpdyDataSource implements Source { /** Buffer to receive data from the network into. Only accessed by the reader thread. */ - private final OkBuffer receiveBuffer = new OkBuffer(); + private final Buffer receiveBuffer = new Buffer(); /** Buffer with readable data. Guarded by SpdyStream.this. */ - private final OkBuffer readBuffer = new OkBuffer(); + private final Buffer readBuffer = new Buffer(); /** Maximum number of bytes to buffer before reporting a flow control error. */ private final long maxByteCount; @@ -359,7 +359,7 @@ public final class SpdyStream { this.maxByteCount = maxByteCount; } - @Override public long read(OkBuffer sink, long byteCount) + @Override public long read(Buffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); @@ -462,9 +462,9 @@ public final class SpdyStream { } } - @Override public Source deadline(Deadline deadline) { - // TODO: honor deadlines. - return this; + @Override public Timeout timeout() { + // TODO: honor timeouts. + return Timeout.NONE; } @Override public void close() throws IOException { @@ -518,7 +518,7 @@ public final class SpdyStream { */ private boolean finished; - @Override public void write(OkBuffer source, long byteCount) throws IOException { + @Override public void write(Buffer source, long byteCount) throws IOException { assert (!Thread.holdsLock(SpdyStream.this)); while (byteCount > 0) { long toWrite; @@ -549,9 +549,9 @@ public final class SpdyStream { connection.flush(); } - @Override public Sink deadline(Deadline deadline) { - // TODO: honor deadlines. - return this; + @Override public Timeout timeout() { + // TODO: honor timeouts. + return Timeout.NONE; } @Override public void close() throws IOException { diff --git a/okio/pom.xml b/okio/pom.xml deleted file mode 100644 index f1a33b5d6..000000000 --- a/okio/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - 4.0.0 - - - com.squareup.okhttp - parent - 2.0.0-SNAPSHOT - - - com.squareup.okio - okio - Okio - - - - junit - junit - test - - - org.codehaus.mojo - animal-sniffer-annotations - 1.10 - true - - - diff --git a/okio/src/main/java/okio/Base64.java b/okio/src/main/java/okio/Base64.java deleted file mode 100644 index 087b28747..000000000 --- a/okio/src/main/java/okio/Base64.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author Alexander Y. Kleymenov - */ - -package okio; - -import java.io.UnsupportedEncodingException; - -final class Base64 { - private Base64() { - } - - public static byte[] decode(String in) { - // Ignore trailing '=' padding and whitespace from the input. - int limit = in.length(); - for (; limit > 0; limit--) { - char c = in.charAt(limit - 1); - if (c != '=' && c != '\n' && c != '\r' && c != ' ' && c != '\t') { - break; - } - } - - // If the input includes whitespace, this output array will be longer than necessary. - byte[] out = new byte[(int) (limit * 6L / 8L)]; - int outCount = 0; - int inCount = 0; - - int word = 0; - for (int pos = 0; pos < limit; pos++) { - char c = in.charAt(pos); - - int bits; - if (c >= 'A' && c <= 'Z') { - // char ASCII value - // A 65 0 - // Z 90 25 (ASCII - 65) - bits = c - 65; - } else if (c >= 'a' && c <= 'z') { - // char ASCII value - // a 97 26 - // z 122 51 (ASCII - 71) - bits = c - 71; - } else if (c >= '0' && c <= '9') { - // char ASCII value - // 0 48 52 - // 9 57 61 (ASCII + 4) - bits = c + 4; - } else if (c == '+') { - bits = 62; - } else if (c == '/') { - bits = 63; - } else if (c == '\n' || c == '\r' || c == ' ' || c == '\t') { - continue; - } else { - return null; - } - - // Append this char's 6 bits to the word. - word = (word << 6) | (byte) bits; - - // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes. - inCount++; - if (inCount % 4 == 0) { - out[outCount++] = (byte) (word >> 16); - out[outCount++] = (byte) (word >> 8); - out[outCount++] = (byte) word; - } - } - - int lastWordChars = inCount % 4; - if (lastWordChars == 1) { - // We read 1 char followed by "===". But 6 bits is a truncated byte! Fail. - return null; - } else if (lastWordChars == 2) { - // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits. - word = word << 12; - out[outCount++] = (byte) (word >> 16); - } else if (lastWordChars == 3) { - // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits. - word = word << 6; - out[outCount++] = (byte) (word >> 16); - out[outCount++] = (byte) (word >> 8); - } - - // If we sized our out array perfectly, we're done. - if (outCount == out.length) return out; - - // Copy the decoded bytes to a new, right-sized array. - byte[] prefix = new byte[outCount]; - System.arraycopy(out, 0, prefix, 0, outCount); - return prefix; - } - - private static final byte[] MAP = new byte[] { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', '+', '/' - }; - - public static String encode(byte[] in) { - int length = (in.length + 2) * 4 / 3; - byte[] out = new byte[length]; - int index = 0, end = in.length - in.length % 3; - for (int i = 0; i < end; i += 3) { - out[index++] = MAP[(in[i] & 0xff) >> 2]; - out[index++] = MAP[((in[i] & 0x03) << 4) | ((in[i + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[i + 1] & 0x0f) << 2) | ((in[i + 2] & 0xff) >> 6)]; - out[index++] = MAP[(in[i + 2] & 0x3f)]; - } - switch (in.length % 3) { - case 1: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[(in[end] & 0x03) << 4]; - out[index++] = '='; - out[index++] = '='; - break; - case 2: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[((in[end] & 0x03) << 4) | ((in[end + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[end + 1] & 0x0f) << 2)]; - out[index++] = '='; - break; - } - try { - return new String(out, 0, index, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } - } -} diff --git a/okio/src/main/java/okio/BufferedSink.java b/okio/src/main/java/okio/BufferedSink.java deleted file mode 100644 index 3066011a0..000000000 --- a/okio/src/main/java/okio/BufferedSink.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A sink that keeps a buffer internally so that callers can do small writes - * without a performance penalty. - */ -public interface BufferedSink extends Sink { - /** Returns this sink's internal buffer. */ - OkBuffer buffer(); - - BufferedSink write(ByteString byteString) throws IOException; - - /** - * Like {@link OutputStream#write}, this writes a complete byte array to this - * sink. - */ - BufferedSink write(byte[] source) throws IOException; - - /** - * Like {@link OutputStream#write}, this writes {@code byteCount} bytes - * of {@code source}, starting at {@code offset}. - */ - BufferedSink write(byte[] source, int offset, int byteCount) throws IOException; - - /** Encodes {@code string} in UTF-8 and writes it to this sink. */ - BufferedSink writeUtf8(String string) throws IOException; - - /** Writes a byte to this sink. */ - BufferedSink writeByte(int b) throws IOException; - - /** Writes a big-endian short to this sink using two bytes. */ - BufferedSink writeShort(int s) throws IOException; - - /** Writes a little-endian short to this sink using two bytes. */ - BufferedSink writeShortLe(int s) throws IOException; - - /** Writes a big-endian int to this sink using four bytes. */ - BufferedSink writeInt(int i) throws IOException; - - /** Writes a little-endian int to this sink using four bytes. */ - BufferedSink writeIntLe(int i) throws IOException; - - /** Writes a big-endian long to this sink using eight bytes. */ - BufferedSink writeLong(long v) throws IOException; - - /** Writes a little-endian long to this sink using eight bytes. */ - BufferedSink writeLongLe(long v) throws IOException; - - /** Writes complete segments to this sink. Like {@link #flush}, but weaker. */ - BufferedSink emitCompleteSegments() throws IOException; - - /** Returns an output stream that writes to this sink. */ - OutputStream outputStream(); -} diff --git a/okio/src/main/java/okio/BufferedSource.java b/okio/src/main/java/okio/BufferedSource.java deleted file mode 100644 index 2b48823ce..000000000 --- a/okio/src/main/java/okio/BufferedSource.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A source that keeps a buffer internally so that callers can do small reads - * without a performance penalty. It also allows clients to read ahead, - * buffering as much as necessary before consuming input. - */ -public interface BufferedSource extends Source { - /** Returns this source's internal buffer. */ - OkBuffer buffer(); - - /** - * Returns true if there are no more bytes in this source. This will block - * until there are bytes to read or the source is definitely exhausted. - */ - boolean exhausted() throws IOException; - - /** - * Returns when the buffer contains at least {@code byteCount} bytes. Throws - * an {@link java.io.EOFException} if the source is exhausted before the - * required bytes can be read. - */ - void require(long byteCount) throws IOException; - - /** Removes a byte from this source and returns it. */ - byte readByte() throws IOException; - - /** Removes two bytes from this source and returns a big-endian short. */ - short readShort() throws IOException; - - /** Removes two bytes from this source and returns a little-endian short. */ - short readShortLe() throws IOException; - - /** Removes four bytes from this source and returns a big-endian int. */ - int readInt() throws IOException; - - /** Removes four bytes from this source and returns a little-endian int. */ - int readIntLe() throws IOException; - - /** Removes eight bytes from this source and returns a big-endian long. */ - long readLong() throws IOException; - - /** Removes eight bytes from this source and returns a little-endian long. */ - long readLongLe() throws IOException; - - /** - * Reads and discards {@code byteCount} bytes from this source. Throws an - * {@link java.io.EOFException} if the source is exhausted before the - * requested bytes can be skipped. - */ - void skip(long byteCount) throws IOException; - - /** Removes {@code byteCount} bytes from this and returns them as a byte string. */ - ByteString readByteString(long byteCount) throws IOException; - - /** - * Removes {@code byteCount} bytes from this, decodes them as UTF-8 and - * returns the string. - */ - String readUtf8(long byteCount) throws IOException; - - /** - * Removes and returns characters up to but not including the next line break. - * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are - * not included in the result. - * - *

On the end of the stream this method returns null, just - * like {@link java.io.BufferedReader}. If the source doesn't end with a line - * break then an implicit line break is assumed. Null is returned once the - * source is exhausted. Use this for human-generated data, where a trailing - * line break is optional. - */ - String readUtf8Line() throws IOException; - - /** - * Removes and returns characters up to but not including the next line break. - * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are - * not included in the result. - * - *

On the end of the stream this method throws. Every call - * must consume either '\r\n' or '\n'. If these characters are absent in the - * stream, an {@link java.io.EOFException} is thrown. Use this for - * machine-generated data where a missing line break implies truncated input. - */ - String readUtf8LineStrict() throws IOException; - - /** - * Returns the index of {@code b} in the buffer, refilling it if necessary - * until it is found. This reads an unbounded number of bytes into the buffer. - * Returns -1 if the stream is exhausted before the requested byte is found. - */ - long indexOf(byte b) throws IOException; - - /** Returns an input stream that reads from this source. */ - InputStream inputStream(); -} diff --git a/okio/src/main/java/okio/ByteString.java b/okio/src/main/java/okio/ByteString.java deleted file mode 100644 index 6853adb09..000000000 --- a/okio/src/main/java/okio/ByteString.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2014 Square Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -/** - * An immutable sequence of bytes. - * - *

Full disclosure: this class provides untrusted input and - * output streams with raw access to the underlying byte array. A hostile - * stream implementation could keep a reference to the mutable byte string, - * violating the immutable guarantee of this class. For this reason a byte - * string's immutability guarantee cannot be relied upon for security in applets - * and other environments that run both trusted and untrusted code in the same - * process. - */ -public final class ByteString { - private static final char[] HEX_DIGITS = - { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - /** A singleton empty {@code ByteString}. */ - public static final ByteString EMPTY = ByteString.of(); - - final byte[] data; - private transient int hashCode; // Lazily computed; 0 if unknown. - private transient String utf8; // Lazily computed. - - ByteString(byte[] data) { - this.data = data; // Trusted internal constructor doesn't clone data. - } - - /** - * Returns a new byte string containing a clone of the bytes of {@code data}. - */ - public static ByteString of(byte... data) { - return new ByteString(data.clone()); - } - - /** Returns a new byte string containing the {@code UTF-8} bytes of {@code s}. */ - public static ByteString encodeUtf8(String s) { - ByteString byteString = new ByteString(s.getBytes(Util.UTF_8)); - byteString.utf8 = s; - return byteString; - } - - /** Constructs a new {@code String} by decoding the bytes as {@code UTF-8}. */ - public String utf8() { - String result = utf8; - // We don't care if we double-allocate in racy code. - return result != null ? result : (utf8 = new String(data, Util.UTF_8)); - } - - /** - * Returns this byte string encoded as Base64. In violation of the - * RFC, the returned string does not wrap lines at 76 columns. - */ - public String base64() { - return Base64.encode(data); - } - - /** - * Decodes the Base64-encoded bytes and returns their value as a byte string. - * Returns null if {@code base64} is not a Base64-encoded sequence of bytes. - */ - public static ByteString decodeBase64(String base64) { - byte[] decoded = Base64.decode(base64); - return decoded != null ? new ByteString(decoded) : null; - } - - /** Returns this byte string encoded in hexadecimal. */ - public String hex() { - char[] result = new char[data.length * 2]; - int c = 0; - for (byte b : data) { - result[c++] = HEX_DIGITS[(b >> 4) & 0xf]; - result[c++] = HEX_DIGITS[b & 0xf]; - } - return new String(result); - } - - /** Decodes the hex-encoded bytes and returns their value a byte string. */ - public static ByteString decodeHex(String hex) { - if (hex.length() % 2 != 0) throw new IllegalArgumentException("Unexpected hex string: " + hex); - - byte[] result = new byte[hex.length() / 2]; - for (int i = 0; i < result.length; i++) { - int d1 = decodeHexDigit(hex.charAt(i * 2)) << 4; - int d2 = decodeHexDigit(hex.charAt(i * 2 + 1)); - result[i] = (byte) (d1 + d2); - } - return of(result); - } - - private static int decodeHexDigit(char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - throw new IllegalArgumentException("Unexpected hex digit: " + c); - } - - /** - * Reads {@code count} bytes from {@code in} and returns the result. - * - * @throws java.io.EOFException if {@code in} has fewer than {@code count} - * bytes to read. - */ - public static ByteString read(InputStream in, int byteCount) throws IOException { - byte[] result = new byte[byteCount]; - for (int offset = 0, read; offset < byteCount; offset += read) { - read = in.read(result, offset, byteCount - offset); - if (read == -1) throw new EOFException(); - } - return new ByteString(result); - } - - /** - * Returns a byte string equal to this byte string, but with the bytes 'A' - * through 'Z' replaced with the corresponding byte in 'a' through 'z'. - * Returns this byte string if it contains no bytes in 'A' through 'Z'. - */ - public ByteString toAsciiLowercase() { - // Search for an uppercase character. If we don't find one, return this. - for (int i = 0; i < data.length; i++) { - byte c = data[i]; - if (c < 'A' || c > 'Z') continue; - - // If we reach this point, this string is not not lowercase. Create and - // return a new byte string. - byte[] lowercase = data.clone(); - lowercase[i++] = (byte) (c - ('A' - 'a')); - for (; i < lowercase.length; i++) { - c = lowercase[i]; - if (c < 'A' || c > 'Z') continue; - lowercase[i] = (byte) (c - ('A' - 'a')); - } - return new ByteString(lowercase); - } - return this; - } - - /** Returns the byte at {@code pos}. */ - public byte getByte(int pos) { - return data[pos]; - } - - /** - * Returns the number of bytes in this ByteString. - */ - public int size() { - return data.length; - } - - /** - * Returns a byte array containing a copy of the bytes in this {@code ByteString}. - */ - public byte[] toByteArray() { - return data.clone(); - } - - /** Writes the contents of this byte string to {@code out}. */ - public void write(OutputStream out) throws IOException { - out.write(data); - } - - @Override public boolean equals(Object o) { - return o == this || o instanceof ByteString && Arrays.equals(((ByteString) o).data, data); - } - - @Override public int hashCode() { - int result = hashCode; - return result != 0 ? result : (hashCode = Arrays.hashCode(data)); - } - - @Override public String toString() { - if (data.length == 0) { - return "ByteString[size=0]"; - } - - if (data.length <= 16) { - return String.format("ByteString[size=%s data=%s]", data.length, hex()); - } - - try { - return String.format("ByteString[size=%s md5=%s]", data.length, - ByteString.of(MessageDigest.getInstance("MD5").digest(data)).hex()); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(); - } - } -} diff --git a/okio/src/main/java/okio/Deadline.java b/okio/src/main/java/okio/Deadline.java deleted file mode 100644 index e5f951e65..000000000 --- a/okio/src/main/java/okio/Deadline.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.util.concurrent.TimeUnit; - -/** - * The time that a requested operation is due. If the deadline is reached before - * the operation has completed, the operation should be aborted. - */ -public class Deadline { - public static final Deadline NONE = new Deadline() { - @Override public Deadline start(long timeout, TimeUnit unit) { - throw new UnsupportedOperationException(); - } - - @Override public boolean reached() { - return false; - } - }; - - private long deadlineNanos; - - public Deadline() { - } - - public Deadline start(long timeout, TimeUnit unit) { - deadlineNanos = System.nanoTime() + unit.toNanos(timeout); - return this; - } - - public boolean reached() { - return System.nanoTime() - deadlineNanos >= 0; // Subtract to avoid overflow! - } - - public final void throwIfReached() throws IOException { - // TODO: a more catchable exception type? - if (reached()) throw new IOException("Deadline reached"); - - // If the thread is interrupted, do not proceed with further I/O. - if (Thread.interrupted()) throw new InterruptedIOException(); - } -} diff --git a/okio/src/main/java/okio/DeflaterSink.java b/okio/src/main/java/okio/DeflaterSink.java deleted file mode 100644 index ce7081de3..000000000 --- a/okio/src/main/java/okio/DeflaterSink.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.util.zip.Deflater; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; - -import static okio.Util.checkOffsetAndCount; - -/** - * A sink that uses DEFLATE to - * compress data written to another source. - * - *

Sync flush

- * Aggressive flushing of this stream may result in reduced compression. Each - * call to {@link #flush} immediately compresses all currently-buffered data; - * this early compression may be less effective than compression performed - * without flushing. - * - *

This is equivalent to using {@link Deflater} with the sync flush option. - * This class does not offer any partial flush mechanism. For best performance, - * only call {@link #flush} when application behavior requires it. - */ -public final class DeflaterSink implements Sink { - private final BufferedSink sink; - private final Deflater deflater; - private boolean closed; - - public DeflaterSink(Sink sink, Deflater deflater) { - this.sink = Okio.buffer(sink); - this.deflater = deflater; - } - - @Override public void write(OkBuffer source, long byteCount) - throws IOException { - checkOffsetAndCount(source.size, 0, byteCount); - while (byteCount > 0) { - // Share bytes from the head segment of 'source' with the deflater. - Segment head = source.head; - int toDeflate = (int) Math.min(byteCount, head.limit - head.pos); - deflater.setInput(head.data, head.pos, toDeflate); - - // Deflate those bytes into sink. - deflate(false); - - // Mark those bytes as read. - source.size -= toDeflate; - head.pos += toDeflate; - if (head.pos == head.limit) { - source.head = head.pop(); - SegmentPool.INSTANCE.recycle(head); - } - - byteCount -= toDeflate; - } - } - - @IgnoreJRERequirement - private void deflate(boolean syncFlush) throws IOException { - OkBuffer buffer = sink.buffer(); - while (true) { - Segment s = buffer.writableSegment(1); - - // The 4-parameter overload of deflate() doesn't exist in the RI until - // Java 1.7, and is public (although with @hide) on Android since 2.3. - // The @hide tag means that this code won't compile against the Android - // 2.3 SDK, but it will run fine there. - int deflated = syncFlush - ? deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit, Deflater.SYNC_FLUSH) - : deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit); - - if (deflated > 0) { - s.limit += deflated; - buffer.size += deflated; - sink.emitCompleteSegments(); - } else if (deflater.needsInput()) { - return; - } - } - } - - @Override public void flush() throws IOException { - deflate(true); - sink.flush(); - } - - @Override public void close() throws IOException { - if (closed) return; - - // Emit deflated data to the underlying sink. If this fails, we still need - // to close the deflater and the sink; otherwise we risk leaking resources. - Throwable thrown = null; - try { - deflater.finish(); - deflate(false); - } catch (Throwable e) { - thrown = e; - } - - try { - deflater.end(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - - try { - sink.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - closed = true; - - if (thrown != null) Util.sneakyRethrow(thrown); - } - - @Override public Sink deadline(Deadline deadline) { - sink.deadline(deadline); - return this; - } - - @Override public String toString() { - return "DeflaterSink(" + sink + ")"; - } -} diff --git a/okio/src/main/java/okio/GzipSource.java b/okio/src/main/java/okio/GzipSource.java deleted file mode 100644 index eae3a1645..000000000 --- a/okio/src/main/java/okio/GzipSource.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.util.zip.CRC32; -import java.util.zip.Inflater; - -public final class GzipSource implements Source { - private static final byte FHCRC = 1; - private static final byte FEXTRA = 2; - private static final byte FNAME = 3; - private static final byte FCOMMENT = 4; - - private static final byte SECTION_HEADER = 0; - private static final byte SECTION_BODY = 1; - private static final byte SECTION_TRAILER = 2; - private static final byte SECTION_DONE = 3; - - /** The current section. Always progresses forward. */ - private int section = SECTION_HEADER; - - /** - * Our source should yield a GZIP header (which we consume directly), followed - * by deflated bytes (which we consume via an InflaterSource), followed by a - * GZIP trailer (which we also consume directly). - */ - private final BufferedSource source; - - /** The inflater used to decompress the deflated body. */ - private final Inflater inflater; - - /** - * The inflater source takes care of moving data between compressed source and - * decompressed sink buffers. - */ - private final InflaterSource inflaterSource; - - /** Checksum used to check both the GZIP header and decompressed body. */ - private final CRC32 crc = new CRC32(); - - public GzipSource(Source source) throws IOException { - this.inflater = new Inflater(true); - this.source = Okio.buffer(source); - this.inflaterSource = new InflaterSource(this.source, inflater); - } - - @Override public long read(OkBuffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (byteCount == 0) return 0; - - // If we haven't consumed the header, we must consume it before anything else. - if (section == SECTION_HEADER) { - consumeHeader(); - section = SECTION_BODY; - } - - // Attempt to read at least a byte of the body. If we do, we're done. - if (section == SECTION_BODY) { - long offset = sink.size; - long result = inflaterSource.read(sink, byteCount); - if (result != -1) { - updateCrc(sink, offset, result); - return result; - } - section = SECTION_TRAILER; - } - - // The body is exhausted; time to read the trailer. We always consume the - // trailer before returning a -1 exhausted result; that way if you read to - // the end of a GzipSource you guarantee that the CRC has been checked. - if (section == SECTION_TRAILER) { - consumeTrailer(); - section = SECTION_DONE; - - // Gzip streams self-terminate: they return -1 before their underlying - // source returns -1. Here we attempt to force the underlying stream to - // return -1 which may trigger it to release its resources. If it doesn't - // return -1, then our Gzip data finished prematurely! - if (!source.exhausted()) { - throw new IOException("gzip finished without exhausting source"); - } - } - - return -1; - } - - private void consumeHeader() throws IOException { - // Read the 10-byte header. We peek at the flags byte first so we know if we - // need to CRC the entire header. Then we read the magic ID1ID2 sequence. - // We can skip everything else in the first 10 bytes. - // +---+---+---+---+---+---+---+---+---+---+ - // |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) - // +---+---+---+---+---+---+---+---+---+---+ - source.require(10); - byte flags = source.buffer().getByte(3); - boolean fhcrc = ((flags >> FHCRC) & 1) == 1; - if (fhcrc) updateCrc(source.buffer(), 0, 10); - - short id1id2 = source.readShort(); - checkEqual("ID1ID2", (short) 0x1f8b, id1id2); - source.skip(8); - - // Skip optional extra fields. - // +---+---+=================================+ - // | XLEN |...XLEN bytes of "extra field"...| (more-->) - // +---+---+=================================+ - if (((flags >> FEXTRA) & 1) == 1) { - source.require(2); - if (fhcrc) updateCrc(source.buffer(), 0, 2); - int xlen = source.buffer().readShortLe(); - source.require(xlen); - if (fhcrc) updateCrc(source.buffer(), 0, xlen); - source.skip(xlen); - } - - // Skip an optional 0-terminated name. - // +=========================================+ - // |...original file name, zero-terminated...| (more-->) - // +=========================================+ - if (((flags >> FNAME) & 1) == 1) { - long index = source.indexOf((byte) 0); - if (index == -1) throw new EOFException(); - if (fhcrc) updateCrc(source.buffer(), 0, index + 1); - source.skip(index + 1); - } - - // Skip an optional 0-terminated comment. - // +===================================+ - // |...file comment, zero-terminated...| (more-->) - // +===================================+ - if (((flags >> FCOMMENT) & 1) == 1) { - long index = source.indexOf((byte) 0); - if (index == -1) throw new EOFException(); - if (fhcrc) updateCrc(source.buffer(), 0, index + 1); - source.skip(index + 1); - } - - // Confirm the optional header CRC. - // +---+---+ - // | CRC16 | - // +---+---+ - if (fhcrc) { - checkEqual("FHCRC", source.readShortLe(), (short) crc.getValue()); - crc.reset(); - } - } - - private void consumeTrailer() throws IOException { - // Read the eight-byte trailer. Confirm the body's CRC and size. - // +---+---+---+---+---+---+---+---+ - // | CRC32 | ISIZE | - // +---+---+---+---+---+---+---+---+ - checkEqual("CRC", source.readIntLe(), (int) crc.getValue()); - checkEqual("ISIZE", source.readIntLe(), inflater.getTotalOut()); - } - - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; - } - - @Override public void close() throws IOException { - inflaterSource.close(); - } - - /** Updates the CRC with the given bytes. */ - private void updateCrc(OkBuffer buffer, long offset, long byteCount) { - for (Segment s = buffer.head; byteCount > 0; s = s.next) { - int segmentByteCount = s.limit - s.pos; - if (offset < segmentByteCount) { - int toUpdate = (int) Math.min(byteCount, segmentByteCount - offset); - crc.update(s.data, (int) (s.pos + offset), toUpdate); - byteCount -= toUpdate; - } - offset -= segmentByteCount; // Track the offset of the current segment. - } - } - - private void checkEqual(String name, int expected, int actual) throws IOException { - if (actual != expected) { - throw new IOException(String.format( - "%s: actual 0x%08x != expected 0x%08x", name, actual, expected)); - } - } -} diff --git a/okio/src/main/java/okio/InflaterSource.java b/okio/src/main/java/okio/InflaterSource.java deleted file mode 100644 index c86c9959a..000000000 --- a/okio/src/main/java/okio/InflaterSource.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -/** - * A source that uses DEFLATE - * to decompress data read from another source. - */ -public final class InflaterSource implements Source { - private final BufferedSource source; - private final Inflater inflater; - - /** - * When we call Inflater.setInput(), the inflater keeps our byte array until - * it needs input again. This tracks how many bytes the inflater is currently - * holding on to. - */ - private int bufferBytesHeldByInflater; - private boolean closed; - - public InflaterSource(Source source, Inflater inflater) { - this(Okio.buffer(source), inflater); - } - - /** - * This package-private constructor shares a buffer with its trusted caller. - * In general we can't share a BufferedSource because the inflater holds input - * bytes until they are inflated. - */ - InflaterSource(BufferedSource source, Inflater inflater) { - if (source == null) throw new IllegalArgumentException("source == null"); - if (inflater == null) throw new IllegalArgumentException("inflater == null"); - this.source = source; - this.inflater = inflater; - } - - @Override public long read( - OkBuffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (closed) throw new IllegalStateException("closed"); - if (byteCount == 0) return 0; - - while (true) { - boolean sourceExhausted = refill(); - - // Decompress the inflater's compressed data into the sink. - try { - Segment tail = sink.writableSegment(1); - int bytesInflated = inflater.inflate(tail.data, tail.limit, Segment.SIZE - tail.limit); - if (bytesInflated > 0) { - tail.limit += bytesInflated; - sink.size += bytesInflated; - return bytesInflated; - } - if (inflater.finished() || inflater.needsDictionary()) { - releaseInflatedBytes(); - return -1; - } - if (sourceExhausted) throw new EOFException("source exhausted prematurely"); - } catch (DataFormatException e) { - throw new IOException(e); - } - } - } - - /** - * Refills the inflater with compressed data if it needs input. (And only if - * it needs input). Returns true if the inflater required input but the source - * was exhausted. - */ - public boolean refill() throws IOException { - if (!inflater.needsInput()) return false; - - releaseInflatedBytes(); - if (inflater.getRemaining() != 0) throw new IllegalStateException("?"); // TODO: possible? - - // If there are compressed bytes in the source, assign them to the inflater. - if (source.exhausted()) return true; - - // Assign buffer bytes to the inflater. - Segment head = source.buffer().head; - bufferBytesHeldByInflater = head.limit - head.pos; - inflater.setInput(head.data, head.pos, bufferBytesHeldByInflater); - return false; - } - - /** When the inflater has processed compressed data, remove it from the buffer. */ - private void releaseInflatedBytes() throws IOException { - if (bufferBytesHeldByInflater == 0) return; - int toRelease = bufferBytesHeldByInflater - inflater.getRemaining(); - bufferBytesHeldByInflater -= toRelease; - source.skip(toRelease); - } - - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; - } - - @Override public void close() throws IOException { - if (closed) return; - inflater.end(); - closed = true; - source.close(); - } -} diff --git a/okio/src/main/java/okio/OkBuffer.java b/okio/src/main/java/okio/OkBuffer.java deleted file mode 100644 index 8dc4290c2..000000000 --- a/okio/src/main/java/okio/OkBuffer.java +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static okio.Util.UTF_8; -import static okio.Util.checkOffsetAndCount; -import static okio.Util.reverseBytesLong; - -/** - * A collection of bytes in memory. - * - *

Moving data from one OkBuffer to another is fast. Instead - * of copying bytes from one place in memory to another, this class just changes - * ownership of the underlying byte arrays. - * - *

This buffer grows with your data. Just like ArrayList, - * each OkBuffer starts small. It consumes only the memory it needs to. - * - *

This buffer pools its byte arrays. When you allocate a - * byte array in Java, the runtime must zero-fill the requested array before - * returning it to you. Even if you're going to write over that space anyway. - * This class avoids zero-fill and GC churn by pooling byte arrays. - */ -public final class OkBuffer implements BufferedSource, BufferedSink, Cloneable { - Segment head; - long size; - - public OkBuffer() { - } - - /** Returns the number of bytes currently in this buffer. */ - public long size() { - return size; - } - - @Override public OkBuffer buffer() { - return this; - } - - @Override public OutputStream outputStream() { - return new OutputStream() { - @Override public void write(int b) { - writeByte((byte) b); - } - - @Override public void write(byte[] data, int offset, int byteCount) { - OkBuffer.this.write(data, offset, byteCount); - } - - @Override public void flush() { - } - - @Override public void close() { - } - - @Override public String toString() { - return this + ".outputStream()"; - } - }; - } - - @Override public OkBuffer emitCompleteSegments() { - return this; // Nowhere to emit to! - } - - @Override public boolean exhausted() { - return size == 0; - } - - @Override public void require(long byteCount) throws EOFException { - if (this.size < byteCount) throw new EOFException(); - } - - @Override public InputStream inputStream() { - return new InputStream() { - @Override public int read() { - return readByte() & 0xff; - } - - @Override public int read(byte[] sink, int offset, int byteCount) { - return OkBuffer.this.read(sink, offset, byteCount); - } - - @Override public int available() { - return (int) Math.min(size, Integer.MAX_VALUE); - } - - @Override public void close() { - } - - @Override public String toString() { - return OkBuffer.this + ".inputStream()"; - } - }; - } - - /** - * Returns the number of bytes in segments that are not writable. This is the - * number of bytes that can be flushed immediately to an underlying sink - * without harming throughput. - */ - public long completeSegmentByteCount() { - long result = size; - if (result == 0) return 0; - - // Omit the tail if it's still writable. - Segment tail = head.prev; - if (tail.limit < Segment.SIZE) { - result -= tail.limit - tail.pos; - } - - return result; - } - - @Override public byte readByte() { - if (size == 0) throw new IllegalStateException("size == 0"); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - byte[] data = segment.data; - byte b = data[pos++]; - size -= 1; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return b; - } - - /** Returns the byte at {@code pos}. */ - public byte getByte(long pos) { - checkOffsetAndCount(size, pos, 1); - for (Segment s = head; true; s = s.next) { - int segmentByteCount = s.limit - s.pos; - if (pos < segmentByteCount) return s.data[s.pos + (int) pos]; - pos -= segmentByteCount; - } - } - - @Override public short readShort() { - if (size < 2) throw new IllegalStateException("size < 2: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the short is split across multiple segments, delegate to readByte(). - if (limit - pos < 2) { - int s = (readByte() & 0xff) << 8 - | (readByte() & 0xff); - return (short) s; - } - - byte[] data = segment.data; - int s = (data[pos++] & 0xff) << 8 - | (data[pos++] & 0xff); - size -= 2; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return (short) s; - } - - @Override public int readInt() { - if (size < 4) throw new IllegalStateException("size < 4: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the int is split across multiple segments, delegate to readByte(). - if (limit - pos < 4) { - return (readByte() & 0xff) << 24 - | (readByte() & 0xff) << 16 - | (readByte() & 0xff) << 8 - | (readByte() & 0xff); - } - - byte[] data = segment.data; - int i = (data[pos++] & 0xff) << 24 - | (data[pos++] & 0xff) << 16 - | (data[pos++] & 0xff) << 8 - | (data[pos++] & 0xff); - size -= 4; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return i; - } - - @Override public long readLong() { - if (size < 8) throw new IllegalStateException("size < 8: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the long is split across multiple segments, delegate to readInt(). - if (limit - pos < 8) { - return (readInt() & 0xffffffffL) << 32 - | (readInt() & 0xffffffffL); - } - - byte[] data = segment.data; - long v = (data[pos++] & 0xffL) << 56 - | (data[pos++] & 0xffL) << 48 - | (data[pos++] & 0xffL) << 40 - | (data[pos++] & 0xffL) << 32 - | (data[pos++] & 0xffL) << 24 - | (data[pos++] & 0xffL) << 16 - | (data[pos++] & 0xffL) << 8 - | (data[pos++] & 0xffL); - size -= 8; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return v; - } - - @Override public short readShortLe() { - return Util.reverseBytesShort(readShort()); - } - - @Override public int readIntLe() { - return Util.reverseBytesInt(readInt()); - } - - @Override public long readLongLe() { - return Util.reverseBytesLong(readLong()); - } - - @Override public ByteString readByteString(long byteCount) { - return new ByteString(readBytes(byteCount)); - } - - @Override public String readUtf8(long byteCount) { - checkOffsetAndCount(this.size, 0, byteCount); - if (byteCount > Integer.MAX_VALUE) { - throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount); - } - if (byteCount == 0) return ""; - - Segment head = this.head; - if (head.pos + byteCount > head.limit) { - // If the string spans multiple segments, delegate to readBytes(). - return new String(readBytes(byteCount), Util.UTF_8); - } - - String result = new String(head.data, head.pos, (int) byteCount, UTF_8); - head.pos += byteCount; - this.size -= byteCount; - - if (head.pos == head.limit) { - this.head = head.pop(); - SegmentPool.INSTANCE.recycle(head); - } - - return result; - } - - @Override public String readUtf8Line() throws IOException { - long newline = indexOf((byte) '\n'); - - if (newline == -1) { - return size != 0 ? readUtf8(size) : null; - } - - return readUtf8Line(newline); - } - - @Override public String readUtf8LineStrict() throws IOException { - long newline = indexOf((byte) '\n'); - if (newline == -1) throw new EOFException(); - return readUtf8Line(newline); - } - - String readUtf8Line(long newline) { - if (newline > 0 && getByte(newline - 1) == '\r') { - // Read everything until '\r\n', then skip the '\r\n'. - String result = readUtf8((newline - 1)); - skip(2); - return result; - - } else { - // Read everything until '\n', then skip the '\n'. - String result = readUtf8(newline); - skip(1); - return result; - } - } - - private byte[] readBytes(long byteCount) { - checkOffsetAndCount(this.size, 0, byteCount); - if (byteCount > Integer.MAX_VALUE) { - throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount); - } - - int offset = 0; - byte[] result = new byte[(int) byteCount]; - - while (offset < byteCount) { - int toCopy = (int) Math.min(byteCount - offset, head.limit - head.pos); - System.arraycopy(head.data, head.pos, result, offset, toCopy); - - offset += toCopy; - head.pos += toCopy; - - if (head.pos == head.limit) { - Segment toRecycle = head; - head = toRecycle.pop(); - SegmentPool.INSTANCE.recycle(toRecycle); - } - } - - this.size -= byteCount; - return result; - } - - /** Like {@link InputStream#read}. */ - int read(byte[] sink, int offset, int byteCount) { - Segment s = this.head; - if (s == null) return -1; - int toCopy = Math.min(byteCount, s.limit - s.pos); - System.arraycopy(s.data, s.pos, sink, offset, toCopy); - - s.pos += toCopy; - this.size -= toCopy; - - if (s.pos == s.limit) { - this.head = s.pop(); - SegmentPool.INSTANCE.recycle(s); - } - - return toCopy; - } - - /** - * Discards all bytes in this buffer. Calling this method when you're done - * with a buffer will return its segments to the pool. - */ - public void clear() { - skip(size); - } - - /** Discards {@code byteCount} bytes from the head of this buffer. */ - @Override public void skip(long byteCount) { - checkOffsetAndCount(this.size, 0, byteCount); - - this.size -= byteCount; - while (byteCount > 0) { - int toSkip = (int) Math.min(byteCount, head.limit - head.pos); - byteCount -= toSkip; - head.pos += toSkip; - - if (head.pos == head.limit) { - Segment toRecycle = head; - head = toRecycle.pop(); - SegmentPool.INSTANCE.recycle(toRecycle); - } - } - } - - @Override public OkBuffer write(ByteString byteString) { - return write(byteString.data, 0, byteString.data.length); - } - - @Override public OkBuffer writeUtf8(String string) { - // TODO: inline UTF-8 encoding to save allocating a byte[]? - byte[] data = string.getBytes(Util.UTF_8); - return write(data, 0, data.length); - } - - @Override public OkBuffer write(byte[] source) { - return write(source, 0, source.length); - } - - @Override public OkBuffer write(byte[] source, int offset, int byteCount) { - int limit = offset + byteCount; - while (offset < limit) { - Segment tail = writableSegment(1); - - int toCopy = Math.min(limit - offset, Segment.SIZE - tail.limit); - System.arraycopy(source, offset, tail.data, tail.limit, toCopy); - - offset += toCopy; - tail.limit += toCopy; - } - - this.size += byteCount; - return this; - } - - @Override public OkBuffer writeByte(int b) { - Segment tail = writableSegment(1); - tail.data[tail.limit++] = (byte) b; - size += 1; - return this; - } - - @Override public OkBuffer writeShort(int s) { - Segment tail = writableSegment(2); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((s >>> 8) & 0xff); - data[limit++] = (byte) (s & 0xff); - tail.limit = limit; - size += 2; - return this; - } - - @Override public BufferedSink writeShortLe(int s) { - return writeShort(Util.reverseBytesShort((short) s)); - } - - @Override public OkBuffer writeInt(int i) { - Segment tail = writableSegment(4); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((i >>> 24) & 0xff); - data[limit++] = (byte) ((i >>> 16) & 0xff); - data[limit++] = (byte) ((i >>> 8) & 0xff); - data[limit++] = (byte) (i & 0xff); - tail.limit = limit; - size += 4; - return this; - } - - @Override public BufferedSink writeIntLe(int i) { - return writeInt(Util.reverseBytesInt(i)); - } - - @Override public OkBuffer writeLong(long v) { - Segment tail = writableSegment(8); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((v >>> 56L) & 0xff); - data[limit++] = (byte) ((v >>> 48L) & 0xff); - data[limit++] = (byte) ((v >>> 40L) & 0xff); - data[limit++] = (byte) ((v >>> 32L) & 0xff); - data[limit++] = (byte) ((v >>> 24L) & 0xff); - data[limit++] = (byte) ((v >>> 16L) & 0xff); - data[limit++] = (byte) ((v >>> 8L) & 0xff); - data[limit++] = (byte) (v & 0xff); - tail.limit = limit; - size += 8; - return this; - } - - @Override public BufferedSink writeLongLe(long v) { - return writeLong(reverseBytesLong(v)); - } - - /** - * Returns a tail segment that we can write at least {@code minimumCapacity} - * bytes to, creating it if necessary. - */ - Segment writableSegment(int minimumCapacity) { - if (minimumCapacity < 1 || minimumCapacity > Segment.SIZE) throw new IllegalArgumentException(); - - if (head == null) { - head = SegmentPool.INSTANCE.take(); // Acquire a first segment. - return head.next = head.prev = head; - } - - Segment tail = head.prev; - if (tail.limit + minimumCapacity > Segment.SIZE) { - tail = tail.push(SegmentPool.INSTANCE.take()); // Append a new empty segment to fill up. - } - return tail; - } - - @Override public void write(OkBuffer source, long byteCount) { - // Move bytes from the head of the source buffer to the tail of this buffer - // while balancing two conflicting goals: don't waste CPU and don't waste - // memory. - // - // - // Don't waste CPU (ie. don't copy data around). - // - // Copying large amounts of data is expensive. Instead, we prefer to - // reassign entire segments from one OkBuffer to the other. - // - // - // Don't waste memory. - // - // As an invariant, adjacent pairs of segments in an OkBuffer should be at - // least 50% full, except for the head segment and the tail segment. - // - // The head segment cannot maintain the invariant because the application is - // consuming bytes from this segment, decreasing its level. - // - // The tail segment cannot maintain the invariant because the application is - // producing bytes, which may require new nearly-empty tail segments to be - // appended. - // - // - // Moving segments between buffers - // - // When writing one buffer to another, we prefer to reassign entire segments - // over copying bytes into their most compact form. Suppose we have a buffer - // with these segment levels [91%, 61%]. If we append a buffer with a - // single [72%] segment, that yields [91%, 61%, 72%]. No bytes are copied. - // - // Or suppose we have a buffer with these segment levels: [100%, 2%], and we - // want to append it to a buffer with these segment levels [99%, 3%]. This - // operation will yield the following segments: [100%, 2%, 99%, 3%]. That - // is, we do not spend time copying bytes around to achieve more efficient - // memory use like [100%, 100%, 4%]. - // - // When combining buffers, we will compact adjacent buffers when their - // combined level doesn't exceed 100%. For example, when we start with - // [100%, 40%] and append [30%, 80%], the result is [100%, 70%, 80%]. - // - // - // Splitting segments - // - // Occasionally we write only part of a source buffer to a sink buffer. For - // example, given a sink [51%, 91%], we may want to write the first 30% of - // a source [92%, 82%] to it. To simplify, we first transform the source to - // an equivalent buffer [30%, 62%, 82%] and then move the head segment, - // yielding sink [51%, 91%, 30%] and source [62%, 82%]. - - if (source == this) { - throw new IllegalArgumentException("source == this"); - } - checkOffsetAndCount(source.size, 0, byteCount); - - while (byteCount > 0) { - // Is a prefix of the source's head segment all that we need to move? - if (byteCount < (source.head.limit - source.head.pos)) { - Segment tail = head != null ? head.prev : null; - if (tail == null || byteCount + (tail.limit - tail.pos) > Segment.SIZE) { - // We're going to need another segment. Split the source's head - // segment in two, then move the first of those two to this buffer. - source.head = source.head.split((int) byteCount); - } else { - // Our existing segments are sufficient. Move bytes from source's head to our tail. - source.head.writeTo(tail, (int) byteCount); - source.size -= byteCount; - this.size += byteCount; - return; - } - } - - // Remove the source's head segment and append it to our tail. - Segment segmentToMove = source.head; - long movedByteCount = segmentToMove.limit - segmentToMove.pos; - source.head = segmentToMove.pop(); - if (head == null) { - head = segmentToMove; - head.next = head.prev = head; - } else { - Segment tail = head.prev; - tail = tail.push(segmentToMove); - tail.compact(); - } - source.size -= movedByteCount; - this.size += movedByteCount; - byteCount -= movedByteCount; - } - } - - @Override public long read(OkBuffer sink, long byteCount) { - if (this.size == 0) return -1L; - if (byteCount > this.size) byteCount = this.size; - sink.write(this, byteCount); - return byteCount; - } - - @Override public OkBuffer deadline(Deadline deadline) { - // All operations are in memory so this class doesn't need to honor deadlines. - return this; - } - - @Override public long indexOf(byte b) { - return indexOf(b, 0); - } - - /** - * Returns the index of {@code b} in this at or beyond {@code fromIndex}, or - * -1 if this buffer does not contain {@code b} in that range. - */ - public long indexOf(byte b, long fromIndex) { - Segment s = head; - if (s == null) return -1L; - long offset = 0L; - do { - int segmentByteCount = s.limit - s.pos; - if (fromIndex > segmentByteCount) { - fromIndex -= segmentByteCount; - } else { - byte[] data = s.data; - for (long pos = s.pos + fromIndex, limit = s.limit; pos < limit; pos++) { - if (data[(int) pos] == b) return offset + pos - s.pos; - } - fromIndex = 0; - } - offset += segmentByteCount; - s = s.next; - } while (s != head); - return -1L; - } - - @Override public void flush() { - } - - @Override public void close() { - } - - /** For testing. This returns the sizes of the segments in this buffer. */ - List segmentSizes() { - if (head == null) return Collections.emptyList(); - List result = new ArrayList(); - result.add(head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - result.add(s.limit - s.pos); - } - return result; - } - - @Override public boolean equals(Object o) { - if (!(o instanceof OkBuffer)) return false; - OkBuffer that = (OkBuffer) o; - if (size != that.size) return false; - if (size == 0) return true; // Both buffers are empty. - - Segment sa = this.head; - Segment sb = that.head; - int posA = sa.pos; - int posB = sb.pos; - - for (long pos = 0, count; pos < size; pos += count) { - count = Math.min(sa.limit - posA, sb.limit - posB); - - for (int i = 0; i < count; i++) { - if (sa.data[posA++] != sb.data[posB++]) return false; - } - - if (posA == sa.limit) { - sa = sa.next; - posA = sa.pos; - } - - if (posB == sb.limit) { - sb = sb.next; - posB = sb.pos; - } - } - - return true; - } - - @Override public int hashCode() { - Segment s = head; - if (s == null) return 0; - int result = 1; - do { - for (int pos = s.pos, limit = s.limit; pos < limit; pos++) { - result = 31 * result + s.data[pos]; - } - s = s.next; - } while (s != head); - return result; - } - - @Override public String toString() { - if (size == 0) { - return "OkBuffer[size=0]"; - } - - if (size <= 16) { - ByteString data = clone().readByteString(size); - return String.format("OkBuffer[size=%s data=%s]", size, data.hex()); - } - - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - md5.update(head.data, head.pos, head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - md5.update(s.data, s.pos, s.limit - s.pos); - } - return String.format("OkBuffer[size=%s md5=%s]", - size, ByteString.of(md5.digest()).hex()); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(); - } - } - - /** Returns a deep copy of this buffer. */ - @Override public OkBuffer clone() { - OkBuffer result = new OkBuffer(); - if (size() == 0) return result; - - result.write(head.data, head.pos, head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - result.write(s.data, s.pos, s.limit - s.pos); - } - - return result; - } -} diff --git a/okio/src/main/java/okio/Okio.java b/okio/src/main/java/okio/Okio.java deleted file mode 100644 index 3a9b4f9f8..000000000 --- a/okio/src/main/java/okio/Okio.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import static okio.Util.checkOffsetAndCount; - -public final class Okio { - private Okio() { - } - - public static BufferedSource buffer(Source source) { - return new RealBufferedSource(source); - } - - public static BufferedSink buffer(Sink sink) { - return new RealBufferedSink(sink); - } - - /** Copies bytes from {@code source} to {@code sink}. */ - public static void copy(OkBuffer source, long offset, long byteCount, OutputStream sink) - throws IOException { - checkOffsetAndCount(source.size, offset, byteCount); - - // Skip segments that we aren't copying from. - Segment s = source.head; - while (offset >= (s.limit - s.pos)) { - offset -= (s.limit - s.pos); - s = s.next; - } - - // Copy from one segment at a time. - while (byteCount > 0) { - int pos = (int) (s.pos + offset); - int toWrite = (int) Math.min(s.limit - pos, byteCount); - sink.write(s.data, pos, toWrite); - byteCount -= toWrite; - offset = 0; - } - } - - /** Returns a sink that writes to {@code out}. */ - public static Sink sink(final OutputStream out) { - return new Sink() { - private Deadline deadline = Deadline.NONE; - - @Override public void write(OkBuffer source, long byteCount) - throws IOException { - checkOffsetAndCount(source.size, 0, byteCount); - while (byteCount > 0) { - deadline.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.INSTANCE.recycle(head); - } - } - } - - @Override public void flush() throws IOException { - out.flush(); - } - - @Override public void close() throws IOException { - out.close(); - } - - @Override public Sink deadline(Deadline deadline) { - if (deadline == null) throw new IllegalArgumentException("deadline == null"); - this.deadline = deadline; - return this; - } - - @Override public String toString() { - return "sink(" + out + ")"; - } - }; - } - - /** Returns a source that reads from {@code in}. */ - public static Source source(final InputStream in) { - return new Source() { - private Deadline deadline = Deadline.NONE; - - @Override public long read(OkBuffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - deadline.throwIfReached(); - Segment tail = sink.writableSegment(1); - int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit); - int bytesRead = in.read(tail.data, tail.limit, maxToCopy); - if (bytesRead == -1) return -1; - tail.limit += bytesRead; - sink.size += bytesRead; - return bytesRead; - } - - @Override public void close() throws IOException { - in.close(); - } - - @Override public Source deadline(Deadline deadline) { - if (deadline == null) throw new IllegalArgumentException("deadline == null"); - this.deadline = deadline; - return this; - } - - @Override public String toString() { - return "source(" + in + ")"; - } - }; - } -} diff --git a/okio/src/main/java/okio/RealBufferedSink.java b/okio/src/main/java/okio/RealBufferedSink.java deleted file mode 100644 index 74454c60c..000000000 --- a/okio/src/main/java/okio/RealBufferedSink.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.OutputStream; - -final class RealBufferedSink implements BufferedSink { - public final OkBuffer buffer; - public final Sink sink; - private boolean closed; - - public RealBufferedSink(Sink sink, OkBuffer buffer) { - if (sink == null) throw new IllegalArgumentException("sink == null"); - this.buffer = buffer; - this.sink = sink; - } - - public RealBufferedSink(Sink sink) { - this(sink, new OkBuffer()); - } - - @Override public OkBuffer buffer() { - return buffer; - } - - @Override public void write(OkBuffer source, long byteCount) - throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source, byteCount); - emitCompleteSegments(); - } - - @Override public BufferedSink write(ByteString byteString) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(byteString); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeUtf8(String string) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeUtf8(string); - return emitCompleteSegments(); - } - - @Override public BufferedSink write(byte[] source) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source); - return emitCompleteSegments(); - } - - @Override public BufferedSink write(byte[] source, int offset, int byteCount) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source, offset, byteCount); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeByte(int b) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeByte(b); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeShort(int s) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeShort(s); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeShortLe(int s) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeShortLe(s); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeInt(int i) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeInt(i); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeIntLe(int i) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeIntLe(i); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeLong(long v) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeLong(v); - return emitCompleteSegments(); - } - - @Override public BufferedSink writeLongLe(long v) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeLongLe(v); - return emitCompleteSegments(); - } - - @Override public BufferedSink emitCompleteSegments() throws IOException { - if (closed) throw new IllegalStateException("closed"); - long byteCount = buffer.completeSegmentByteCount(); - if (byteCount > 0) sink.write(buffer, byteCount); - return this; - } - - @Override public OutputStream outputStream() { - return new OutputStream() { - @Override public void write(int b) throws IOException { - if (closed) throw new IOException("closed"); - buffer.writeByte((byte) b); - emitCompleteSegments(); - } - - @Override public void write(byte[] data, int offset, int byteCount) throws IOException { - if (closed) throw new IOException("closed"); - buffer.write(data, offset, byteCount); - emitCompleteSegments(); - } - - @Override public void flush() throws IOException { - // For backwards compatibility, a flush() on a closed stream is a no-op. - if (!closed) { - RealBufferedSink.this.flush(); - } - } - - @Override public void close() throws IOException { - RealBufferedSink.this.close(); - } - - @Override public String toString() { - return RealBufferedSink.this + ".outputStream()"; - } - }; - } - - @Override public void flush() throws IOException { - if (closed) throw new IllegalStateException("closed"); - if (buffer.size > 0) { - sink.write(buffer, buffer.size); - } - sink.flush(); - } - - @Override public void close() throws IOException { - if (closed) return; - - // Emit buffered data to the underlying sink. If this fails, we still need - // to close the sink; otherwise we risk leaking resources. - Throwable thrown = null; - try { - if (buffer.size > 0) { - sink.write(buffer, buffer.size); - } - } catch (Throwable e) { - thrown = e; - } - - try { - sink.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - closed = true; - - if (thrown != null) Util.sneakyRethrow(thrown); - } - - @Override public Sink deadline(Deadline deadline) { - sink.deadline(deadline); - return this; - } - - @Override public String toString() { - return "buffer(" + sink + ")"; - } -} diff --git a/okio/src/main/java/okio/RealBufferedSource.java b/okio/src/main/java/okio/RealBufferedSource.java deleted file mode 100644 index 0189d0f7f..000000000 --- a/okio/src/main/java/okio/RealBufferedSource.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -import static okio.Util.checkOffsetAndCount; - -final class RealBufferedSource implements BufferedSource { - public final OkBuffer buffer; - public final Source source; - private boolean closed; - - public RealBufferedSource(Source source, OkBuffer buffer) { - if (source == null) throw new IllegalArgumentException("source == null"); - this.buffer = buffer; - this.source = source; - } - - public RealBufferedSource(Source source) { - this(source, new OkBuffer()); - } - - @Override public OkBuffer buffer() { - return buffer; - } - - @Override public long read(OkBuffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (closed) throw new IllegalStateException("closed"); - - if (buffer.size == 0) { - long read = source.read(buffer, Segment.SIZE); - if (read == -1) return -1; - } - - long toRead = Math.min(byteCount, buffer.size); - return buffer.read(sink, toRead); - } - - @Override public boolean exhausted() throws IOException { - if (closed) throw new IllegalStateException("closed"); - return buffer.exhausted() && source.read(buffer, Segment.SIZE) == -1; - } - - @Override public void require(long byteCount) throws IOException { - if (closed) throw new IllegalStateException("closed"); - while (buffer.size < byteCount) { - if (source.read(buffer, Segment.SIZE) == -1) throw new EOFException(); - } - } - - @Override public byte readByte() throws IOException { - require(1); - return buffer.readByte(); - } - - @Override public ByteString readByteString(long byteCount) throws IOException { - require(byteCount); - return buffer.readByteString(byteCount); - } - - @Override public String readUtf8(long byteCount) throws IOException { - require(byteCount); - return buffer.readUtf8(byteCount); - } - - @Override public String readUtf8Line() throws IOException { - long newline = indexOf((byte) '\n'); - - if (newline == -1) { - return buffer.size != 0 ? readUtf8(buffer.size) : null; - } - - return buffer.readUtf8Line(newline); - } - - @Override public String readUtf8LineStrict() throws IOException { - long newline = indexOf((byte) '\n'); - if (newline == -1L) throw new EOFException(); - return buffer.readUtf8Line(newline); - } - - @Override public short readShort() throws IOException { - require(2); - return buffer.readShort(); - } - - @Override public short readShortLe() throws IOException { - require(2); - return buffer.readShortLe(); - } - - @Override public int readInt() throws IOException { - require(4); - return buffer.readInt(); - } - - @Override public int readIntLe() throws IOException { - require(4); - return buffer.readIntLe(); - } - - @Override public long readLong() throws IOException { - require(8); - return buffer.readLong(); - } - - @Override public long readLongLe() throws IOException { - require(8); - return buffer.readLongLe(); - } - - @Override public void skip(long byteCount) throws IOException { - if (closed) throw new IllegalStateException("closed"); - while (byteCount > 0) { - if (buffer.size == 0 && source.read(buffer, Segment.SIZE) == -1) { - throw new EOFException(); - } - long toSkip = Math.min(byteCount, buffer.size()); - buffer.skip(toSkip); - byteCount -= toSkip; - } - } - - @Override public long indexOf(byte b) throws IOException { - if (closed) throw new IllegalStateException("closed"); - long start = 0; - long index; - while ((index = buffer.indexOf(b, start)) == -1) { - start = buffer.size; - if (source.read(buffer, Segment.SIZE) == -1) return -1L; - } - return index; - } - - @Override public InputStream inputStream() { - return new InputStream() { - @Override public int read() throws IOException { - if (closed) throw new IOException("closed"); - if (buffer.size == 0) { - long count = source.read(buffer, Segment.SIZE); - if (count == -1) return -1; - } - return buffer.readByte() & 0xff; - } - - @Override public int read(byte[] data, int offset, int byteCount) throws IOException { - if (closed) throw new IOException("closed"); - checkOffsetAndCount(data.length, offset, byteCount); - - if (buffer.size == 0) { - long count = source.read(buffer, Segment.SIZE); - if (count == -1) return -1; - } - - return buffer.read(data, offset, byteCount); - } - - @Override public int available() throws IOException { - if (closed) throw new IOException("closed"); - return (int) Math.min(buffer.size, Integer.MAX_VALUE); - } - - @Override public void close() throws IOException { - RealBufferedSource.this.close(); - } - - @Override public String toString() { - return RealBufferedSource.this + ".inputStream()"; - } - }; - } - - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; - } - - @Override public void close() throws IOException { - if (closed) return; - closed = true; - source.close(); - buffer.clear(); - } - - @Override public String toString() { - return "buffer(" + source + ")"; - } -} diff --git a/okio/src/main/java/okio/Segment.java b/okio/src/main/java/okio/Segment.java deleted file mode 100644 index 77dbee186..000000000 --- a/okio/src/main/java/okio/Segment.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -/** - * A segment of an OkBuffer. - * - *

Each segment in an OkBuffer is a circularly-linked list node referencing - * the following and preceding segments in the buffer. - * - *

Each segment in the pool is a singly-linked list node referencing the rest - * of segments in the pool. - */ -final class Segment { - /** The size of all segments in bytes. */ - // TODO: Using fixed-size segments makes pooling easier. But it harms memory - // efficiency and encourages copying. Try variable sized segments? - // TODO: Is 2 KiB a good default segment size? - static final int SIZE = 2048; - - final byte[] data = new byte[SIZE]; - - /** The next byte of application data byte to read in this segment. */ - int pos; - - /** The first byte of available data ready to be written to. */ - int limit; - - /** Next segment in a linked or circularly-linked list. */ - Segment next; - - /** Previous segment in a circularly-linked list. */ - Segment prev; - - /** - * Removes this segment of a circularly-linked list and returns its successor. - * Returns null if the list is now empty. - */ - public Segment pop() { - Segment result = next != this ? next : null; - prev.next = next; - next.prev = prev; - next = null; - prev = null; - return result; - } - - /** - * Appends {@code segment} after this segment in the circularly-linked list. - * Returns the pushed segment. - */ - public Segment push(Segment segment) { - segment.prev = this; - segment.next = next; - next.prev = segment; - next = segment; - return segment; - } - - /** - * Splits this head of a circularly-linked list into two segments. The first - * segment contains the data in {@code [pos..pos+byteCount)}. The second - * segment contains the data in {@code [pos+byteCount..limit)}. This can be - * useful when moving partial segments from one OkBuffer to another. - * - *

Returns the new head of the circularly-linked list. - */ - public Segment split(int byteCount) { - int aSize = byteCount; - int bSize = (limit - pos) - byteCount; - if (aSize <= 0 || bSize <= 0) throw new IllegalArgumentException(); - - // Which side of the split is larger? We want to copy as few bytes as possible. - if (aSize < bSize) { - // Create a segment of size 'aSize' before this segment. - Segment before = SegmentPool.INSTANCE.take(); - System.arraycopy(data, pos, before.data, before.pos, aSize); - pos += aSize; - before.limit += aSize; - prev.push(before); - return before; - } else { - // Create a new segment of size 'bSize' after this segment. - Segment after = SegmentPool.INSTANCE.take(); - System.arraycopy(data, pos + aSize, after.data, after.pos, bSize); - limit -= bSize; - after.limit += bSize; - push(after); - return this; - } - } - - /** - * Call this when the tail and its predecessor may both be less than half - * full. This will copy data so that segments can be recycled. - */ - public void compact() { - if (prev == this) throw new IllegalStateException(); - if ((prev.limit - prev.pos) + (limit - pos) > SIZE) return; // Cannot compact. - writeTo(prev, limit - pos); - pop(); - SegmentPool.INSTANCE.recycle(this); - } - - /** Moves {@code byteCount} bytes from {@code sink} to this segment. */ - // TODO: if sink has fewer bytes than this, it may be cheaper to reverse the - // direction of the copy and swap the segments! - public void writeTo(Segment sink, int byteCount) { - if (byteCount + (sink.limit - sink.pos) > SIZE) throw new IllegalArgumentException(); - - if (sink.limit + byteCount > SIZE) { - // We can't fit byteCount bytes at the sink's current position. Compact sink first. - System.arraycopy(sink.data, sink.pos, sink.data, 0, sink.limit - sink.pos); - sink.limit -= sink.pos; - sink.pos = 0; - } - - System.arraycopy(data, pos, sink.data, sink.limit, byteCount); - sink.limit += byteCount; - pos += byteCount; - } -} diff --git a/okio/src/main/java/okio/SegmentPool.java b/okio/src/main/java/okio/SegmentPool.java deleted file mode 100644 index c132f244b..000000000 --- a/okio/src/main/java/okio/SegmentPool.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -/** - * A collection of unused segments, necessary to avoid GC churn and zero-fill. - * This pool is a thread-safe static singleton. - */ -final class SegmentPool { - static final SegmentPool INSTANCE = new SegmentPool(); - - /** The maximum number of bytes to pool. */ - // TODO: Is 64 KiB a good maximum size? Do we ever have that many idle segments? - static final long MAX_SIZE = 64 * 1024; // 64 KiB. - - /** Singly-linked list of segments. */ - private Segment next; - - /** Total bytes in this pool. */ - long byteCount; - - private SegmentPool() { - } - - Segment take() { - synchronized (this) { - if (next != null) { - Segment result = next; - next = result.next; - result.next = null; - byteCount -= Segment.SIZE; - return result; - } - } - return new Segment(); // Pool is empty. Don't zero-fill while holding a lock. - } - - void recycle(Segment segment) { - if (segment.next != null || segment.prev != null) throw new IllegalArgumentException(); - synchronized (this) { - if (byteCount + Segment.SIZE > MAX_SIZE) return; // Pool is full. - byteCount += Segment.SIZE; - segment.next = next; - segment.pos = segment.limit = 0; - next = segment; - } - } -} diff --git a/okio/src/main/java/okio/Sink.java b/okio/src/main/java/okio/Sink.java deleted file mode 100644 index 402aa0fc3..000000000 --- a/okio/src/main/java/okio/Sink.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Receives a stream of bytes. Use this interface to write data wherever it's - * needed: to the network, storage, or a buffer in memory. Sinks may be layered - * to transform received data, such as to compress, encrypt, throttle, or add - * protocol framing. - * - *

Most application code shouldn't operate on a sink directly, but rather - * {@link BufferedSink} which is both more efficient and more convenient. Use - * {@link Okio#buffer(Sink)} to wrap any sink with a buffer. - * - *

Sinks are easy to test: just use an {@link OkBuffer} in your tests, and - * read from it to confirm it received the data that was expected. - * - *

Comparison with OutputStream

- * This interface is functionally equivalent to {@link java.io.OutputStream}. - * - *

{@code OutputStream} requires multiple layers when emitted data is - * heterogeneous: a {@code DataOutputStream} for primitive values, a {@code - * BufferedOutputStream} for buffering, and {@code OutputStreamWriter} for - * charset encoding. This class uses {@code BufferedSink} for all of the above. - * - *

Sink is also easier to layer: there is no {@link - * java.io.OutputStream#write(int) single-byte write} method that is awkward to - * implement efficiently. - * - *

Interop with OutputStream

- * Use {@link Okio#sink} to adapt an {@code OutputStream} to a sink. Use {@link - * BufferedSink#outputStream} to adapt a sink to an {@code OutputStream}. - */ -public interface Sink extends Closeable { - /** Removes {@code byteCount} bytes from {@code source} and appends them to this. */ - void write(OkBuffer source, long byteCount) throws IOException; - - /** Pushes all buffered bytes to their final destination. */ - void flush() throws IOException; - - /** - * Sets the deadline for all operations on this sink. - * @return this sink. - */ - Sink deadline(Deadline deadline); - - /** - * Pushes all buffered bytes to their final destination and releases the - * resources held by this sink. It is an error to write a closed sink. It is - * safe to close a sink more than once. - */ - @Override void close() throws IOException; -} diff --git a/okio/src/main/java/okio/Source.java b/okio/src/main/java/okio/Source.java deleted file mode 100644 index d402beed3..000000000 --- a/okio/src/main/java/okio/Source.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Supplies a stream of bytes. Use this interface to read data from wherever - * it's located: from the network, storage, or a buffer in memory. Sources may - * be layered to transform supplied data, such as to decompress, decrypt, or - * remove protocol framing. - * - *

Most applications shouldn't operate on a source directly, but rather - * {@link BufferedSource} which is both more efficient and more convenient. Use - * {@link Okio#buffer(Source)} to wrap any source with a buffer. - * - *

Sources are easy to test: just use an {@link OkBuffer} in your tests, and - * fill it with the data your application is to read. - * - *

Comparison with InputStream

- * This interface is functionally equivalent to {@link java.io.InputStream}. - * - *

{@code InputStream} requires multiple layers when consumed data is - * heterogeneous: a {@code DataOutputStream} for primitive values, a {@code - * BufferedInputStream} for buffering, and {@code InputStreamReader} for - * strings. This class uses {@code BufferedSource} for all of the above. - * - *

Source avoids the impossible-to-implement {@link - * java.io.InputStream#available available()} method. Instead callers specify - * how many bytes they {@link BufferedSource#require require}. - * - *

Source omits the unsafe-to-compose {@link java.io.InputStream#mark mark - * and reset} state that's tracked by {@code InputStream}; callers instead just - * buffer what they need. - * - *

When implementing a source, you need not worry about the {@link - * java.io.InputStream#read single-byte read} method that is awkward to - * implement efficiently and that returns one of 257 possible values. - * - *

And source has a stronger {@code skip} method: {@link BufferedSource#skip} - * won't return prematurely. - * - *

Interop with InputStream

- * Use {@link Okio#source} to adapt an {@code InputStream} to a source. Use - * {@link BufferedSource#inputStream} to adapt a source to an {@code - * InputStream}. - */ -public interface Source extends Closeable { - /** - * Removes at least 1, and up to {@code byteCount} bytes from this and appends - * them to {@code sink}. Returns the number of bytes read, or -1 if this - * source is exhausted. - */ - long read(OkBuffer sink, long byteCount) throws IOException; - - /** - * Sets the deadline for all operations on this source. - * @return this source. - */ - Source deadline(Deadline deadline); - - /** - * Closes this source and releases the resources held by this source. It is an - * error to read a closed source. It is safe to close a source more than once. - */ - @Override void close() throws IOException; -} diff --git a/okio/src/main/java/okio/Util.java b/okio/src/main/java/okio/Util.java deleted file mode 100644 index 475948865..000000000 --- a/okio/src/main/java/okio/Util.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.nio.charset.Charset; - -final class Util { - /** A cheap and type-safe constant for the UTF-8 Charset. */ - public static final Charset UTF_8 = Charset.forName("UTF-8"); - - private Util() { - } - - public static void checkOffsetAndCount(long arrayLength, long offset, long count) { - if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) { - throw new ArrayIndexOutOfBoundsException(); - } - } - - public static short reverseBytesShort(short s) { - int i = s & 0xffff; - int reversed = (i & 0xff00) >>> 8 - | (i & 0x00ff) << 8; - return (short) reversed; - } - - public static int reverseBytesInt(int i) { - return (i & 0xff000000) >>> 24 - | (i & 0x00ff0000) >>> 8 - | (i & 0x0000ff00) << 8 - | (i & 0x000000ff) << 24; - } - - public static long reverseBytesLong(long v) { - return (v & 0xff00000000000000L) >>> 56 - | (v & 0x00ff000000000000L) >>> 40 - | (v & 0x0000ff0000000000L) >>> 24 - | (v & 0x000000ff00000000L) >>> 8 - | (v & 0x00000000ff000000L) << 8 - | (v & 0x0000000000ff0000L) << 24 - | (v & 0x000000000000ff00L) << 40 - | (v & 0x00000000000000ffL) << 56; - } - - /** - * Throws {@code t}, even if the declared throws clause doesn't permit it. - * This is a terrible – but terribly convenient – hack that makes it easy to - * catch and rethrow exceptions after cleanup. See Java Puzzlers #43. - */ - public static void sneakyRethrow(Throwable t) { - Util.sneakyThrow2(t); - } - - @SuppressWarnings("unchecked") - private static void sneakyThrow2(Throwable t) throws T { - throw (T) t; - } -} diff --git a/okio/src/test/java/okio/ByteStringTest.java b/okio/src/test/java/okio/ByteStringTest.java deleted file mode 100644 index 16b8e2d51..000000000 --- a/okio/src/test/java/okio/ByteStringTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2014 Square Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Arrays; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public class ByteStringTest { - - @Test public void getByte() throws Exception { - ByteString byteString = ByteString.decodeHex("ab12"); - assertEquals(-85, byteString.getByte(0)); - assertEquals(18, byteString.getByte(1)); - } - - @Test public void getByteOutOfBounds() throws Exception { - ByteString byteString = ByteString.decodeHex("ab12"); - try { - byteString.getByte(2); - fail(); - } catch (IndexOutOfBoundsException expected) { - } - } - - @Test public void equals() throws Exception { - ByteString byteString = ByteString.decodeHex("000102"); - assertTrue(byteString.equals(byteString)); - assertTrue(byteString.equals(ByteString.decodeHex("000102"))); - assertTrue(ByteString.of().equals(ByteString.EMPTY)); - assertTrue(ByteString.EMPTY.equals(ByteString.of())); - assertFalse(byteString.equals(new Object())); - assertFalse(byteString.equals(ByteString.decodeHex("000201"))); - } - - private final String bronzeHorseman = "На берегу пустынных волн"; - - @Test public void utf8() throws Exception { - ByteString byteString = ByteString.encodeUtf8(bronzeHorseman); - assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(Util.UTF_8)); - assertTrue(byteString.equals(ByteString.of(bronzeHorseman.getBytes(Util.UTF_8)))); - assertEquals(byteString.utf8(), bronzeHorseman); - } - - @Test public void testHashCode() throws Exception { - ByteString byteString = ByteString.decodeHex("0102"); - assertEquals(byteString.hashCode(), byteString.hashCode()); - assertEquals(byteString.hashCode(), ByteString.decodeHex("0102").hashCode()); - } - - @Test public void read() throws Exception { - InputStream in = new ByteArrayInputStream("abc".getBytes(Util.UTF_8)); - assertEquals(ByteString.decodeHex("6162"), ByteString.read(in, 2)); - assertEquals(ByteString.decodeHex("63"), ByteString.read(in, 1)); - assertEquals(ByteString.of(), ByteString.read(in, 0)); - } - - @Test public void readLowerCase() throws Exception { - InputStream in = new ByteArrayInputStream("ABC".getBytes(Util.UTF_8)); - assertEquals(ByteString.encodeUtf8("ab"), ByteString.read(in, 2).toAsciiLowercase()); - assertEquals(ByteString.encodeUtf8("c"), ByteString.read(in, 1).toAsciiLowercase()); - assertEquals(ByteString.EMPTY, ByteString.read(in, 0).toAsciiLowercase()); - } - - @Test public void toAsciiLowerCaseNoUppercase() throws Exception { - ByteString s = ByteString.encodeUtf8("a1_+"); - assertSame(s, s.toAsciiLowercase()); - } - - @Test public void toAsciiAllUppercase() throws Exception { - assertEquals(ByteString.encodeUtf8("ab"), ByteString.encodeUtf8("AB").toAsciiLowercase()); - } - - @Test public void toAsciiStartsLowercaseEndsUppercase() throws Exception { - assertEquals(ByteString.encodeUtf8("abcd"), ByteString.encodeUtf8("abCD").toAsciiLowercase()); - } - - @Test public void write() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteString.decodeHex("616263").write(out); - assertByteArraysEquals(new byte[] { 0x61, 0x62, 0x63 }, out.toByteArray()); - } - - @Test public void encodeBase64() { - assertEquals("", ByteString.encodeUtf8("").base64()); - assertEquals("AA==", ByteString.encodeUtf8("\u0000").base64()); - assertEquals("AAA=", ByteString.encodeUtf8("\u0000\u0000").base64()); - assertEquals("AAAA", ByteString.encodeUtf8("\u0000\u0000\u0000").base64()); - assertEquals("V2UncmUgZ29ubmEgbWFrZSBhIGZvcnR1bmUgd2l0aCB0aGlzIHBsYWNlLg==", - ByteString.encodeUtf8("We're gonna make a fortune with this place.").base64()); - } - - @Test public void ignoreUnnecessaryPadding() { - assertEquals("", ByteString.decodeBase64("====").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AAAA====").utf8()); - } - - @Test public void decodeBase64() { - assertEquals("", ByteString.decodeBase64("").utf8()); - assertEquals(null, ByteString.decodeBase64("/===")); // Can't do anything with 6 bits! - assertEquals(ByteString.decodeHex("ff"), ByteString.decodeBase64("//==")); - assertEquals(ByteString.decodeHex("ffff"), ByteString.decodeBase64("///=")); - assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("////")); - assertEquals(ByteString.decodeHex("ffffffffffff"), ByteString.decodeBase64("////////")); - assertEquals("What's to be scared about? It's just a little hiccup in the power...", - ByteString.decodeBase64("V2hhdCdzIHRvIGJlIHNjYXJlZCBhYm91dD8gSXQncyBqdXN0IGEgbGl0dGxlIGhpY2" - + "N1cCBpbiB0aGUgcG93ZXIuLi4=").utf8()); - } - - @Test public void decodeBase64WithWhitespace() { - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AA AA").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8()); - assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("A AAA").utf8()); - assertEquals("", ByteString.decodeBase64(" ").utf8()); - } - - @Test public void encodeHex() throws Exception { - assertEquals("000102", ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2).hex()); - } - - @Test public void decodeHex() throws Exception { - assertEquals(ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2), ByteString.decodeHex("000102")); - } - - @Test public void decodeHexOddNumberOfChars() throws Exception { - try { - ByteString.decodeHex("aaa"); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test public void decodeHexInvalidChar() throws Exception { - try { - ByteString.decodeHex("a\u0000"); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test public void toStringOnEmptyByteString() { - assertEquals("ByteString[size=0]", ByteString.of().toString()); - } - - @Test public void toStringOnSmallByteStringIncludesContents() { - assertEquals("ByteString[size=16 data=a1b2c3d4e5f61a2b3c4d5e6f10203040]", - ByteString.decodeHex("a1b2c3d4e5f61a2b3c4d5e6f10203040").toString()); - } - - @Test public void toStringOnLargeByteStringIncludesMd5() { - assertEquals("ByteString[size=17 md5=2c9728a2138b2f25e9f89f99bdccf8db]", - ByteString.encodeUtf8("12345678901234567").toString()); - } - - private static void assertByteArraysEquals(byte[] a, byte[] b) { - assertEquals(Arrays.toString(a), Arrays.toString(b)); - } -} diff --git a/okio/src/test/java/okio/DeflaterSinkTest.java b/okio/src/test/java/okio/DeflaterSinkTest.java deleted file mode 100644 index 0f6b8c286..000000000 --- a/okio/src/test/java/okio/DeflaterSinkTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Random; -import java.util.zip.Deflater; -import java.util.zip.Inflater; -import java.util.zip.InflaterInputStream; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public final class DeflaterSinkTest { - @Test public void deflateWithClose() throws Exception { - OkBuffer data = new OkBuffer(); - String original = "They're moving in herds. They do move in herds."; - data.writeUtf8(original); - OkBuffer sink = new OkBuffer(); - DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.size()); - deflaterSink.close(); - OkBuffer inflated = inflate(sink); - assertEquals(original, inflated.readUtf8(inflated.size())); - } - - @Test public void deflateWithSyncFlush() throws Exception { - String original = "Yes, yes, yes. That's why we're taking extreme precautions."; - OkBuffer data = new OkBuffer(); - data.writeUtf8(original); - OkBuffer sink = new OkBuffer(); - DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.size()); - deflaterSink.flush(); - OkBuffer inflated = inflate(sink); - assertEquals(original, inflated.readUtf8(inflated.size())); - } - - @Test public void deflateWellCompressed() throws IOException { - String original = repeat('a', 1024 * 1024); - OkBuffer data = new OkBuffer(); - data.writeUtf8(original); - OkBuffer sink = new OkBuffer(); - DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.size()); - deflaterSink.close(); - OkBuffer inflated = inflate(sink); - assertEquals(original, inflated.readUtf8(inflated.size())); - } - - @Test public void deflatePoorlyCompressed() throws IOException { - ByteString original = randomBytes(1024 * 1024); - OkBuffer data = new OkBuffer(); - data.write(original); - OkBuffer sink = new OkBuffer(); - DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.size()); - deflaterSink.close(); - OkBuffer inflated = inflate(sink); - assertEquals(original, inflated.readByteString(inflated.size())); - } - - @Test public void multipleSegmentsWithoutCompression() throws IOException { - OkBuffer buffer = new OkBuffer(); - Deflater deflater = new Deflater(); - deflater.setLevel(Deflater.NO_COMPRESSION); - DeflaterSink deflaterSink = new DeflaterSink(buffer, deflater); - int byteCount = Segment.SIZE * 4; - deflaterSink.write(new OkBuffer().writeUtf8(repeat('a', byteCount)), byteCount); - deflaterSink.close(); - assertEquals(repeat('a', byteCount), inflate(buffer).readUtf8(byteCount)); - } - - /** - * This test deflates a single segment of without compression because that's - * the easiest way to force close() to emit a large amount of data to the - * underlying sink. - */ - @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException { - MockSink mockSink = new MockSink(); - mockSink.scheduleThrow(0, new IOException("first")); - mockSink.scheduleThrow(1, new IOException("second")); - Deflater deflater = new Deflater(); - deflater.setLevel(Deflater.NO_COMPRESSION); - DeflaterSink deflaterSink = new DeflaterSink(mockSink, deflater); - deflaterSink.write(new OkBuffer().writeUtf8(repeat('a', Segment.SIZE)), Segment.SIZE); - try { - deflaterSink.close(); - fail(); - } catch (IOException expected) { - assertEquals("first", expected.getMessage()); - } - mockSink.assertLogContains("close()"); - } - - /** - * Uses streaming decompression to inflate {@code deflated}. The input must - * either be finished or have a trailing sync flush. - */ - private OkBuffer inflate(OkBuffer deflated) throws IOException { - InputStream deflatedIn = deflated.inputStream(); - Inflater inflater = new Inflater(); - InputStream inflatedIn = new InflaterInputStream(deflatedIn, inflater); - OkBuffer result = new OkBuffer(); - byte[] buffer = new byte[8192]; - while (!inflater.needsInput() || deflated.size() > 0 || deflatedIn.available() > 0) { - int count = inflatedIn.read(buffer, 0, buffer.length); - result.write(buffer, 0, count); - } - return result; - } - - private ByteString randomBytes(int length) { - Random random = new Random(0); - byte[] randomBytes = new byte[length]; - random.nextBytes(randomBytes); - return ByteString.of(randomBytes); - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/okio/src/test/java/okio/GzipSourceTest.java b/okio/src/test/java/okio/GzipSourceTest.java deleted file mode 100644 index f14b99963..000000000 --- a/okio/src/test/java/okio/GzipSourceTest.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.util.zip.CRC32; -import org.junit.Test; - -import static okio.Util.UTF_8; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public class GzipSourceTest { - - @Test public void gunzip() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeader); - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - @Test public void gunzip_withHCRC() throws Exception { - CRC32 hcrc = new CRC32(); - ByteString gzipHeader = gzipHeaderWithFlags((byte) 0x02); - hcrc.update(gzipHeader.toByteArray()); - - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeader); - gzipped.writeShort(Util.reverseBytesShort((short) hcrc.getValue())); // little endian - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - @Test public void gunzip_withExtra() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeaderWithFlags((byte) 0x04)); - gzipped.writeShort(Util.reverseBytesShort((short) 7)); // little endian extra length - gzipped.write("blubber".getBytes(UTF_8), 0, 7); - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - @Test public void gunzip_withName() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeaderWithFlags((byte) 0x08)); - gzipped.write("foo.txt".getBytes(UTF_8), 0, 7); - gzipped.writeByte(0); // zero-terminated - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - @Test public void gunzip_withComment() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeaderWithFlags((byte) 0x10)); - gzipped.write("rubbish".getBytes(UTF_8), 0, 7); - gzipped.writeByte(0); // zero-terminated - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - /** - * For portability, it is a good idea to export the gzipped bytes and try running gzip. Ex. - * {@code echo gzipped | base64 --decode | gzip -l -v} - */ - @Test public void gunzip_withAll() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeaderWithFlags((byte) 0x1c)); - gzipped.writeShort(Util.reverseBytesShort((short) 7)); // little endian extra length - gzipped.write("blubber".getBytes(UTF_8), 0, 7); - gzipped.write("foo.txt".getBytes(UTF_8), 0, 7); - gzipped.writeByte(0); // zero-terminated - gzipped.write("rubbish".getBytes(UTF_8), 0, 7); - gzipped.writeByte(0); // zero-terminated - gzipped.write(deflated); - gzipped.write(gzipTrailer); - assertGzipped(gzipped); - } - - private void assertGzipped(OkBuffer gzipped) throws IOException { - OkBuffer gunzipped = gunzip(gzipped); - assertEquals("It's a UNIX system! I know this!", gunzipped.readUtf8(gunzipped.size())); - } - - /** - * Note that you cannot test this with old versions of gzip, as they interpret flag bit 1 as - * CONTINUATION, not HCRC. For example, this is the case with the default gzip on osx. - */ - @Test public void gunzipWhenHeaderCRCIncorrect() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeaderWithFlags((byte) 0x02)); - gzipped.writeShort((short) 0); // wrong HCRC! - gzipped.write(deflated); - gzipped.write(gzipTrailer); - - try { - gunzip(gzipped); - fail(); - } catch (IOException e) { - assertEquals("FHCRC: actual 0x0000261d != expected 0x00000000", e.getMessage()); - } - } - - @Test public void gunzipWhenCRCIncorrect() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeader); - gzipped.write(deflated); - gzipped.writeInt(Util.reverseBytesInt(0x1234567)); // wrong CRC - gzipped.write(gzipTrailer.toByteArray(), 3, 4); - - try { - gunzip(gzipped); - fail(); - } catch (IOException e) { - assertEquals("CRC: actual 0x37ad8f8d != expected 0x01234567", e.getMessage()); - } - } - - @Test public void gunzipWhenLengthIncorrect() throws Exception { - OkBuffer gzipped = new OkBuffer(); - gzipped.write(gzipHeader); - gzipped.write(deflated); - gzipped.write(gzipTrailer.toByteArray(), 0, 4); - gzipped.writeInt(Util.reverseBytesInt(0x123456)); // wrong length - - try { - gunzip(gzipped); - fail(); - } catch (IOException e) { - assertEquals("ISIZE: actual 0x00000020 != expected 0x00123456", e.getMessage()); - } - } - - @Test public void gunzipExhaustsSource() throws Exception { - OkBuffer gzippedSource = new OkBuffer() - .write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc' - - ExhaustableSource exhaustableSource = new ExhaustableSource(gzippedSource); - BufferedSource gunzippedSource = Okio.buffer(new GzipSource(exhaustableSource)); - - assertEquals('a', gunzippedSource.readByte()); - assertEquals('b', gunzippedSource.readByte()); - assertEquals('c', gunzippedSource.readByte()); - assertFalse(exhaustableSource.exhausted); - assertEquals(-1, gunzippedSource.read(new OkBuffer(), 1)); - assertTrue(exhaustableSource.exhausted); - } - - @Test public void gunzipThrowsIfSourceIsNotExhausted() throws Exception { - OkBuffer gzippedSource = new OkBuffer() - .write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc' - gzippedSource.writeByte('d'); // This byte shouldn't be here! - - BufferedSource gunzippedSource = Okio.buffer(new GzipSource(gzippedSource)); - - assertEquals('a', gunzippedSource.readByte()); - assertEquals('b', gunzippedSource.readByte()); - assertEquals('c', gunzippedSource.readByte()); - try { - gunzippedSource.readByte(); - fail(); - } catch (IOException expected) { - } - } - - private ByteString gzipHeaderWithFlags(byte flags) { - byte[] result = gzipHeader.toByteArray(); - result[3] = flags; - return ByteString.of(result); - } - - private final ByteString gzipHeader = ByteString.decodeHex("1f8b0800000000000000"); - - // Deflated "It's a UNIX system! I know this!" - private final ByteString deflated = ByteString.decodeHex( - "f32c512f56485408f5f38c5028ae2c2e49cd5554f054c8cecb2f5728c9c82c560400"); - - private final ByteString gzipTrailer = ByteString.decodeHex("" - + "8d8fad37" // Checksum of deflated. - + "20000000" // 32 in little endian. - ); - - private OkBuffer gunzip(OkBuffer gzipped) throws IOException { - OkBuffer result = new OkBuffer(); - GzipSource source = new GzipSource(gzipped); - while (source.read(result, Integer.MAX_VALUE) != -1) { - } - return result; - } - - /** This source keeps track of whether its read have returned -1. */ - static class ExhaustableSource implements Source { - private final Source source; - private boolean exhausted; - - ExhaustableSource(Source source) { - this.source = source; - } - - @Override public long read(OkBuffer sink, long byteCount) throws IOException { - long result = source.read(sink, byteCount); - if (result == -1) exhausted = true; - return result; - } - - @Override public Source deadline(Deadline deadline) { - source.deadline(deadline); - return this; - } - - @Override public void close() throws IOException { - source.close(); - } - } -} diff --git a/okio/src/test/java/okio/InflaterSourceTest.java b/okio/src/test/java/okio/InflaterSourceTest.java deleted file mode 100644 index e6f2bc653..000000000 --- a/okio/src/test/java/okio/InflaterSourceTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.util.Arrays; -import java.util.Random; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.Inflater; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public final class InflaterSourceTest { - @Test public void inflate() throws Exception { - OkBuffer deflated = decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tK" - + "tYDAF6CD5s="); - OkBuffer inflated = inflate(deflated); - assertEquals("God help us, we're in the hands of engineers.", readUtf8(inflated)); - } - - @Test public void inflateTruncated() throws Exception { - OkBuffer deflated = decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tK" - + "tYDAF6CDw=="); - try { - inflate(deflated); - fail(); - } catch (EOFException expected) { - } - } - - @Test public void inflateWellCompressed() throws Exception { - OkBuffer deflated = decodeBase64("eJztwTEBAAAAwqCs61/CEL5AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8B" - + "tFeWvE=\n"); - String original = repeat('a', 1024 * 1024); - OkBuffer inflated = inflate(deflated); - assertEquals(original, readUtf8(inflated)); - } - - @Test public void inflatePoorlyCompressed() throws Exception { - ByteString original = randomBytes(1024 * 1024); - OkBuffer deflated = deflate(original); - OkBuffer inflated = inflate(deflated); - assertEquals(original, inflated.readByteString(inflated.size())); - } - - private OkBuffer decodeBase64(String s) { - return new OkBuffer().write(ByteString.decodeBase64(s)); - } - - private String readUtf8(OkBuffer buffer) { - return buffer.readUtf8(buffer.size()); - } - - /** Use DeflaterOutputStream to deflate source. */ - private OkBuffer deflate(ByteString source) throws IOException { - OkBuffer result = new OkBuffer(); - Sink sink = Okio.sink(new DeflaterOutputStream(result.outputStream())); - sink.write(new OkBuffer().write(source), source.size()); - sink.close(); - return result; - } - - /** Returns a new buffer containing the inflated contents of {@code deflated}. */ - private OkBuffer inflate(OkBuffer deflated) throws IOException { - OkBuffer result = new OkBuffer(); - InflaterSource source = new InflaterSource(deflated, new Inflater()); - while (source.read(result, Integer.MAX_VALUE) != -1) { - } - return result; - } - - private ByteString randomBytes(int length) { - Random random = new Random(0); - byte[] randomBytes = new byte[length]; - random.nextBytes(randomBytes); - return ByteString.of(randomBytes); - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/okio/src/test/java/okio/MockSink.java b/okio/src/test/java/okio/MockSink.java deleted file mode 100644 index bae325911..000000000 --- a/okio/src/test/java/okio/MockSink.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** A scriptable sink. Like Mockito, but worse and requiring less configuration. */ -class MockSink implements Sink { - private final List log = new ArrayList(); - private final Map callThrows = new LinkedHashMap(); - - public void assertLog(String... messages) { - assertEquals(Arrays.asList(messages), log); - } - - public void assertLogContains(String message) { - assertTrue(log.contains(message)); - } - - public void scheduleThrow(int call, IOException e) { - callThrows.put(call, e); - } - - private void throwIfScheduled() throws IOException { - IOException exception = callThrows.get(log.size() - 1); - if (exception != null) throw exception; - } - - @Override public void write(OkBuffer source, long byteCount) throws IOException { - log.add("write(" + source + ", " + byteCount + ")"); - source.skip(byteCount); - throwIfScheduled(); - } - - @Override public void flush() throws IOException { - log.add("flush()"); - throwIfScheduled(); - } - - @Override public Sink deadline(Deadline deadline) { - log.add("deadline()"); - return this; - } - - @Override public void close() throws IOException { - log.add("close()"); - throwIfScheduled(); - } -} diff --git a/okio/src/test/java/okio/OkBufferReadUtf8LineTest.java b/okio/src/test/java/okio/OkBufferReadUtf8LineTest.java deleted file mode 100644 index ac3de728e..000000000 --- a/okio/src/test/java/okio/OkBufferReadUtf8LineTest.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -public final class OkBufferReadUtf8LineTest extends ReadUtf8LineTest { - @Override protected BufferedSource newSource(String s) { - return new OkBuffer().writeUtf8(s); - } -} diff --git a/okio/src/test/java/okio/OkBufferTest.java b/okio/src/test/java/okio/OkBufferTest.java deleted file mode 100644 index f69613a18..000000000 --- a/okio/src/test/java/okio/OkBufferTest.java +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public final class OkBufferTest { - @Test public void readAndWriteUtf8() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8("ab"); - assertEquals(2, buffer.size()); - buffer.writeUtf8("cdef"); - assertEquals(6, buffer.size()); - assertEquals("abcd", buffer.readUtf8(4)); - assertEquals(2, buffer.size()); - assertEquals("ef", buffer.readUtf8(2)); - assertEquals(0, buffer.size()); - try { - buffer.readUtf8(1); - fail(); - } catch (ArrayIndexOutOfBoundsException expected) { - } - } - - @Test public void completeSegmentByteCountOnEmptyBuffer() throws Exception { - OkBuffer buffer = new OkBuffer(); - assertEquals(0, buffer.completeSegmentByteCount()); - } - - @Test public void completeSegmentByteCountOnBufferWithFullSegments() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', Segment.SIZE * 4)); - assertEquals(Segment.SIZE * 4, buffer.completeSegmentByteCount()); - } - - @Test public void completeSegmentByteCountOnBufferWithIncompleteTailSegment() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', Segment.SIZE * 4 - 10)); - assertEquals(Segment.SIZE * 3, buffer.completeSegmentByteCount()); - } - - @Test public void readUtf8SpansSegments() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', Segment.SIZE * 2)); - buffer.readUtf8(Segment.SIZE - 1); - assertEquals("aa", buffer.readUtf8(2)); - } - - @Test public void readUtf8EntireBuffer() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', Segment.SIZE)); - assertEquals(repeat('a', Segment.SIZE), buffer.readUtf8(Segment.SIZE)); - } - - @Test public void toStringOnEmptyBuffer() throws Exception { - OkBuffer buffer = new OkBuffer(); - assertEquals("OkBuffer[size=0]", buffer.toString()); - } - - @Test public void toStringOnSmallBufferIncludesContents() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.write(ByteString.decodeHex("a1b2c3d4e5f61a2b3c4d5e6f10203040")); - assertEquals("OkBuffer[size=16 data=a1b2c3d4e5f61a2b3c4d5e6f10203040]", buffer.toString()); - } - - @Test public void toStringOnLargeBufferIncludesMd5() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.write(ByteString.encodeUtf8("12345678901234567")); - assertEquals("OkBuffer[size=17 md5=2c9728a2138b2f25e9f89f99bdccf8db]", buffer.toString()); - } - - @Test public void toStringOnMultipleSegmentBuffer() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', 6144)); - assertEquals("OkBuffer[size=6144 md5=d890021f28522533c1cc1b9b1f83ce73]", buffer.toString()); - } - - @Test public void multipleSegmentBuffers() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8(repeat('a', 1000)); - buffer.writeUtf8(repeat('b', 2500)); - buffer.writeUtf8(repeat('c', 5000)); - buffer.writeUtf8(repeat('d', 10000)); - buffer.writeUtf8(repeat('e', 25000)); - buffer.writeUtf8(repeat('f', 50000)); - - assertEquals(repeat('a', 999), buffer.readUtf8(999)); // a...a - assertEquals("a" + repeat('b', 2500) + "c", buffer.readUtf8(2502)); // ab...bc - assertEquals(repeat('c', 4998), buffer.readUtf8(4998)); // c...c - assertEquals("c" + repeat('d', 10000) + "e", buffer.readUtf8(10002)); // cd...de - assertEquals(repeat('e', 24998), buffer.readUtf8(24998)); // e...e - assertEquals("e" + repeat('f', 50000), buffer.readUtf8(50001)); // ef...f - assertEquals(0, buffer.size()); - } - - @Test public void fillAndDrainPool() throws Exception { - OkBuffer buffer = new OkBuffer(); - - // Take 2 * MAX_SIZE segments. This will drain the pool, even if other tests filled it. - buffer.write(new byte[(int) SegmentPool.MAX_SIZE]); - buffer.write(new byte[(int) SegmentPool.MAX_SIZE]); - assertEquals(0, SegmentPool.INSTANCE.byteCount); - - // Recycle MAX_SIZE segments. They're all in the pool. - buffer.readByteString(SegmentPool.MAX_SIZE); - assertEquals(SegmentPool.MAX_SIZE, SegmentPool.INSTANCE.byteCount); - - // Recycle MAX_SIZE more segments. The pool is full so they get garbage collected. - buffer.readByteString(SegmentPool.MAX_SIZE); - assertEquals(SegmentPool.MAX_SIZE, SegmentPool.INSTANCE.byteCount); - - // Take MAX_SIZE segments to drain the pool. - buffer.write(new byte[(int) SegmentPool.MAX_SIZE]); - assertEquals(0, SegmentPool.INSTANCE.byteCount); - - // Take MAX_SIZE more segments. The pool is drained so these will need to be allocated. - buffer.write(new byte[(int) SegmentPool.MAX_SIZE]); - assertEquals(0, SegmentPool.INSTANCE.byteCount); - } - - @Test public void moveBytesBetweenBuffersShareSegment() throws Exception { - int size = (Segment.SIZE / 2) - 1; - List segmentSizes = moveBytesBetweenBuffers(repeat('a', size), repeat('b', size)); - assertEquals(asList(size * 2), segmentSizes); - } - - @Test public void moveBytesBetweenBuffersReassignSegment() throws Exception { - int size = (Segment.SIZE / 2) + 1; - List segmentSizes = moveBytesBetweenBuffers(repeat('a', size), repeat('b', size)); - assertEquals(asList(size, size), segmentSizes); - } - - @Test public void moveBytesBetweenBuffersMultipleSegments() throws Exception { - int size = 3 * Segment.SIZE + 1; - List segmentSizes = moveBytesBetweenBuffers(repeat('a', size), repeat('b', size)); - assertEquals(asList(Segment.SIZE, Segment.SIZE, Segment.SIZE, 1, - Segment.SIZE, Segment.SIZE, Segment.SIZE, 1), segmentSizes); - } - - private List moveBytesBetweenBuffers(String... contents) { - StringBuilder expected = new StringBuilder(); - OkBuffer buffer = new OkBuffer(); - for (String s : contents) { - OkBuffer source = new OkBuffer(); - source.writeUtf8(s); - buffer.write(source, source.size()); - expected.append(s); - } - List segmentSizes = buffer.segmentSizes(); - assertEquals(expected.toString(), buffer.readUtf8(expected.length())); - return segmentSizes; - } - - /** The big part of source's first segment is being moved. */ - @Test public void writeSplitSourceBufferLeft() throws Exception { - int writeSize = Segment.SIZE / 2 + 1; - - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('b', Segment.SIZE - 10)); - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, writeSize); - - assertEquals(asList(Segment.SIZE - 10, writeSize), sink.segmentSizes()); - assertEquals(asList(Segment.SIZE - writeSize, Segment.SIZE), source.segmentSizes()); - } - - /** The big part of source's first segment is staying put. */ - @Test public void writeSplitSourceBufferRight() throws Exception { - int writeSize = Segment.SIZE / 2 - 1; - - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('b', Segment.SIZE - 10)); - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, writeSize); - - assertEquals(asList(Segment.SIZE - 10, writeSize), sink.segmentSizes()); - assertEquals(asList(Segment.SIZE - writeSize, Segment.SIZE), source.segmentSizes()); - } - - @Test public void writePrefixDoesntSplit() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('b', 10)); - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, 20); - - assertEquals(asList(30), sink.segmentSizes()); - assertEquals(asList(Segment.SIZE - 20, Segment.SIZE), source.segmentSizes()); - assertEquals(30, sink.size()); - assertEquals(Segment.SIZE * 2 - 20, source.size()); - } - - @Test public void writePrefixDoesntSplitButRequiresCompact() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('b', Segment.SIZE - 10)); // limit = size - 10 - sink.readUtf8(Segment.SIZE - 20); // pos = size = 20 - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, 20); - - assertEquals(asList(30), sink.segmentSizes()); - assertEquals(asList(Segment.SIZE - 20, Segment.SIZE), source.segmentSizes()); - assertEquals(30, sink.size()); - assertEquals(Segment.SIZE * 2 - 20, source.size()); - } - - @Test public void readExhaustedSource() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('a', 10)); - - OkBuffer source = new OkBuffer(); - - assertEquals(-1, source.read(sink, 10)); - assertEquals(10, sink.size()); - assertEquals(0, source.size()); - } - - @Test public void readZeroBytesFromSource() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('a', 10)); - - OkBuffer source = new OkBuffer(); - - // Either 0 or -1 is reasonable here. For consistency with Android's - // ByteArrayInputStream we return 0. - assertEquals(-1, source.read(sink, 0)); - assertEquals(10, sink.size()); - assertEquals(0, source.size()); - } - - @Test public void moveAllRequestedBytesWithRead() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('a', 10)); - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('b', 15)); - - assertEquals(10, source.read(sink, 10)); - assertEquals(20, sink.size()); - assertEquals(5, source.size()); - assertEquals(repeat('a', 10) + repeat('b', 10), sink.readUtf8(20)); - } - - @Test public void moveFewerThanRequestedBytesWithRead() throws Exception { - OkBuffer sink = new OkBuffer(); - sink.writeUtf8(repeat('a', 10)); - - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('b', 20)); - - assertEquals(20, source.read(sink, 25)); - assertEquals(30, sink.size()); - assertEquals(0, source.size()); - assertEquals(repeat('a', 10) + repeat('b', 20), sink.readUtf8(30)); - } - - @Test public void indexOf() throws Exception { - OkBuffer buffer = new OkBuffer(); - - // The segment is empty. - assertEquals(-1, buffer.indexOf((byte) 'a')); - - // The segment has one value. - buffer.writeUtf8("a"); // a - assertEquals(0, buffer.indexOf((byte) 'a')); - assertEquals(-1, buffer.indexOf((byte) 'b')); - - // The segment has lots of data. - buffer.writeUtf8(repeat('b', Segment.SIZE - 2)); // ab...b - assertEquals(0, buffer.indexOf((byte) 'a')); - assertEquals(1, buffer.indexOf((byte) 'b')); - assertEquals(-1, buffer.indexOf((byte) 'c')); - - // The segment doesn't start at 0, it starts at 2. - buffer.readUtf8(2); // b...b - assertEquals(-1, buffer.indexOf((byte) 'a')); - assertEquals(0, buffer.indexOf((byte) 'b')); - assertEquals(-1, buffer.indexOf((byte) 'c')); - - // The segment is full. - buffer.writeUtf8("c"); // b...bc - assertEquals(-1, buffer.indexOf((byte) 'a')); - assertEquals(0, buffer.indexOf((byte) 'b')); - assertEquals(Segment.SIZE - 3, buffer.indexOf((byte) 'c')); - - // The segment doesn't start at 2, it starts at 4. - buffer.readUtf8(2); // b...bc - assertEquals(-1, buffer.indexOf((byte) 'a')); - assertEquals(0, buffer.indexOf((byte) 'b')); - assertEquals(Segment.SIZE - 5, buffer.indexOf((byte) 'c')); - - // Two segments. - buffer.writeUtf8("d"); // b...bcd, d is in the 2nd segment. - assertEquals(asList(Segment.SIZE - 4, 1), buffer.segmentSizes()); - assertEquals(Segment.SIZE - 4, buffer.indexOf((byte) 'd')); - assertEquals(-1, buffer.indexOf((byte) 'e')); - } - - @Test public void indexOfWithOffset() throws Exception { - OkBuffer buffer = new OkBuffer(); - int halfSegment = Segment.SIZE / 2; - buffer.writeUtf8(repeat('a', halfSegment)); - buffer.writeUtf8(repeat('b', halfSegment)); - buffer.writeUtf8(repeat('c', halfSegment)); - buffer.writeUtf8(repeat('d', halfSegment)); - assertEquals(0, buffer.indexOf((byte) 'a', 0)); - assertEquals(halfSegment - 1, buffer.indexOf((byte) 'a', halfSegment - 1)); - assertEquals(halfSegment, buffer.indexOf((byte) 'b', halfSegment - 1)); - assertEquals(halfSegment * 2, buffer.indexOf((byte) 'c', halfSegment - 1)); - assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment - 1)); - assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 2)); - assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 3)); - assertEquals(halfSegment * 4 - 1, buffer.indexOf((byte) 'd', halfSegment * 4 - 1)); - } - - @Test public void writeBytes() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeByte(0xab); - data.writeByte(0xcd); - assertEquals("OkBuffer[size=2 data=abcd]", data.toString()); - } - - @Test public void writeLastByteInSegment() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 1)); - data.writeByte(0x20); - data.writeByte(0x21); - assertEquals(asList(Segment.SIZE, 1), data.segmentSizes()); - assertEquals(repeat('a', Segment.SIZE - 1), data.readUtf8(Segment.SIZE - 1)); - assertEquals("OkBuffer[size=2 data=2021]", data.toString()); - } - - @Test public void writeShort() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeShort(0xabcd); - data.writeShort(0x4321); - assertEquals("OkBuffer[size=4 data=abcd4321]", data.toString()); - } - - @Test public void writeShortLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeShortLe(0xabcd); - data.writeShortLe(0x4321); - assertEquals("OkBuffer[size=4 data=cdab2143]", data.toString()); - } - - @Test public void writeInt() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeInt(0xabcdef01); - data.writeInt(0x87654321); - assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString()); - } - - @Test public void writeLastIntegerInSegment() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 4)); - data.writeInt(0xabcdef01); - data.writeInt(0x87654321); - assertEquals(asList(Segment.SIZE, 4), data.segmentSizes()); - assertEquals(repeat('a', Segment.SIZE - 4), data.readUtf8(Segment.SIZE - 4)); - assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString()); - } - - @Test public void writeIntegerDoesntQuiteFitInSegment() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 3)); - data.writeInt(0xabcdef01); - data.writeInt(0x87654321); - assertEquals(asList(Segment.SIZE - 3, 8), data.segmentSizes()); - assertEquals(repeat('a', Segment.SIZE - 3), data.readUtf8(Segment.SIZE - 3)); - assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString()); - } - - @Test public void writeIntLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeIntLe(0xabcdef01); - data.writeIntLe(0x87654321); - assertEquals("OkBuffer[size=8 data=01efcdab21436587]", data.toString()); - } - - @Test public void writeLong() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeLong(0xabcdef0187654321L); - data.writeLong(0xcafebabeb0b15c00L); - assertEquals("OkBuffer[size=16 data=abcdef0187654321cafebabeb0b15c00]", data.toString()); - } - - @Test public void writeLongLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeLongLe(0xabcdef0187654321L); - data.writeLongLe(0xcafebabeb0b15c00L); - assertEquals("OkBuffer[size=16 data=2143658701efcdab005cb1b0bebafeca]", data.toString()); - } - - @Test public void readByte() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { (byte) 0xab, (byte) 0xcd }); - assertEquals(0xab, data.readByte() & 0xff); - assertEquals(0xcd, data.readByte() & 0xff); - assertEquals(0, data.size()); - } - - @Test public void readShort() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01 - }); - assertEquals((short) 0xabcd, data.readShort()); - assertEquals((short) 0xef01, data.readShort()); - assertEquals(0, data.size()); - } - - @Test public void readShortLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10 - }); - assertEquals((short) 0xcdab, data.readShortLe()); - assertEquals((short) 0x10ef, data.readShortLe()); - assertEquals(0, data.size()); - } - - @Test public void readShortSplitAcrossMultipleSegments() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 1)); - data.write(new byte[] { (byte) 0xab, (byte) 0xcd }); - data.readUtf8(Segment.SIZE - 1); - assertEquals((short) 0xabcd, data.readShort()); - assertEquals(0, data.size()); - } - - @Test public void readInt() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, - (byte) 0x87, (byte) 0x65, (byte) 0x43, (byte) 0x21 - }); - assertEquals(0xabcdef01, data.readInt()); - assertEquals(0x87654321, data.readInt()); - assertEquals(0, data.size()); - } - - @Test public void readIntLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, - (byte) 0x87, (byte) 0x65, (byte) 0x43, (byte) 0x21 - }); - assertEquals(0x10efcdab, data.readIntLe()); - assertEquals(0x21436587, data.readIntLe()); - assertEquals(0, data.size()); - } - - @Test public void readIntSplitAcrossMultipleSegments() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 3)); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01 - }); - data.readUtf8(Segment.SIZE - 3); - assertEquals(0xabcdef01, data.readInt()); - assertEquals(0, data.size()); - } - - @Test public void readLong() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, - (byte) 0x87, (byte) 0x65, (byte) 0x43, (byte) 0x21, - (byte) 0x36, (byte) 0x47, (byte) 0x58, (byte) 0x69, - (byte) 0x12, (byte) 0x23, (byte) 0x34, (byte) 0x45 - }); - assertEquals(0xabcdef1087654321L, data.readLong()); - assertEquals(0x3647586912233445L, data.readLong()); - assertEquals(0, data.size()); - } - - @Test public void readLongLe() throws Exception { - OkBuffer data = new OkBuffer(); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, - (byte) 0x87, (byte) 0x65, (byte) 0x43, (byte) 0x21, - (byte) 0x36, (byte) 0x47, (byte) 0x58, (byte) 0x69, - (byte) 0x12, (byte) 0x23, (byte) 0x34, (byte) 0x45 - }); - assertEquals(0x2143658710efcdabL, data.readLongLe()); - assertEquals(0x4534231269584736L, data.readLongLe()); - assertEquals(0, data.size()); - } - - @Test public void readLongSplitAcrossMultipleSegments() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8(repeat('a', Segment.SIZE - 7)); - data.write(new byte[] { - (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, - (byte) 0x87, (byte) 0x65, (byte) 0x43, (byte) 0x21, - }); - data.readUtf8(Segment.SIZE - 7); - assertEquals(0xabcdef0187654321L, data.readLong()); - assertEquals(0, data.size()); - } - - @Test public void byteAt() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8("a"); - buffer.writeUtf8(repeat('b', Segment.SIZE)); - buffer.writeUtf8("c"); - assertEquals('a', buffer.getByte(0)); - assertEquals('a', buffer.getByte(0)); // getByte doesn't mutate! - assertEquals('c', buffer.getByte(buffer.size - 1)); - assertEquals('b', buffer.getByte(buffer.size - 2)); - assertEquals('b', buffer.getByte(buffer.size - 3)); - } - - @Test public void getByteOfEmptyBuffer() throws Exception { - OkBuffer buffer = new OkBuffer(); - try { - buffer.getByte(0); - fail(); - } catch (IndexOutOfBoundsException expected) { - } - } - - @Test public void skip() throws Exception { - OkBuffer buffer = new OkBuffer(); - buffer.writeUtf8("a"); - buffer.writeUtf8(repeat('b', Segment.SIZE)); - buffer.writeUtf8("c"); - buffer.skip(1); - assertEquals('b', buffer.readByte() & 0xff); - buffer.skip(Segment.SIZE - 2); - assertEquals('b', buffer.readByte() & 0xff); - buffer.skip(1); - assertEquals(0, buffer.size()); - } - - @Test public void testWritePrefixToEmptyBuffer() { - OkBuffer sink = new OkBuffer(); - OkBuffer source = new OkBuffer(); - source.writeUtf8("abcd"); - sink.write(source, 2); - assertEquals("ab", sink.readUtf8(2)); - } - - @Test public void cloneDoesNotObserveWritesToOriginal() throws Exception { - OkBuffer original = new OkBuffer(); - OkBuffer clone = original.clone(); - original.writeUtf8("abc"); - assertEquals(0, clone.size()); - } - - @Test public void cloneDoesNotObserveReadsFromOriginal() throws Exception { - OkBuffer original = new OkBuffer(); - original.writeUtf8("abc"); - OkBuffer clone = original.clone(); - assertEquals("abc", original.readUtf8(3)); - assertEquals(3, clone.size()); - assertEquals("ab", clone.readUtf8(2)); - } - - @Test public void originalDoesNotObserveWritesToClone() throws Exception { - OkBuffer original = new OkBuffer(); - OkBuffer clone = original.clone(); - clone.writeUtf8("abc"); - assertEquals(0, original.size()); - } - - @Test public void originalDoesNotObserveReadsFromClone() throws Exception { - OkBuffer original = new OkBuffer(); - original.writeUtf8("abc"); - OkBuffer clone = original.clone(); - assertEquals("abc", clone.readUtf8(3)); - assertEquals(3, original.size()); - assertEquals("ab", original.readUtf8(2)); - } - - @Test public void cloneMultipleSegments() throws Exception { - OkBuffer original = new OkBuffer(); - original.writeUtf8(repeat('a', Segment.SIZE * 3)); - OkBuffer clone = original.clone(); - original.writeUtf8(repeat('b', Segment.SIZE * 3)); - clone.writeUtf8(repeat('c', Segment.SIZE * 3)); - - assertEquals(repeat('a', Segment.SIZE * 3) + repeat('b', Segment.SIZE * 3), - original.readUtf8(Segment.SIZE * 6)); - assertEquals(repeat('a', Segment.SIZE * 3) + repeat('c', Segment.SIZE * 3), - clone.readUtf8(Segment.SIZE * 6)); - } - - @Test public void testEqualsAndHashCodeEmpty() throws Exception { - OkBuffer a = new OkBuffer(); - OkBuffer b = new OkBuffer(); - assertTrue(a.equals(b)); - assertTrue(a.hashCode() == b.hashCode()); - } - - @Test public void testEqualsAndHashCode() throws Exception { - OkBuffer a = new OkBuffer().writeUtf8("dog"); - OkBuffer b = new OkBuffer().writeUtf8("hotdog"); - assertFalse(a.equals(b)); - assertFalse(a.hashCode() == b.hashCode()); - - b.readUtf8(3); // Leaves b containing 'dog'. - assertTrue(a.equals(b)); - assertTrue(a.hashCode() == b.hashCode()); - } - - @Test public void testEqualsAndHashCodeSpanningSegments() throws Exception { - byte[] data = new byte[1024 * 1024]; - Random dice = new Random(0); - dice.nextBytes(data); - - OkBuffer a = bufferWithRandomSegmentLayout(dice, data); - OkBuffer b = bufferWithRandomSegmentLayout(dice, data); - assertTrue(a.equals(b)); - assertTrue(a.hashCode() == b.hashCode()); - - data[data.length / 2]++; // Change a single byte. - OkBuffer c = bufferWithRandomSegmentLayout(dice, data); - assertFalse(a.equals(c)); - assertFalse(a.hashCode() == c.hashCode()); - } - - /** - * Returns a new buffer containing the data in {@code data}, and a segment - * layout determined by {@code dice}. - */ - private OkBuffer bufferWithRandomSegmentLayout(Random dice, byte[] data) { - OkBuffer result = new OkBuffer(); - - // Writing to result directly will yield packed segments. Instead, write to - // other buffers, then write those buffers to result. - for (int pos = 0, byteCount; pos < data.length; pos += byteCount) { - byteCount = (Segment.SIZE / 2) + dice.nextInt(Segment.SIZE / 2); - if (byteCount > data.length - pos) byteCount = data.length - pos; - int offset = dice.nextInt(Segment.SIZE - byteCount); - - OkBuffer segment = new OkBuffer(); - segment.write(new byte[offset]); - segment.write(data, pos, byteCount); - segment.skip(offset); - - result.write(segment, byteCount); - } - - return result; - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/okio/src/test/java/okio/OkioTest.java b/okio/src/test/java/okio/OkioTest.java deleted file mode 100644 index e56979fe4..000000000 --- a/okio/src/test/java/okio/OkioTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Arrays; -import org.junit.Test; - -import static okio.Util.UTF_8; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public final class OkioTest { - @Test public void sinkFromOutputStream() throws Exception { - OkBuffer data = new OkBuffer(); - data.writeUtf8("a"); - data.writeUtf8(repeat('b', 9998)); - data.writeUtf8("c"); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Sink sink = Okio.sink(out); - sink.write(data, 3); - assertEquals("abb", out.toString("UTF-8")); - sink.write(data, data.size()); - assertEquals("a" + repeat('b', 9998) + "c", out.toString("UTF-8")); - } - - @Test public void sourceFromInputStream() throws Exception { - InputStream in = new ByteArrayInputStream( - ("a" + repeat('b', Segment.SIZE * 2) + "c").getBytes(UTF_8)); - - // Source: ab...bc - Source source = Okio.source(in); - OkBuffer sink = new OkBuffer(); - - // Source: b...bc. Sink: abb. - assertEquals(3, source.read(sink, 3)); - assertEquals("abb", sink.readUtf8(3)); - - // Source: b...bc. Sink: b...b. - assertEquals(Segment.SIZE, source.read(sink, 20000)); - assertEquals(repeat('b', Segment.SIZE), sink.readUtf8(sink.size())); - - // Source: b...bc. Sink: b...bc. - assertEquals(Segment.SIZE - 1, source.read(sink, 20000)); - assertEquals(repeat('b', Segment.SIZE - 2) + "c", sink.readUtf8(sink.size())); - - // Source and sink are empty. - assertEquals(-1, source.read(sink, 1)); - } - - @Test public void sourceFromInputStreamBounds() throws Exception { - Source source = Okio.source(new ByteArrayInputStream(new byte[100])); - try { - source.read(new OkBuffer(), -1); - fail(); - } catch (IllegalArgumentException expected) { - } - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/okio/src/test/java/okio/ReadUtf8LineTest.java b/okio/src/test/java/okio/ReadUtf8LineTest.java deleted file mode 100644 index 79b4c8abd..000000000 --- a/okio/src/test/java/okio/ReadUtf8LineTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -public abstract class ReadUtf8LineTest { - protected abstract BufferedSource newSource(String s); - - @Test public void readLines() throws IOException { - BufferedSource source = newSource("abc\ndef\n"); - assertEquals("abc", source.readUtf8LineStrict()); - assertEquals("def", source.readUtf8LineStrict()); - try { - source.readUtf8LineStrict(); - fail(); - } catch (EOFException expected) { - } - } - - @Test public void emptyLines() throws IOException { - BufferedSource source = newSource("\n\n\n"); - assertEquals("", source.readUtf8LineStrict()); - assertEquals("", source.readUtf8LineStrict()); - assertEquals("", source.readUtf8LineStrict()); - assertTrue(source.exhausted()); - } - - @Test public void crDroppedPrecedingLf() throws IOException { - BufferedSource source = newSource("abc\r\ndef\r\nghi\rjkl\r\n"); - assertEquals("abc", source.readUtf8LineStrict()); - assertEquals("def", source.readUtf8LineStrict()); - assertEquals("ghi\rjkl", source.readUtf8LineStrict()); - } - - @Test public void bufferedReaderCompatible() throws IOException { - BufferedSource source = newSource("abc\ndef"); - assertEquals("abc", source.readUtf8Line()); - assertEquals("def", source.readUtf8Line()); - assertEquals(null, source.readUtf8Line()); - } - - @Test public void bufferedReaderCompatibleWithTrailingNewline() throws IOException { - BufferedSource source = newSource("abc\ndef\n"); - assertEquals("abc", source.readUtf8Line()); - assertEquals("def", source.readUtf8Line()); - assertEquals(null, source.readUtf8Line()); - } -} diff --git a/okio/src/test/java/okio/RealBufferedSinkTest.java b/okio/src/test/java/okio/RealBufferedSinkTest.java deleted file mode 100644 index 80a131736..000000000 --- a/okio/src/test/java/okio/RealBufferedSinkTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import org.junit.Test; - -import static okio.Util.UTF_8; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public final class RealBufferedSinkTest { - @Test public void outputStreamFromSink() throws Exception { - OkBuffer sink = new OkBuffer(); - OutputStream out = new RealBufferedSink(sink).outputStream(); - out.write('a'); - out.write(repeat('b', 9998).getBytes(UTF_8)); - out.write('c'); - out.flush(); - assertEquals("a" + repeat('b', 9998) + "c", sink.readUtf8(10000)); - } - - @Test public void outputStreamFromSinkBounds() throws Exception { - OkBuffer sink = new OkBuffer(); - OutputStream out = new RealBufferedSink(sink).outputStream(); - try { - out.write(new byte[100], 50, 51); - fail(); - } catch (ArrayIndexOutOfBoundsException expected) { - } - } - - @Test public void bufferedSinkEmitsTailWhenItIsComplete() throws IOException { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE - 1)); - assertEquals(0, sink.size()); - bufferedSink.writeByte(0); - assertEquals(Segment.SIZE, sink.size()); - assertEquals(0, bufferedSink.buffer().size()); - } - - @Test public void bufferedSinkEmitZero() throws IOException { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8(""); - assertEquals(0, sink.size()); - } - - @Test public void bufferedSinkEmitMultipleSegments() throws IOException { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 4 - 1)); - assertEquals(Segment.SIZE * 3, sink.size()); - assertEquals(Segment.SIZE - 1, bufferedSink.buffer().size()); - } - - @Test public void bufferedSinkFlush() throws IOException { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeByte('a'); - assertEquals(0, sink.size()); - bufferedSink.flush(); - assertEquals(0, bufferedSink.buffer().size()); - assertEquals(1, sink.size()); - } - - @Test public void bytesEmittedToSinkWithFlush() throws Exception { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8("abc"); - bufferedSink.flush(); - assertEquals(3, sink.size()); - } - - @Test public void bytesNotEmittedToSinkWithoutFlush() throws Exception { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8("abc"); - assertEquals(0, sink.size()); - } - - @Test public void completeSegmentsEmitted() throws Exception { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3)); - assertEquals(Segment.SIZE * 3, sink.size()); - } - - @Test public void incompleteSegmentsNotEmitted() throws Exception { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3 - 1)); - assertEquals(Segment.SIZE * 2, sink.size()); - } - - @Test public void closeEmitsBufferedBytes() throws IOException { - OkBuffer sink = new OkBuffer(); - BufferedSink bufferedSink = new RealBufferedSink(sink); - bufferedSink.writeByte('a'); - bufferedSink.close(); - assertEquals('a', sink.readByte()); - } - - @Test public void closeWithExceptionWhenWriting() throws IOException { - MockSink mockSink = new MockSink(); - mockSink.scheduleThrow(0, new IOException()); - BufferedSink bufferedSink = new RealBufferedSink(mockSink); - bufferedSink.writeByte('a'); - try { - bufferedSink.close(); - fail(); - } catch (IOException expected) { - } - mockSink.assertLog("write(OkBuffer[size=1 data=61], 1)", "close()"); - } - - @Test public void closeWithExceptionWhenClosing() throws IOException { - MockSink mockSink = new MockSink(); - mockSink.scheduleThrow(1, new IOException()); - BufferedSink bufferedSink = new RealBufferedSink(mockSink); - bufferedSink.writeByte('a'); - try { - bufferedSink.close(); - fail(); - } catch (IOException expected) { - } - mockSink.assertLog("write(OkBuffer[size=1 data=61], 1)", "close()"); - } - - @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException { - MockSink mockSink = new MockSink(); - mockSink.scheduleThrow(0, new IOException("first")); - mockSink.scheduleThrow(1, new IOException("second")); - BufferedSink bufferedSink = new RealBufferedSink(mockSink); - bufferedSink.writeByte('a'); - try { - bufferedSink.close(); - fail(); - } catch (IOException expected) { - assertEquals("first", expected.getMessage()); - } - mockSink.assertLog("write(OkBuffer[size=1 data=61], 1)", "close()"); - } - - @Test public void operationsAfterClose() throws IOException { - MockSink mockSink = new MockSink(); - BufferedSink bufferedSink = new RealBufferedSink(mockSink); - bufferedSink.writeByte('a'); - bufferedSink.close(); - - // Test a sample set of methods. - try { - bufferedSink.writeByte('a'); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSink.write(new byte[10]); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSink.emitCompleteSegments(); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSink.flush(); - fail(); - } catch (IllegalStateException expected) { - } - - // Test a sample set of methods on the OutputStream. - OutputStream os = bufferedSink.outputStream(); - try { - os.write('a'); - fail(); - } catch (IOException expected) { - } - - try { - os.write(new byte[10]); - fail(); - } catch (IOException expected) { - } - - // Permitted - os.flush(); - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/okio/src/test/java/okio/RealBufferedSourceReadUtf8LineTest.java b/okio/src/test/java/okio/RealBufferedSourceReadUtf8LineTest.java deleted file mode 100644 index 8793640b1..000000000 --- a/okio/src/test/java/okio/RealBufferedSourceReadUtf8LineTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.IOException; - -public final class RealBufferedSourceReadUtf8LineTest extends ReadUtf8LineTest { - /** Returns a buffered source that gets bytes of {@code data} one at a time. */ - @Override protected BufferedSource newSource(String s) { - final OkBuffer buffer = new OkBuffer().writeUtf8(s); - - Source slowSource = new Source() { - @Override public long read(OkBuffer sink, long byteCount) throws IOException { - return buffer.read(sink, Math.min(1, byteCount)); - } - - @Override public Source deadline(Deadline deadline) { - throw new UnsupportedOperationException(); - } - - @Override public void close() throws IOException { - throw new UnsupportedOperationException(); - } - }; - - return Okio.buffer(slowSource); - } -} diff --git a/okio/src/test/java/okio/RealBufferedSourceTest.java b/okio/src/test/java/okio/RealBufferedSourceTest.java deleted file mode 100644 index a77eaf280..000000000 --- a/okio/src/test/java/okio/RealBufferedSourceTest.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import org.junit.Test; - -import static okio.Util.UTF_8; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -public final class RealBufferedSourceTest { - @Test public void inputStreamFromSource() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("a"); - source.writeUtf8(repeat('b', Segment.SIZE)); - source.writeUtf8("c"); - - InputStream in = new RealBufferedSource(source).inputStream(); - assertEquals(0, in.available()); - assertEquals(Segment.SIZE + 2, source.size()); - - // Reading one byte buffers a full segment. - assertEquals('a', in.read()); - assertEquals(Segment.SIZE - 1, in.available()); - assertEquals(2, source.size()); - - // Reading as much as possible reads the rest of that buffered segment. - byte[] data = new byte[Segment.SIZE * 2]; - assertEquals(Segment.SIZE - 1, in.read(data, 0, data.length)); - assertEquals(repeat('b', Segment.SIZE - 1), new String(data, 0, Segment.SIZE - 1, UTF_8)); - assertEquals(2, source.size()); - - // Continuing to read buffers the next segment. - assertEquals('b', in.read()); - assertEquals(1, in.available()); - assertEquals(0, source.size()); - - // Continuing to read reads from the buffer. - assertEquals('c', in.read()); - assertEquals(0, in.available()); - assertEquals(0, source.size()); - - // Once we've exhausted the source, we're done. - assertEquals(-1, in.read()); - assertEquals(0, source.size()); - } - - @Test public void inputStreamFromSourceBounds() throws IOException { - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', 100)); - InputStream in = new RealBufferedSource(source).inputStream(); - try { - in.read(new byte[100], 50, 51); - fail(); - } catch (ArrayIndexOutOfBoundsException expected) { - } - } - - @Test public void requireTracksBufferFirst() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("bb"); - - BufferedSource bufferedSource = new RealBufferedSource(source); - bufferedSource.buffer().writeUtf8("aa"); - - bufferedSource.require(2); - assertEquals(2, bufferedSource.buffer().size()); - assertEquals(2, source.size()); - } - - @Test public void requireIncludesBufferBytes() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("b"); - - BufferedSource bufferedSource = new RealBufferedSource(source); - bufferedSource.buffer().writeUtf8("a"); - - bufferedSource.require(2); - assertEquals("ab", bufferedSource.buffer().readUtf8(2)); - } - - @Test public void requireInsufficientData() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("a"); - - BufferedSource bufferedSource = new RealBufferedSource(source); - - try { - bufferedSource.require(2); - fail(); - } catch (EOFException expected) { - } - } - - @Test public void requireReadsOneSegmentAtATime() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE)); - source.writeUtf8(repeat('b', Segment.SIZE)); - - BufferedSource bufferedSource = new RealBufferedSource(source); - - bufferedSource.require(2); - assertEquals(Segment.SIZE, source.size()); - assertEquals(Segment.SIZE, bufferedSource.buffer().size()); - } - - @Test public void skipInsufficientData() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("a"); - - BufferedSource bufferedSource = new RealBufferedSource(source); - try { - bufferedSource.skip(2); - fail(); - } catch (EOFException expected) { - } - } - - @Test public void skipReadsOneSegmentAtATime() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8(repeat('a', Segment.SIZE)); - source.writeUtf8(repeat('b', Segment.SIZE)); - BufferedSource bufferedSource = new RealBufferedSource(source); - bufferedSource.skip(2); - assertEquals(Segment.SIZE, source.size()); - assertEquals(Segment.SIZE - 2, bufferedSource.buffer().size()); - } - - @Test public void skipTracksBufferFirst() throws Exception { - OkBuffer source = new OkBuffer(); - source.writeUtf8("bb"); - - BufferedSource bufferedSource = new RealBufferedSource(source); - bufferedSource.buffer().writeUtf8("aa"); - - bufferedSource.skip(2); - assertEquals(0, bufferedSource.buffer().size()); - assertEquals(2, source.size()); - } - - @Test public void operationsAfterClose() throws IOException { - OkBuffer source = new OkBuffer(); - BufferedSource bufferedSource = new RealBufferedSource(source); - bufferedSource.close(); - - // Test a sample set of methods. - try { - bufferedSource.indexOf((byte) 1); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSource.skip(1); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSource.readByte(); - fail(); - } catch (IllegalStateException expected) { - } - - try { - bufferedSource.readByteString(10); - fail(); - } catch (IllegalStateException expected) { - } - - // Test a sample set of methods on the InputStream. - InputStream is = bufferedSource.inputStream(); - try { - is.read(); - fail(); - } catch (IOException expected) { - } - - try { - is.read(new byte[10]); - fail(); - } catch (IOException expected) { - } - } - - private String repeat(char c, int count) { - char[] array = new char[count]; - Arrays.fill(array, c); - return new String(array); - } -} diff --git a/pom.xml b/pom.xml index c534a1d3f..c76be8e77 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,6 @@ okhttp-apache okhttp-tests okcurl - okio mockwebserver samples benchmarks @@ -34,6 +33,7 @@ 1.6 + 0.6.0 8.1.2.v20120308 1.48 2.2.3 @@ -66,6 +66,11 @@ + + com.squareup.okio + okio + ${okio.version} + org.mortbay.jetty.npn npn-boot