mirror of
https://github.com/square/okhttp.git
synced 2026-01-21 03:41:07 +03:00
Merge pull request #553 from square/jwilson_0222_hex
OkBuffer toString and hex.
This commit is contained in:
@@ -63,7 +63,7 @@ import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
|
||||
import static com.squareup.okhttp.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
|
||||
import static com.squareup.okhttp.mockwebserver.SocketPolicy.FAIL_HANDSHAKE;
|
||||
@@ -656,7 +656,7 @@ public final class MockWebServer {
|
||||
}
|
||||
}
|
||||
|
||||
InputStream bodyIn = OkBuffers.buffer(stream.getSource()).inputStream();
|
||||
InputStream bodyIn = Okio.buffer(stream.getSource()).inputStream();
|
||||
ByteArrayOutputStream bodyOut = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int count;
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffer;
|
||||
import okio.Sink;
|
||||
import okio.Source;
|
||||
@@ -57,9 +58,6 @@ public 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 static final char[] DIGITS =
|
||||
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
private Util() {
|
||||
}
|
||||
|
||||
@@ -303,7 +301,7 @@ public final class Util {
|
||||
try {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
|
||||
byte[] md5bytes = messageDigest.digest(s.getBytes("UTF-8"));
|
||||
return bytesToHexString(md5bytes);
|
||||
return ByteString.of(md5bytes).hex();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
@@ -311,17 +309,6 @@ public final class Util {
|
||||
}
|
||||
}
|
||||
|
||||
private static String bytesToHexString(byte[] bytes) {
|
||||
char[] digits = DIGITS;
|
||||
char[] buf = new char[bytes.length * 2];
|
||||
int c = 0;
|
||||
for (byte b : bytes) {
|
||||
buf[c++] = digits[(b >> 4) & 0xf];
|
||||
buf[c++] = digits[b & 0xf];
|
||||
}
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
/** Returns an immutable copy of {@code list}. */
|
||||
public static <T> List<T> immutableList(List<T> list) {
|
||||
return Collections.unmodifiableList(new ArrayList<T>(list));
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
/**
|
||||
@@ -125,7 +125,7 @@ final class HpackDraft05 {
|
||||
Reader(boolean client, int maxHeaderTableByteCount, Source source) {
|
||||
this.huffmanCodec = client ? Huffman.Codec.RESPONSE : Huffman.Codec.REQUEST;
|
||||
this.maxHeaderTableByteCount = maxHeaderTableByteCount;
|
||||
this.source = OkBuffers.buffer(source);
|
||||
this.source = Okio.buffer(source);
|
||||
}
|
||||
|
||||
int maxHeaderTableByteCount() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import okio.ByteString;
|
||||
import okio.Deadline;
|
||||
import okio.InflaterSource;
|
||||
import okio.OkBuffer;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
/**
|
||||
@@ -70,7 +70,7 @@ class NameValueBlockReader {
|
||||
};
|
||||
|
||||
this.inflaterSource = new InflaterSource(throttleSource, inflater);
|
||||
this.source = OkBuffers.buffer(inflaterSource);
|
||||
this.source = Okio.buffer(inflaterSource);
|
||||
}
|
||||
|
||||
public List<Header> readNameValueBlock(int length) throws IOException {
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
|
||||
/**
|
||||
* A socket connection to a remote peer. A connection hosts streams which can
|
||||
@@ -464,7 +464,7 @@ public final class SpdyConnection implements Closeable {
|
||||
private boolean client;
|
||||
|
||||
public Builder(boolean client, Socket socket) throws IOException {
|
||||
this("", client, OkBuffers.buffer(OkBuffers.source(socket.getInputStream())),
|
||||
this("", client, Okio.buffer(Okio.source(socket.getInputStream())),
|
||||
socket.getOutputStream());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,18 @@ 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 equals() throws Exception {
|
||||
ByteString byteString = ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2);
|
||||
ByteString byteString = ByteString.decodeHex("000102");
|
||||
assertTrue(byteString.equals(byteString));
|
||||
assertTrue(byteString.equals(ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2)));
|
||||
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.of((byte) 0x0, (byte) 0x2, (byte) 0x1)));
|
||||
assertFalse(byteString.equals(ByteString.decodeHex("000201")));
|
||||
}
|
||||
|
||||
private final String bronzeHorseman = "На берегу пустынных волн";
|
||||
@@ -58,15 +59,15 @@ public class ByteStringTest {
|
||||
}
|
||||
|
||||
@Test public void testHashCode() throws Exception {
|
||||
ByteString byteString = ByteString.of((byte) 0x1, (byte) 0x2);
|
||||
ByteString byteString = ByteString.decodeHex("0102");
|
||||
assertEquals(byteString.hashCode(), byteString.hashCode());
|
||||
assertEquals(byteString.hashCode(), ByteString.of((byte) 0x1, (byte) 0x2).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.of((byte) 0x61, (byte) 0x62), ByteString.read(in, 2));
|
||||
assertEquals(ByteString.of((byte) 0x63), ByteString.read(in, 1));
|
||||
assertEquals(ByteString.decodeHex("6162"), ByteString.read(in, 2));
|
||||
assertEquals(ByteString.decodeHex("63"), ByteString.read(in, 1));
|
||||
assertEquals(ByteString.of(), ByteString.read(in, 0));
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ public class ByteStringTest {
|
||||
|
||||
@Test public void write() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ByteString.of((byte) 0x61, (byte) 0x62, (byte) 0x63).write(out);
|
||||
ByteString.decodeHex("616263").write(out);
|
||||
assertByteArraysEquals(new byte[] { 0x61, 0x62, 0x63 }, out.toByteArray());
|
||||
}
|
||||
|
||||
@@ -123,16 +124,16 @@ public class ByteStringTest {
|
||||
@Test public void decodeBase64() {
|
||||
assertEquals("", ByteString.decodeBase64("").utf8());
|
||||
assertEquals(null, ByteString.decodeBase64("/===")); // Can't do anything with 6 bits!
|
||||
assertEquals(bytes(0xff), ByteString.decodeBase64("//=="));
|
||||
assertEquals(bytes(0xff, 0xff), ByteString.decodeBase64("///="));
|
||||
assertEquals(bytes(0xff, 0xff, 0xff), ByteString.decodeBase64("////"));
|
||||
assertEquals(bytes(0xff, 0xff, 0xff, 0xff, 0xff, 0xff), ByteString.decodeBase64("////////"));
|
||||
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 decodeWithWhitespace() {
|
||||
@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());
|
||||
@@ -142,13 +143,28 @@ public class ByteStringTest {
|
||||
assertEquals("", ByteString.decodeBase64(" ").utf8());
|
||||
}
|
||||
|
||||
/** Make it easy to make varargs calls. Otherwise we need a lot of (byte) casts. */
|
||||
private ByteString bytes(int... bytes) {
|
||||
byte[] result = new byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
result[i] = (byte) bytes[i];
|
||||
@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) {
|
||||
}
|
||||
return ByteString.of(result);
|
||||
}
|
||||
|
||||
private static void assertByteArraysEquals(byte[] a, byte[] b) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -800,7 +800,7 @@ public class HpackDraft05Test {
|
||||
}
|
||||
|
||||
private HpackDraft05.Reader newReader(InputStream input) {
|
||||
return new HpackDraft05.Reader(false, 4096, OkBuffers.source(input));
|
||||
return new HpackDraft05.Reader(false, 4096, Okio.source(input));
|
||||
}
|
||||
|
||||
private InputStream byteStream(int... bytes) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
|
||||
/** Replays prerecorded outgoing frames and records incoming frames. */
|
||||
public final class MockSpdyPeer implements Closeable {
|
||||
@@ -118,7 +118,7 @@ public final class MockSpdyPeer implements Closeable {
|
||||
socket = serverSocket.accept();
|
||||
OutputStream out = socket.getOutputStream();
|
||||
InputStream in = socket.getInputStream();
|
||||
FrameReader reader = variant.newReader(OkBuffers.buffer(OkBuffers.source(in)), client);
|
||||
FrameReader reader = variant.newReader(Okio.buffer(Okio.source(in)), client);
|
||||
|
||||
Iterator<OutFrame> outFramesIterator = outFrames.iterator();
|
||||
byte[] outBytes = bytesOut.toByteArray();
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffer;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -1252,7 +1252,7 @@ public final class SpdyConnectionTest {
|
||||
assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
|
||||
Source in = stream.getSource();
|
||||
try {
|
||||
OkBuffers.buffer(in).readByteString(101);
|
||||
Okio.buffer(in).readByteString(101);
|
||||
fail();
|
||||
} catch (IOException expected) {
|
||||
assertEquals("stream was reset: PROTOCOL_ERROR", expected.getMessage());
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.net.SocketTimeoutException;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
|
||||
import static java.net.HttpURLConnection.HTTP_OK;
|
||||
import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
|
||||
@@ -306,7 +306,7 @@ public final class Connection implements Closeable {
|
||||
* retried if the proxy requires authorization.
|
||||
*/
|
||||
private void makeTunnel(TunnelRequest tunnelRequest) throws IOException {
|
||||
BufferedSource tunnelSource = OkBuffers.buffer(OkBuffers.source(in));
|
||||
BufferedSource tunnelSource = Okio.buffer(Okio.source(in));
|
||||
HttpConnection tunnelConnection = new HttpConnection(pool, this, tunnelSource, out);
|
||||
Request request = tunnelRequest.getRequest();
|
||||
String requestLine = tunnelRequest.requestLine();
|
||||
@@ -338,7 +338,7 @@ public final class Connection implements Closeable {
|
||||
}
|
||||
|
||||
private void streamWrapper() throws IOException {
|
||||
source = OkBuffers.buffer(OkBuffers.source(in));
|
||||
source = Okio.buffer(Okio.source(in));
|
||||
out = new BufferedOutputStream(out, 256);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.io.InputStream;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static com.squareup.okhttp.internal.Util.getEffectivePort;
|
||||
@@ -264,7 +264,7 @@ final class Job extends NamedRunnable {
|
||||
InputStream result = in;
|
||||
return result != null
|
||||
? result
|
||||
: (in = OkBuffers.buffer(source).inputStream());
|
||||
: (in = Okio.buffer(source).inputStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static com.squareup.okhttp.internal.Util.UTF_8;
|
||||
@@ -221,7 +221,7 @@ public final class Response {
|
||||
// TODO: Source needs to be an API type for this to be public
|
||||
public Source source() {
|
||||
Source s = source;
|
||||
return s != null ? s : (source = OkBuffers.source(byteStream()));
|
||||
return s != null ? s : (source = Okio.source(byteStream()));
|
||||
}
|
||||
|
||||
public final byte[] bytes() throws IOException {
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.net.Socket;
|
||||
import okio.BufferedSource;
|
||||
import okio.Deadline;
|
||||
import okio.OkBuffer;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static com.squareup.okhttp.internal.Util.checkOffsetAndCount;
|
||||
@@ -425,7 +425,7 @@ 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 {
|
||||
if (cacheBody != null) {
|
||||
OkBuffers.copy(source, source.byteCount() - byteCount, byteCount, cacheBody);
|
||||
Okio.copy(source, source.byteCount() - byteCount, byteCount, cacheBody);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import okio.GzipSource;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static com.squareup.okhttp.internal.Util.closeQuietly;
|
||||
@@ -290,7 +290,7 @@ public class HttpEngine {
|
||||
InputStream result = responseBodyBytes;
|
||||
return result != null
|
||||
? result
|
||||
: (responseBodyBytes = OkBuffers.buffer(getResponseBody()).inputStream());
|
||||
: (responseBodyBytes = Okio.buffer(getResponseBody()).inputStream());
|
||||
}
|
||||
|
||||
public final Connection getConnection() {
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.Set;
|
||||
import okio.ByteString;
|
||||
import okio.Deadline;
|
||||
import okio.OkBuffer;
|
||||
import okio.OkBuffers;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static com.squareup.okhttp.internal.spdy.Header.RESPONSE_STATUS;
|
||||
@@ -273,7 +273,7 @@ public final class SpdyTransport implements Transport {
|
||||
}
|
||||
|
||||
if (cacheBody != null) {
|
||||
OkBuffers.copy(sink, sink.byteCount() - read, read, cacheBody);
|
||||
Okio.copy(sink, sink.byteCount() - read, read, cacheBody);
|
||||
}
|
||||
|
||||
return read;
|
||||
|
||||
@@ -32,6 +32,9 @@ import java.util.Arrays;
|
||||
* 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' };
|
||||
|
||||
final byte[] data;
|
||||
private transient int hashCode; // Lazily computed; 0 if unknown.
|
||||
private transient String utf8; // Lazily computed.
|
||||
@@ -78,6 +81,37 @@ public final class ByteString {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when {@code ascii} is not null and equals the bytes wrapped
|
||||
* by this byte string.
|
||||
|
||||
@@ -40,7 +40,7 @@ public final class DeflaterSink implements Sink {
|
||||
private final Deflater deflater;
|
||||
|
||||
public DeflaterSink(Sink sink, Deflater deflater) {
|
||||
this.sink = OkBuffers.buffer(sink);
|
||||
this.sink = Okio.buffer(sink);
|
||||
this.deflater = deflater;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public final class GzipSource implements Source {
|
||||
|
||||
public GzipSource(Source source) throws IOException {
|
||||
this.inflater = new Inflater(true);
|
||||
this.source = OkBuffers.buffer(source);
|
||||
this.source = Okio.buffer(source);
|
||||
this.inflaterSource = new InflaterSource(this.source, inflater);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public final class InflaterSource implements Source {
|
||||
private boolean closed;
|
||||
|
||||
public InflaterSource(Source source, Inflater inflater) {
|
||||
this(OkBuffers.buffer(source), inflater);
|
||||
this(Okio.buffer(source), inflater);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ package okio;
|
||||
import java.io.EOFException;
|
||||
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;
|
||||
@@ -41,9 +43,6 @@ import static okio.Util.checkOffsetAndCount;
|
||||
* This class avoids zero-fill and GC churn by pooling byte arrays.
|
||||
*/
|
||||
public final class OkBuffer implements BufferedSource, BufferedSink, Cloneable {
|
||||
private static final char[] HEX_DIGITS =
|
||||
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
Segment head;
|
||||
long byteCount;
|
||||
|
||||
@@ -579,22 +578,27 @@ public final class OkBuffer implements BufferedSource, BufferedSink, Cloneable {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of this buffer in hex. For buffers larger than 1 MiB
|
||||
* this method is undefined.
|
||||
*/
|
||||
@Override public String toString() {
|
||||
if (byteCount > 0x100000) return super.toString();
|
||||
int charCount = (int) (byteCount * 2);
|
||||
char[] result = new char[charCount];
|
||||
int offset = 0;
|
||||
for (Segment s = head; offset < charCount; s = s.next) {
|
||||
for (int i = s.pos; i < s.limit; i++) {
|
||||
result[offset++] = HEX_DIGITS[(s.data[i] >> 4) & 0xf];
|
||||
result[offset++] = HEX_DIGITS[s.data[i] & 0xf];
|
||||
}
|
||||
if (byteCount == 0) {
|
||||
return "OkBuffer[size=0]";
|
||||
}
|
||||
|
||||
if (byteCount <= 16) {
|
||||
ByteString data = clone().readByteString((int) byteCount);
|
||||
return String.format("OkBuffer[size=%s data=%s]", byteCount, 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]",
|
||||
byteCount, ByteString.of(md5.digest()).hex());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
/** Returns a deep copy of this buffer. */
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.io.OutputStream;
|
||||
|
||||
import static okio.Util.checkOffsetAndCount;
|
||||
|
||||
public final class OkBuffers {
|
||||
private OkBuffers() {
|
||||
public final class Okio {
|
||||
private Okio() {
|
||||
}
|
||||
|
||||
public static BufferedSource buffer(Source source) {
|
||||
@@ -16,7 +16,6 @@
|
||||
package okio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -30,51 +29,52 @@ public class GzipSourceTest {
|
||||
|
||||
@Test public void gunzip() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeader, 0, gzipHeader.length);
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(gzipHeader);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@Test public void gunzip_withHCRC() throws Exception {
|
||||
CRC32 hcrc = new CRC32();
|
||||
hcrc.update(gzipHeaderWithFlags((byte) 0x02));
|
||||
ByteString gzipHeader = gzipHeaderWithFlags((byte) 0x02);
|
||||
hcrc.update(gzipHeader.toByteArray());
|
||||
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x02), 0, gzipHeader.length);
|
||||
gzipped.write(gzipHeader);
|
||||
gzipped.writeShort(Util.reverseBytesShort((short) hcrc.getValue())); // little endian
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@Test public void gunzip_withExtra() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x04), 0, gzipHeader.length);
|
||||
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, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@Test public void gunzip_withName() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x08), 0, gzipHeader.length);
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x08));
|
||||
gzipped.write("foo.txt".getBytes(UTF_8), 0, 7);
|
||||
gzipped.writeByte(0); // zero-terminated
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@Test public void gunzip_withComment() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x10), 0, gzipHeader.length);
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x10));
|
||||
gzipped.write("rubbish".getBytes(UTF_8), 0, 7);
|
||||
gzipped.writeByte(0); // zero-terminated
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@@ -84,15 +84,15 @@ public class GzipSourceTest {
|
||||
*/
|
||||
@Test public void gunzip_withAll() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x1c), 0, gzipHeader.length);
|
||||
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, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
assertGzipped(gzipped);
|
||||
}
|
||||
|
||||
@@ -108,10 +108,10 @@ public class GzipSourceTest {
|
||||
*/
|
||||
@Test public void gunzipWhenHeaderCRCIncorrect() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x02), 0, gzipHeader.length);
|
||||
gzipped.write(gzipHeaderWithFlags((byte) 0x02));
|
||||
gzipped.writeShort((short) 0); // wrong HCRC!
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, gzipTrailer.length);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer);
|
||||
|
||||
try {
|
||||
gunzip(gzipped);
|
||||
@@ -123,10 +123,10 @@ public class GzipSourceTest {
|
||||
|
||||
@Test public void gunzipWhenCRCIncorrect() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeader, 0, gzipHeader.length);
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipHeader);
|
||||
gzipped.write(deflated);
|
||||
gzipped.writeInt(Util.reverseBytesInt(0x1234567)); // wrong CRC
|
||||
gzipped.write(gzipTrailer, 3, 4);
|
||||
gzipped.write(gzipTrailer.toByteArray(), 3, 4);
|
||||
|
||||
try {
|
||||
gunzip(gzipped);
|
||||
@@ -138,9 +138,9 @@ public class GzipSourceTest {
|
||||
|
||||
@Test public void gunzipWhenLengthIncorrect() throws Exception {
|
||||
OkBuffer gzipped = new OkBuffer();
|
||||
gzipped.write(gzipHeader, 0, gzipHeader.length);
|
||||
gzipped.write(deflated, 0, deflated.length);
|
||||
gzipped.write(gzipTrailer, 0, 4);
|
||||
gzipped.write(gzipHeader);
|
||||
gzipped.write(deflated);
|
||||
gzipped.write(gzipTrailer.toByteArray(), 0, 4);
|
||||
gzipped.writeInt(Util.reverseBytesInt(0x123456)); // wrong length
|
||||
|
||||
try {
|
||||
@@ -152,17 +152,11 @@ public class GzipSourceTest {
|
||||
}
|
||||
|
||||
@Test public void gunzipExhaustsSource() throws Exception {
|
||||
byte[] abcGzipped = {
|
||||
(byte) 0x1f, (byte) 0x8b, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x4b, (byte) 0x4c, (byte) 0x4a, (byte) 0x06,
|
||||
(byte) 0x00, (byte) 0xc2, (byte) 0x41, (byte) 0x24, (byte) 0x35, (byte) 0x03, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00
|
||||
};
|
||||
OkBuffer gzippedSource = new OkBuffer();
|
||||
gzippedSource.write(abcGzipped, 0, abcGzipped.length);
|
||||
OkBuffer gzippedSource = new OkBuffer()
|
||||
.write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
|
||||
|
||||
ExhaustableSource exhaustableSource = new ExhaustableSource(gzippedSource);
|
||||
BufferedSource gunzippedSource = OkBuffers.buffer(new GzipSource(exhaustableSource));
|
||||
BufferedSource gunzippedSource = Okio.buffer(new GzipSource(exhaustableSource));
|
||||
|
||||
assertEquals('a', gunzippedSource.readByte());
|
||||
assertEquals('b', gunzippedSource.readByte());
|
||||
@@ -173,17 +167,11 @@ public class GzipSourceTest {
|
||||
}
|
||||
|
||||
@Test public void gunzipThrowsIfSourceIsNotExhausted() throws Exception {
|
||||
byte[] abcGzipped = {
|
||||
(byte) 0x1f, (byte) 0x8b, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x4b, (byte) 0x4c, (byte) 0x4a, (byte) 0x06,
|
||||
(byte) 0x00, (byte) 0xc2, (byte) 0x41, (byte) 0x24, (byte) 0x35, (byte) 0x03, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x00
|
||||
};
|
||||
OkBuffer gzippedSource = new OkBuffer();
|
||||
gzippedSource.write(abcGzipped, 0, abcGzipped.length);
|
||||
OkBuffer gzippedSource = new OkBuffer()
|
||||
.write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
|
||||
gzippedSource.writeByte('d'); // This byte shouldn't be here!
|
||||
|
||||
BufferedSource gunzippedSource = OkBuffers.buffer(new GzipSource(gzippedSource));
|
||||
BufferedSource gunzippedSource = Okio.buffer(new GzipSource(gzippedSource));
|
||||
|
||||
assertEquals('a', gunzippedSource.readByte());
|
||||
assertEquals('b', gunzippedSource.readByte());
|
||||
@@ -195,29 +183,22 @@ public class GzipSourceTest {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] gzipHeaderWithFlags(byte flags) {
|
||||
byte[] result = Arrays.copyOf(gzipHeader, gzipHeader.length);
|
||||
private ByteString gzipHeaderWithFlags(byte flags) {
|
||||
byte[] result = gzipHeader.toByteArray();
|
||||
result[3] = flags;
|
||||
return result;
|
||||
return ByteString.of(result);
|
||||
}
|
||||
|
||||
private final byte[] gzipHeader = new byte[] {
|
||||
(byte) 0x1f, (byte) 0x8b, (byte) 0x08, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
private final ByteString gzipHeader = ByteString.decodeHex("1f8b0800000000000000");
|
||||
|
||||
// deflated "It's a UNIX system! I know this!"
|
||||
private final byte[] deflated = new byte[] {
|
||||
(byte) 0xf3, (byte) 0x2c, (byte) 0x51, (byte) 0x2f, (byte) 0x56, (byte) 0x48, (byte) 0x54,
|
||||
(byte) 0x08, (byte) 0xf5, (byte) 0xf3, (byte) 0x8c, (byte) 0x50, (byte) 0x28, (byte) 0xae,
|
||||
(byte) 0x2c, (byte) 0x2e, (byte) 0x49, (byte) 0xcd, (byte) 0x55, (byte) 0x54, (byte) 0xf0,
|
||||
(byte) 0x54, (byte) 0xc8, (byte) 0xce, (byte) 0xcb, (byte) 0x2f, (byte) 0x57, (byte) 0x28,
|
||||
(byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x56, (byte) 0x04, (byte) 0x00
|
||||
};
|
||||
// Deflated "It's a UNIX system! I know this!"
|
||||
private final ByteString deflated = ByteString.decodeHex(
|
||||
"f32c512f56485408f5f38c5028ae2c2e49cd5554f054c8cecb2f5728c9c82c560400");
|
||||
|
||||
private final byte[] gzipTrailer = new byte[] {
|
||||
(byte) 0x8d, (byte) 0x8f, (byte) 0xad, (byte) 0x37, // checksum of deflated
|
||||
0x20, 0, 0, 0, // 32 in little endian
|
||||
};
|
||||
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();
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class InflaterSourceTest {
|
||||
/** Use DeflaterOutputStream to deflate source. */
|
||||
private OkBuffer deflate(ByteString source) throws IOException {
|
||||
OkBuffer result = new OkBuffer();
|
||||
Sink sink = OkBuffers.sink(new DeflaterOutputStream(result.outputStream()));
|
||||
Sink sink = Okio.sink(new DeflaterOutputStream(result.outputStream()));
|
||||
sink.write(new OkBuffer().write(source), source.size());
|
||||
sink.close();
|
||||
return result;
|
||||
|
||||
@@ -15,14 +15,10 @@
|
||||
*/
|
||||
package okio;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
import static okio.Util.UTF_8;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -75,10 +71,27 @@ public final class OkBufferTest {
|
||||
assertEquals(repeat('a', Segment.SIZE), buffer.readUtf8(Segment.SIZE));
|
||||
}
|
||||
|
||||
@Test public void bufferToString() throws Exception {
|
||||
@Test public void toStringOnEmptyBuffer() throws Exception {
|
||||
OkBuffer buffer = new OkBuffer();
|
||||
buffer.writeUtf8("\u0000\u0001\u0002\u007f");
|
||||
assertEquals("0001027f", buffer.toString());
|
||||
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 toStringIncludesMd5() 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 {
|
||||
@@ -325,58 +338,11 @@ public final class OkBufferTest {
|
||||
assertEquals(halfSegment * 4 - 1, buffer.indexOf((byte) 'd', halfSegment * 4 - 1));
|
||||
}
|
||||
|
||||
@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 = OkBuffers.sink(out);
|
||||
sink.write(data, 3);
|
||||
assertEquals("abb", out.toString("UTF-8"));
|
||||
sink.write(data, data.byteCount());
|
||||
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 = OkBuffers.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((int) sink.byteCount()));
|
||||
|
||||
// Source: b...bc. Sink: b...bc.
|
||||
assertEquals(Segment.SIZE - 1, source.read(sink, 20000));
|
||||
assertEquals(repeat('b', Segment.SIZE - 2) + "c", sink.readUtf8((int) sink.byteCount()));
|
||||
|
||||
// Source and sink are empty.
|
||||
assertEquals(-1, source.read(sink, 1));
|
||||
}
|
||||
|
||||
@Test public void sourceFromInputStreamBounds() throws Exception {
|
||||
Source source = OkBuffers.source(new ByteArrayInputStream(new byte[100]));
|
||||
try {
|
||||
source.read(new OkBuffer(), -1);
|
||||
fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void writeBytes() throws Exception {
|
||||
OkBuffer data = new OkBuffer();
|
||||
data.writeByte(0xab);
|
||||
data.writeByte(0xcd);
|
||||
assertEquals("abcd", data.toString());
|
||||
assertEquals("OkBuffer[size=2 data=abcd]", data.toString());
|
||||
}
|
||||
|
||||
@Test public void writeLastByteInSegment() throws Exception {
|
||||
@@ -386,21 +352,21 @@ public final class OkBufferTest {
|
||||
data.writeByte(0x21);
|
||||
assertEquals(asList(Segment.SIZE, 1), data.segmentSizes());
|
||||
assertEquals(repeat('a', Segment.SIZE - 1), data.readUtf8(Segment.SIZE - 1));
|
||||
assertEquals("2021", data.toString());
|
||||
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("abcd4321", data.toString());
|
||||
assertEquals("OkBuffer[size=4 data=abcd4321]", data.toString());
|
||||
}
|
||||
|
||||
@Test public void writeInt() throws Exception {
|
||||
OkBuffer data = new OkBuffer();
|
||||
data.writeInt(0xabcdef01);
|
||||
data.writeInt(0x87654321);
|
||||
assertEquals("abcdef0187654321", data.toString());
|
||||
assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString());
|
||||
}
|
||||
|
||||
@Test public void writeLastIntegerInSegment() throws Exception {
|
||||
@@ -410,7 +376,7 @@ public final class OkBufferTest {
|
||||
data.writeInt(0x87654321);
|
||||
assertEquals(asList(Segment.SIZE, 4), data.segmentSizes());
|
||||
assertEquals(repeat('a', Segment.SIZE - 4), data.readUtf8(Segment.SIZE - 4));
|
||||
assertEquals("abcdef0187654321", data.toString());
|
||||
assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString());
|
||||
}
|
||||
|
||||
@Test public void writeIntegerDoesntQuiteFitInSegment() throws Exception {
|
||||
@@ -420,7 +386,7 @@ public final class OkBufferTest {
|
||||
data.writeInt(0x87654321);
|
||||
assertEquals(asList(Segment.SIZE - 3, 8), data.segmentSizes());
|
||||
assertEquals(repeat('a', Segment.SIZE - 3), data.readUtf8(Segment.SIZE - 3));
|
||||
assertEquals("abcdef0187654321", data.toString());
|
||||
assertEquals("OkBuffer[size=8 data=abcdef0187654321]", data.toString());
|
||||
}
|
||||
|
||||
@Test public void readByte() throws Exception {
|
||||
|
||||
81
okio/src/test/java/okio/OkioTest.java
Normal file
81
okio/src/test/java/okio/OkioTest.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.byteCount());
|
||||
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((int) sink.byteCount()));
|
||||
|
||||
// Source: b...bc. Sink: b...bc.
|
||||
assertEquals(Segment.SIZE - 1, source.read(sink, 20000));
|
||||
assertEquals(repeat('b', Segment.SIZE - 2) + "c", sink.readUtf8((int) sink.byteCount()));
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user