/*
 * 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.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import static kotlin.text.Charsets.US_ASCII;
import static kotlin.text.Charsets.UTF_8;
import static kotlin.text.StringsKt.repeat;
import static okio.TestUtil.SEGMENT_SIZE;
import static okio.TestUtil.assertByteArrayEquals;
import static okio.TestUtil.assertByteArraysEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

@RunWith(Parameterized.class)
public final class BufferedSourceTest {
  interface Factory {
    Factory BUFFER = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.sink = buffer;
        result.source = buffer;
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return false;
      }

      @Override public String toString() {
        return "Buffer";
      }
    };

    Factory REAL_BUFFERED_SOURCE = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.sink = buffer;
        result.source = Okio.buffer((Source) buffer);
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return false;
      }

      @Override public String toString() {
        return "RealBufferedSource";
      }
    };

    /**
     * A factory deliberately written to create buffers whose internal segments are always 1 byte
     * long. We like testing with these segments because are likely to trigger bugs!
     */
    Factory ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.sink = buffer;
        result.source = Okio.buffer(new ForwardingSource(buffer) {
          @Override public long read(Buffer sink, long byteCount) throws IOException {
            // Read one byte into a new buffer, then clone it so that the segment is shared.
            // Shared segments cannot be compacted so we'll get a long chain of short segments.
            Buffer box = new Buffer();
            long result = super.read(box, Math.min(byteCount, 1L));
            if (result > 0L) sink.write(box.clone(), result);
            return result;
          }
        });
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return true;
      }

      @Override public String toString() {
        return "OneByteAtATimeBufferedSource";
      }
    };

    Factory ONE_BYTE_AT_A_TIME_BUFFER = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.source = buffer;
        result.sink = Okio.buffer(new ForwardingSink(buffer) {
          @Override public void write(Buffer source, long byteCount) throws IOException {
            // Write each byte into a new buffer, then clone it so that the segments are shared.
            // Shared segments cannot be compacted so we'll get a long chain of short segments.
            for (int i = 0; i < byteCount; i++) {
              Buffer box = new Buffer();
              box.write(source, 1);
              super.write(box.clone(), 1);
            }
          }
        });
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return true;
      }

      @Override public String toString() {
        return "OneByteAtATimeBuffer";
      }
    };

    Factory PEEK_BUFFER = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.sink = buffer;
        result.source = buffer.peek();
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return false;
      }

      @Override public String toString() {
        return "PeekBuffer";
      }
    };

    Factory PEEK_BUFFERED_SOURCE = new Factory() {
      @Override public Pipe pipe() {
        Buffer buffer = new Buffer();
        Pipe result = new Pipe();
        result.sink = buffer;
        result.source = Okio.buffer((Source) buffer).peek();
        return result;
      }

      @Override public boolean isOneByteAtATime() {
        return false;
      }

      @Override public String toString() {
        return "PeekBufferedSource";
      }
    };

    Pipe pipe();

    boolean isOneByteAtATime();
  }

  private static class Pipe {
    BufferedSink sink;
    BufferedSource source;
  }

  @Parameters(name = "{0}")
  public static List<Object[]> parameters() {
    return Arrays.asList(
        new Object[] { Factory.BUFFER },
        new Object[] { Factory.REAL_BUFFERED_SOURCE },
        new Object[] { Factory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE },
        new Object[] { Factory.ONE_BYTE_AT_A_TIME_BUFFER },
        new Object[] { Factory.PEEK_BUFFER },
        new Object[] { Factory.PEEK_BUFFERED_SOURCE });
  }

  @Parameter public Factory factory;
  private BufferedSink sink;
  private BufferedSource source;

  @Before public void setUp() {
    Pipe pipe = factory.pipe();
    sink = pipe.sink;
    source = pipe.source;
  }

  @Test public void readBytes() throws Exception {
    sink.write(new byte[] { (byte) 0xab, (byte) 0xcd });
    sink.emit();
    assertEquals(0xab, source.readByte() & 0xff);
    assertEquals(0xcd, source.readByte() & 0xff);
    assertTrue(source.exhausted());
  }

  @Test public void readByteTooShortThrows() throws IOException {
    try {
      source.readByte();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readShort() throws Exception {
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01
    });
    sink.emit();
    assertEquals((short) 0xabcd, source.readShort());
    assertEquals((short) 0xef01, source.readShort());
    assertTrue(source.exhausted());
  }

  @Test public void readShortLe() throws Exception {
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10
    });
    sink.emit();
    assertEquals((short) 0xcdab, source.readShortLe());
    assertEquals((short) 0x10ef, source.readShortLe());
    assertTrue(source.exhausted());
  }

  @Test public void readShortSplitAcrossMultipleSegments() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
    sink.write(new byte[] { (byte) 0xab, (byte) 0xcd });
    sink.emit();
    source.skip(SEGMENT_SIZE - 1);
    assertEquals((short) 0xabcd, source.readShort());
    assertTrue(source.exhausted());
  }

  @Test public void readShortTooShortThrows() throws IOException {
    sink.writeShort(Short.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readShort();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readShortLeTooShortThrows() throws IOException {
    sink.writeShortLe(Short.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readShortLe();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readInt() throws Exception {
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, (byte) 0x87, (byte) 0x65, (byte) 0x43,
        (byte) 0x21
    });
    sink.emit();
    assertEquals(0xabcdef01, source.readInt());
    assertEquals(0x87654321, source.readInt());
    assertTrue(source.exhausted());
  }

  @Test public void readIntLe() throws Exception {
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, (byte) 0x87, (byte) 0x65, (byte) 0x43,
        (byte) 0x21
    });
    sink.emit();
    assertEquals(0x10efcdab, source.readIntLe());
    assertEquals(0x21436587, source.readIntLe());
    assertTrue(source.exhausted());
  }

  @Test public void readIntSplitAcrossMultipleSegments() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 3));
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01
    });
    sink.emit();
    source.skip(SEGMENT_SIZE - 3);
    assertEquals(0xabcdef01, source.readInt());
    assertTrue(source.exhausted());
  }

  @Test public void readIntTooShortThrows() throws IOException {
    sink.writeInt(Integer.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readInt();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readIntLeTooShortThrows() throws IOException {
    sink.writeIntLe(Integer.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readIntLe();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readLong() throws Exception {
    sink.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
    });
    sink.emit();
    assertEquals(0xabcdef1087654321L, source.readLong());
    assertEquals(0x3647586912233445L, source.readLong());
    assertTrue(source.exhausted());
  }

  @Test public void readLongLe() throws Exception {
    sink.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
    });
    sink.emit();
    assertEquals(0x2143658710efcdabL, source.readLongLe());
    assertEquals(0x4534231269584736L, source.readLongLe());
    assertTrue(source.exhausted());
  }

  @Test public void readLongSplitAcrossMultipleSegments() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 7));
    sink.write(new byte[] {
        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, (byte) 0x87, (byte) 0x65, (byte) 0x43,
        (byte) 0x21,
    });
    sink.emit();
    source.skip(SEGMENT_SIZE - 7);
    assertEquals(0xabcdef0187654321L, source.readLong());
    assertTrue(source.exhausted());
  }

  @Test public void readLongTooShortThrows() throws IOException {
    sink.writeLong(Long.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readLong();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readLongLeTooShortThrows() throws IOException {
    sink.writeLongLe(Long.MAX_VALUE);
    sink.emit();
    source.readByte();
    try {
      source.readLongLe();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void readAll() throws IOException {
    source.getBuffer().writeUtf8("abc");
    sink.writeUtf8("def");
    sink.emit();

    Buffer sink = new Buffer();
    assertEquals(6, source.readAll(sink));
    assertEquals("abcdef", sink.readUtf8());
    assertTrue(source.exhausted());
  }

  @Test public void readAllExhausted() throws IOException {
    MockSink mockSink = new MockSink();
    assertEquals(0, source.readAll(mockSink));
    assertTrue(source.exhausted());
    mockSink.assertLog();
  }

  @Test public void readExhaustedSource() throws Exception {
    Buffer sink = new Buffer();
    sink.writeUtf8(repeat("a", 10));
    assertEquals(-1, source.read(sink, 10));
    assertEquals(10, sink.size());
    assertTrue(source.exhausted());
  }

  @Test public void readZeroBytesFromSource() throws Exception {
    Buffer sink = new Buffer();
    sink.writeUtf8(repeat("a", 10));

    // 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());
    assertTrue(source.exhausted());
  }

  @Test public void readFully() throws Exception {
    sink.writeUtf8(repeat("a", 10000));
    sink.emit();
    Buffer sink = new Buffer();
    source.readFully(sink, 9999);
    assertEquals(repeat("a", 9999), sink.readUtf8());
    assertEquals("a", source.readUtf8());
  }

  @Test public void readFullyTooShortThrows() throws IOException {
    sink.writeUtf8("Hi");
    sink.emit();
    Buffer sink = new Buffer();
    try {
      source.readFully(sink, 5);
      fail();
    } catch (EOFException ignored) {
    }

    // Verify we read all that we could from the source.
    assertEquals("Hi", sink.readUtf8());
  }

  @Test public void readFullyByteArray() throws IOException {
    Buffer data = new Buffer();
    data.writeUtf8("Hello").writeUtf8(repeat("e", SEGMENT_SIZE));

    byte[] expected = data.clone().readByteArray();
    sink.write(data, data.size());
    sink.emit();

    byte[] sink = new byte[SEGMENT_SIZE + 5];
    source.readFully(sink);
    assertByteArraysEquals(expected, sink);
  }

  @Test public void readFullyByteArrayTooShortThrows() throws IOException {
    sink.writeUtf8("Hello");
    sink.emit();

    byte[] array = new byte[6];
    try {
      source.readFully(array);
      fail();
    } catch (EOFException ignored) {
    }

    // Verify we read all that we could from the source.
    assertByteArraysEquals(new byte[] { 'H', 'e', 'l', 'l', 'o', 0 }, array);
  }

  @Test public void readIntoByteArray() throws IOException {
    sink.writeUtf8("abcd");
    sink.emit();

    byte[] sink = new byte[3];
    int read = source.read(sink);
    if (factory.isOneByteAtATime()) {
      assertEquals(1, read);
      byte[] expected = { 'a', 0, 0 };
      assertByteArraysEquals(expected, sink);
    } else {
      assertEquals(3, read);
      byte[] expected = { 'a', 'b', 'c' };
      assertByteArraysEquals(expected, sink);
    }
  }

  @Test public void readIntoByteArrayNotEnough() throws IOException {
    sink.writeUtf8("abcd");
    sink.emit();

    byte[] sink = new byte[5];
    int read = source.read(sink);
    if (factory.isOneByteAtATime()) {
      assertEquals(1, read);
      byte[] expected = { 'a', 0, 0, 0, 0 };
      assertByteArraysEquals(expected, sink);
    } else {
      assertEquals(4, read);
      byte[] expected = { 'a', 'b', 'c', 'd', 0 };
      assertByteArraysEquals(expected, sink);
    }
  }

  @Test public void readIntoByteArrayOffsetAndCount() throws IOException {
    sink.writeUtf8("abcd");
    sink.emit();

    byte[] sink = new byte[7];
    int read = source.read(sink, 2, 3);
    if (factory.isOneByteAtATime()) {
      assertEquals(1, read);
      byte[] expected = { 0, 0, 'a', 0, 0, 0, 0 };
      assertByteArraysEquals(expected, sink);
    } else {
      assertEquals(3, read);
      byte[] expected = { 0, 0, 'a', 'b', 'c', 0, 0 };
      assertByteArraysEquals(expected, sink);
    }
  }

  @Test public void readByteArray() throws IOException {
    String string = "abcd" + repeat("e", SEGMENT_SIZE);
    sink.writeUtf8(string);
    sink.emit();
    assertByteArraysEquals(string.getBytes(UTF_8), source.readByteArray());
  }

  @Test public void readByteArrayPartial() throws IOException {
    sink.writeUtf8("abcd");
    sink.emit();
    assertEquals("[97, 98, 99]", Arrays.toString(source.readByteArray(3)));
    assertEquals("d", source.readUtf8(1));
  }

  @Test public void readByteArrayTooShortThrows() throws IOException {
    sink.writeUtf8("abc");
    sink.emit();
    try {
      source.readByteArray(4);
      fail();
    } catch (EOFException expected) {
    }
    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
  }

  @Test public void readByteString() throws IOException {
    sink.writeUtf8("abcd").writeUtf8(repeat("e", SEGMENT_SIZE));
    sink.emit();
    assertEquals("abcd" + repeat("e", SEGMENT_SIZE), source.readByteString().utf8());
  }

  @Test public void readByteStringPartial() throws IOException {
    sink.writeUtf8("abcd").writeUtf8(repeat("e", SEGMENT_SIZE));
    sink.emit();
    assertEquals("abc", source.readByteString(3).utf8());
    assertEquals("d", source.readUtf8(1));
  }

  @Test public void readByteStringTooShortThrows() throws IOException {
    sink.writeUtf8("abc");
    sink.emit();
    try {
      source.readByteString(4);
      fail();
    } catch (EOFException expected) {
    }
    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
  }

  @Test public void readSpecificCharsetPartial() throws Exception {
    sink.write(ByteString.decodeHex("0000007600000259000002c80000006c000000e40000007300000259"
        + "000002cc000000720000006100000070000000740000025900000072"));
    sink.emit();
    assertEquals("vəˈläsə", source.readString(7 * 4, Charset.forName("utf-32")));
  }

  @Test public void readSpecificCharset() throws Exception {
    sink.write(ByteString.decodeHex("0000007600000259000002c80000006c000000e40000007300000259"
        + "000002cc000000720000006100000070000000740000025900000072"));
    sink.emit();
    assertEquals("vəˈläsəˌraptər", source.readString(Charset.forName("utf-32")));
  }

  @Test public void readStringTooShortThrows() throws IOException {
    sink.writeString("abc", US_ASCII);
    sink.emit();
    try {
      source.readString(4, US_ASCII);
      fail();
    } catch (EOFException expected) {
    }
    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
  }

  @Test public void readUtf8SpansSegments() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
    sink.emit();
    source.skip(SEGMENT_SIZE - 1);
    assertEquals("aa", source.readUtf8(2));
  }

  @Test public void readUtf8Segment() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE));
    sink.emit();
    assertEquals(repeat("a", SEGMENT_SIZE), source.readUtf8(SEGMENT_SIZE));
  }

  @Test public void readUtf8PartialBuffer() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE + 20));
    sink.emit();
    assertEquals(repeat("a", SEGMENT_SIZE + 10), source.readUtf8(SEGMENT_SIZE + 10));
  }

  @Test public void readUtf8EntireBuffer() throws Exception {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
    sink.emit();
    assertEquals(repeat("a", SEGMENT_SIZE * 2), source.readUtf8());
  }

  @Test public void readUtf8TooShortThrows() throws IOException {
    sink.writeUtf8("abc");
    sink.emit();
    try {
      source.readUtf8(4L);
      fail();
    } catch (EOFException expected) {
    }
    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
  }

  @Test public void skip() throws Exception {
    sink.writeUtf8("a");
    sink.writeUtf8(repeat("b", SEGMENT_SIZE));
    sink.writeUtf8("c");
    sink.emit();
    source.skip(1);
    assertEquals('b', source.readByte() & 0xff);
    source.skip(SEGMENT_SIZE - 2);
    assertEquals('b', source.readByte() & 0xff);
    source.skip(1);
    assertTrue(source.exhausted());
  }

  @Test public void skipInsufficientData() throws Exception {
    sink.writeUtf8("a");
    sink.emit();

    try {
      source.skip(2);
      fail();
    } catch (EOFException ignored) {
    }
  }

  @Test public void indexOf() throws Exception {
    // The segment is empty.
    assertEquals(-1, source.indexOf((byte) 'a'));

    // The segment has one value.
    sink.writeUtf8("a"); // a
    sink.emit();
    assertEquals(0, source.indexOf((byte) 'a'));
    assertEquals(-1, source.indexOf((byte) 'b'));

    // The segment has lots of data.
    sink.writeUtf8(repeat("b", SEGMENT_SIZE - 2)); // ab...b
    sink.emit();
    assertEquals(0, source.indexOf((byte) 'a'));
    assertEquals(1, source.indexOf((byte) 'b'));
    assertEquals(-1, source.indexOf((byte) 'c'));

    // The segment doesn't start at 0, it starts at 2.
    source.skip(2); // b...b
    assertEquals(-1, source.indexOf((byte) 'a'));
    assertEquals(0, source.indexOf((byte) 'b'));
    assertEquals(-1, source.indexOf((byte) 'c'));

    // The segment is full.
    sink.writeUtf8("c"); // b...bc
    sink.emit();
    assertEquals(-1, source.indexOf((byte) 'a'));
    assertEquals(0, source.indexOf((byte) 'b'));
    assertEquals(SEGMENT_SIZE - 3, source.indexOf((byte) 'c'));

    // The segment doesn't start at 2, it starts at 4.
    source.skip(2); // b...bc
    assertEquals(-1, source.indexOf((byte) 'a'));
    assertEquals(0, source.indexOf((byte) 'b'));
    assertEquals(SEGMENT_SIZE - 5, source.indexOf((byte) 'c'));

    // Two segments.
    sink.writeUtf8("d"); // b...bcd, d is in the 2nd segment.
    sink.emit();
    assertEquals(SEGMENT_SIZE - 4, source.indexOf((byte) 'd'));
    assertEquals(-1, source.indexOf((byte) 'e'));
  }

  @Test public void indexOfByteWithStartOffset() throws IOException {
    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
    sink.emit();
    assertEquals(-1, source.indexOf((byte) 'a', 1));
    assertEquals(15, source.indexOf((byte) 'b', 15));
  }

  @Test public void indexOfByteWithBothOffsets() throws IOException {
    if (factory.isOneByteAtATime()) {
      // When run on Travis this causes out-of-memory errors.
      return;
    }
    byte a = (byte) 'a';
    byte c = (byte) 'c';

    int size = SEGMENT_SIZE * 5;
    byte[] bytes = new byte[size];
    Arrays.fill(bytes, a);

    // These are tricky places where the buffer
    // starts, ends, or segments come together.
    int[] points = {
        0,                       1,                   2,
        SEGMENT_SIZE - 1,        SEGMENT_SIZE,        SEGMENT_SIZE + 1,
        size / 2 - 1,            size / 2,            size / 2 + 1,
        size - SEGMENT_SIZE - 1, size - SEGMENT_SIZE, size - SEGMENT_SIZE + 1,
        size - 3,                size - 2,            size - 1
    };

    // In each iteration, we write c to the known point and then search for it using different
    // windows. Some of the windows don't overlap with c's position, and therefore a match shouldn't
    // be found.
    for (int p : points) {
      bytes[p] = c;
      sink.write(bytes);
      sink.emit();

      assertEquals( p, source.indexOf(c, 0,      size     ));
      assertEquals( p, source.indexOf(c, 0,      p + 1    ));
      assertEquals( p, source.indexOf(c, p,      size     ));
      assertEquals( p, source.indexOf(c, p,      p + 1    ));
      assertEquals( p, source.indexOf(c, p / 2,  p * 2 + 1));
      assertEquals(-1, source.indexOf(c, 0,      p / 2    ));
      assertEquals(-1, source.indexOf(c, 0,      p        ));
      assertEquals(-1, source.indexOf(c, 0,      0        ));
      assertEquals(-1, source.indexOf(c, p,      p        ));

      // Reset.
      source.readUtf8();
      bytes[p] = a;
    }
  }

  @Test public void indexOfByteInvalidBoundsThrows() throws IOException {
    sink.writeUtf8("abc");
    sink.emit();

    try {
      source.indexOf((byte) 'a', -1);
      fail("Expected failure: fromIndex < 0");
    } catch (IllegalArgumentException expected) {
    }

    try {
      source.indexOf((byte) 'a', 10, 0);
      fail("Expected failure: fromIndex > toIndex");
    } catch (IllegalArgumentException expected) {
    }
  }

  @Test public void indexOfByteString() throws IOException {
    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("flop")));

    sink.writeUtf8("flip flop");
    sink.emit();
    assertEquals(5, source.indexOf(ByteString.encodeUtf8("flop")));
    source.readUtf8(); // Clear stream.

    // Make sure we backtrack and resume searching after partial match.
    sink.writeUtf8("hi hi hi hey");
    sink.emit();
    assertEquals(3, source.indexOf(ByteString.encodeUtf8("hi hi hey")));
  }

  @Test public void indexOfByteStringAtSegmentBoundary() throws IOException {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
    sink.writeUtf8("bcd");
    sink.emit();
    assertEquals(SEGMENT_SIZE - 3, source.indexOf(ByteString.encodeUtf8("aabc"), SEGMENT_SIZE - 4));
    assertEquals(SEGMENT_SIZE - 3, source.indexOf(ByteString.encodeUtf8("aabc"), SEGMENT_SIZE - 3));
    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abcd"), SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abc"),  SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abc"),  SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("ab"),   SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("a"),    SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 1, source.indexOf(ByteString.encodeUtf8("bc"),   SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE - 1, source.indexOf(ByteString.encodeUtf8("b"),    SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE,     source.indexOf(ByteString.encodeUtf8("c"),    SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE,     source.indexOf(ByteString.encodeUtf8("c"),    SEGMENT_SIZE    ));
    assertEquals(SEGMENT_SIZE + 1, source.indexOf(ByteString.encodeUtf8("d"),    SEGMENT_SIZE - 2));
    assertEquals(SEGMENT_SIZE + 1, source.indexOf(ByteString.encodeUtf8("d"),    SEGMENT_SIZE + 1));
  }

  @Test public void indexOfDoesNotWrapAround() throws IOException {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
    sink.writeUtf8("bcd");
    sink.emit();
    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("abcda"), SEGMENT_SIZE - 3));
  }

  @Test public void indexOfByteStringWithOffset() throws IOException {
    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("flop"), 1));

    sink.writeUtf8("flop flip flop");
    sink.emit();
    assertEquals(10, source.indexOf(ByteString.encodeUtf8("flop"), 1));
    source.readUtf8(); // Clear stream

    // Make sure we backtrack and resume searching after partial match.
    sink.writeUtf8("hi hi hi hi hey");
    sink.emit();
    assertEquals(6, source.indexOf(ByteString.encodeUtf8("hi hi hey"), 1));
  }

  @Test public void indexOfByteStringInvalidArgumentsThrows() throws IOException {
    try {
      source.indexOf(ByteString.of());
      fail();
    } catch (IllegalArgumentException e) {
      assertEquals("bytes is empty", e.getMessage());
    }
    try {
      source.indexOf(ByteString.encodeUtf8("hi"), -1);
      fail();
    } catch (IllegalArgumentException e) {
      assertEquals("fromIndex < 0: -1", e.getMessage());
    }
  }

  /**
   * With {@link Factory#ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE}, this code was extremely slow.
   * https://github.com/square/okio/issues/171
   */
  @Test public void indexOfByteStringAcrossSegmentBoundaries() throws IOException {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2 - 3));
    sink.writeUtf8("bcdefg");
    sink.emit();
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("ab")));
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abc")));
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcd")));
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcde")));
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcdef")));
    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcdefg")));
    assertEquals(SEGMENT_SIZE * 2 - 3, source.indexOf(ByteString.encodeUtf8("bcdefg")));
    assertEquals(SEGMENT_SIZE * 2 - 2, source.indexOf(ByteString.encodeUtf8("cdefg")));
    assertEquals(SEGMENT_SIZE * 2 - 1, source.indexOf(ByteString.encodeUtf8("defg")));
    assertEquals(SEGMENT_SIZE * 2,     source.indexOf(ByteString.encodeUtf8("efg")));
    assertEquals(SEGMENT_SIZE * 2 + 1, source.indexOf(ByteString.encodeUtf8("fg")));
    assertEquals(SEGMENT_SIZE * 2 + 2, source.indexOf(ByteString.encodeUtf8("g")));
  }

  @Test public void indexOfElement() throws IOException {
    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
    sink.emit();
    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("DEFGaHIJK")));
    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJKb")));
    assertEquals(SEGMENT_SIZE + 1, source.indexOfElement(ByteString.encodeUtf8("cDEFGHIJK")));
    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("DEFbGHIc")));
    assertEquals(-1L, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJK")));
    assertEquals(-1L, source.indexOfElement(ByteString.encodeUtf8("")));
  }

  @Test public void indexOfElementWithOffset() throws IOException {
    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
    sink.emit();
    assertEquals(-1, source.indexOfElement(ByteString.encodeUtf8("DEFGaHIJK"), 1));
    assertEquals(15, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJKb"), 15));
  }

  @Test public void indexOfByteWithFromIndex() throws Exception {
    sink.writeUtf8("aaa");
    sink.emit();
    assertEquals(0, source.indexOf((byte) 'a'));
    assertEquals(0, source.indexOf((byte) 'a', 0));
    assertEquals(1, source.indexOf((byte) 'a', 1));
    assertEquals(2, source.indexOf((byte) 'a', 2));
  }

  @Test public void indexOfByteStringWithFromIndex() throws Exception {
    sink.writeUtf8("aaa");
    sink.emit();
    assertEquals(0, source.indexOf(ByteString.encodeUtf8("a")));
    assertEquals(0, source.indexOf(ByteString.encodeUtf8("a"), 0));
    assertEquals(1, source.indexOf(ByteString.encodeUtf8("a"), 1));
    assertEquals(2, source.indexOf(ByteString.encodeUtf8("a"), 2));
  }

  @Test public void indexOfElementWithFromIndex() throws Exception {
    sink.writeUtf8("aaa");
    sink.emit();
    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("a")));
    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("a"), 0));
    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("a"), 1));
    assertEquals(2, source.indexOfElement(ByteString.encodeUtf8("a"), 2));
  }

  @Test public void request() throws IOException {
    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
    sink.emit();
    assertTrue(source.request(SEGMENT_SIZE + 2));
    assertFalse(source.request(SEGMENT_SIZE + 3));
  }

  @Test public void require() throws IOException {
    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
    sink.emit();
    source.require(SEGMENT_SIZE + 2);
    try {
      source.require(SEGMENT_SIZE + 3);
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void inputStream() throws Exception {
    sink.writeUtf8("abc");
    sink.emit();
    InputStream in = source.inputStream();
    byte[] bytes = { 'z', 'z', 'z' };
    int read = in.read(bytes);
    if (factory.isOneByteAtATime()) {
      assertEquals(1, read);
      assertByteArrayEquals("azz", bytes);

      read = in.read(bytes);
      assertEquals(1, read);
      assertByteArrayEquals("bzz", bytes);

      read = in.read(bytes);
      assertEquals(1, read);
      assertByteArrayEquals("czz", bytes);
    } else {
      assertEquals(3, read);
      assertByteArrayEquals("abc", bytes);
    }

    assertEquals(-1, in.read());
  }

  @Test public void inputStreamOffsetCount() throws Exception {
    sink.writeUtf8("abcde");
    sink.emit();
    InputStream in = source.inputStream();
    byte[] bytes = { 'z', 'z', 'z', 'z', 'z' };
    int read = in.read(bytes, 1, 3);
    if (factory.isOneByteAtATime()) {
      assertEquals(1, read);
      assertByteArrayEquals("zazzz", bytes);
    } else {
      assertEquals(3, read);
      assertByteArrayEquals("zabcz", bytes);
    }
  }

  @Test public void inputStreamSkip() throws Exception {
    sink.writeUtf8("abcde");
    sink.emit();
    InputStream in = source.inputStream();
    assertEquals(4, in.skip(4));
    assertEquals('e', in.read());

    sink.writeUtf8("abcde");
    sink.emit();
    assertEquals(5, in.skip(10)); // Try to skip too much.
    assertEquals(0, in.skip(1)); // Try to skip when exhausted.
  }

  @Test public void inputStreamCharByChar() throws Exception {
    sink.writeUtf8("abc");
    sink.emit();
    InputStream in = source.inputStream();
    assertEquals('a', in.read());
    assertEquals('b', in.read());
    assertEquals('c', in.read());
    assertEquals(-1, in.read());
  }

  @Test public void inputStreamBounds() throws IOException {
    sink.writeUtf8(repeat("a", 100));
    sink.emit();
    InputStream in = source.inputStream();
    try {
      in.read(new byte[100], 50, 51);
      fail();
    } catch (ArrayIndexOutOfBoundsException expected) {
    }
  }

  @Test public void longHexString() throws IOException {
    assertLongHexString("8000000000000000", 0x8000000000000000L);
    assertLongHexString("fffffffffffffffe", 0xFFFFFFFFFFFFFFFEL);
    assertLongHexString("FFFFFFFFFFFFFFFe", 0xFFFFFFFFFFFFFFFEL);
    assertLongHexString("ffffffffffffffff", 0xffffffffffffffffL);
    assertLongHexString("FFFFFFFFFFFFFFFF", 0xFFFFFFFFFFFFFFFFL);
    assertLongHexString("0000000000000000", 0x0);
    assertLongHexString("0000000000000001", 0x1);
    assertLongHexString("7999999999999999", 0x7999999999999999L);

    assertLongHexString("FF", 0xFF);
    assertLongHexString("0000000000000001", 0x1);
  }

  @Test public void hexStringWithManyLeadingZeros() throws IOException {
    assertLongHexString("00000000000000001", 0x1);
    assertLongHexString("0000000000000000ffffffffffffffff", 0xffffffffffffffffL);
    assertLongHexString("00000000000000007fffffffffffffff", 0x7fffffffffffffffL);
    assertLongHexString(repeat("0", SEGMENT_SIZE + 1) + "1", 0x1);
  }

  private void assertLongHexString(String s, long expected) throws IOException {
    sink.writeUtf8(s);
    sink.emit();
    long actual = source.readHexadecimalUnsignedLong();
    assertEquals(s + " --> " + expected, expected, actual);
  }

  @Test public void longHexStringAcrossSegment() throws IOException {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 8)).writeUtf8("FFFFFFFFFFFFFFFF");
    sink.emit();
    source.skip(SEGMENT_SIZE - 8);
    assertEquals(-1, source.readHexadecimalUnsignedLong());
  }

  @Test public void longHexStringTooLongThrows() throws IOException {
    try {
      sink.writeUtf8("fffffffffffffffff");
      sink.emit();
      source.readHexadecimalUnsignedLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Number too large: fffffffffffffffff", e.getMessage());
    }
  }

  @Test public void longHexStringTooShortThrows() throws IOException {
    try {
      sink.writeUtf8(" ");
      sink.emit();
      source.readHexadecimalUnsignedLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Expected leading [0-9a-fA-F] character but was 0x20", e.getMessage());
    }
  }

  @Test public void longHexEmptySourceThrows() throws IOException {
    try {
      sink.writeUtf8("");
      sink.emit();
      source.readHexadecimalUnsignedLong();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void longDecimalString() throws IOException {
    assertLongDecimalString("-9223372036854775808", -9223372036854775808L);
    assertLongDecimalString("-1", -1L);
    assertLongDecimalString("0", 0L);
    assertLongDecimalString("1", 1L);
    assertLongDecimalString("9223372036854775807", 9223372036854775807L);

    assertLongDecimalString("00000001", 1L);
    assertLongDecimalString("-000001", -1L);
  }

  private void assertLongDecimalString(String s, long expected) throws IOException {
    sink.writeUtf8(s);
    sink.writeUtf8("zzz");
    sink.emit();
    long actual = source.readDecimalLong();
    assertEquals(s + " --> " + expected, expected, actual);
    assertEquals("zzz", source.readUtf8());
  }

  @Test public void longDecimalStringAcrossSegment() throws IOException {
    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 8)).writeUtf8("1234567890123456");
    sink.writeUtf8("zzz");
    sink.emit();
    source.skip(SEGMENT_SIZE - 8);
    assertEquals(1234567890123456L, source.readDecimalLong());
    assertEquals("zzz", source.readUtf8());
  }

  @Test public void longDecimalStringTooLongThrows() throws IOException {
    try {
      sink.writeUtf8("12345678901234567890"); // Too many digits.
      sink.emit();
      source.readDecimalLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Number too large: 12345678901234567890", e.getMessage());
    }
  }

  @Test public void longDecimalStringTooHighThrows() throws IOException {
    try {
      sink.writeUtf8("9223372036854775808"); // Right size but cannot fit.
      sink.emit();
      source.readDecimalLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Number too large: 9223372036854775808", e.getMessage());
    }
  }

  @Test public void longDecimalStringTooLowThrows() throws IOException {
    try {
      sink.writeUtf8("-9223372036854775809"); // Right size but cannot fit.
      sink.emit();
      source.readDecimalLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Number too large: -9223372036854775809", e.getMessage());
    }
  }

  @Test public void longDecimalStringTooShortThrows() throws IOException {
    try {
      sink.writeUtf8(" ");
      sink.emit();
      source.readDecimalLong();
      fail();
    } catch (NumberFormatException e) {
      assertEquals("Expected leading [0-9] or '-' character but was 0x20", e.getMessage());
    }
  }

  @Test public void longDecimalEmptyThrows() throws IOException {
    try {
      sink.writeUtf8("");
      sink.emit();
      source.readDecimalLong();
      fail();
    } catch (EOFException expected) {
    }
  }

  @Test public void codePoints() throws IOException {
    sink.write(ByteString.decodeHex("7f"));
    sink.emit();
    assertEquals(0x7f, source.readUtf8CodePoint());

    sink.write(ByteString.decodeHex("dfbf"));
    sink.emit();
    assertEquals(0x07ff, source.readUtf8CodePoint());

    sink.write(ByteString.decodeHex("efbfbf"));
    sink.emit();
    assertEquals(0xffff, source.readUtf8CodePoint());

    sink.write(ByteString.decodeHex("f48fbfbf"));
    sink.emit();
    assertEquals(0x10ffff, source.readUtf8CodePoint());
  }

  @Test public void decimalStringWithManyLeadingZeros() throws IOException {
    assertLongDecimalString("00000000000000001", 1);
    assertLongDecimalString("00000000000000009223372036854775807", 9223372036854775807L);
    assertLongDecimalString("-00000000000000009223372036854775808", -9223372036854775808L);
    assertLongDecimalString(repeat("0", SEGMENT_SIZE + 1) + "1", 1);
  }

  @Test public void select() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("ROCK"),
        ByteString.encodeUtf8("SCISSORS"),
        ByteString.encodeUtf8("PAPER"));

    sink.writeUtf8("PAPER,SCISSORS,ROCK");
    sink.emit();
    assertEquals(2, source.select(options));
    assertEquals(',', source.readByte());
    assertEquals(1, source.select(options));
    assertEquals(',', source.readByte());
    assertEquals(0, source.select(options));
    assertTrue(source.exhausted());
  }

  /** Note that this test crashes the VM on Android. */
  @Test public void selectSpanningMultipleSegments() throws IOException {
    ByteString commonPrefix = TestUtil.randomBytes(SEGMENT_SIZE + 10);
    ByteString a = new Buffer().write(commonPrefix).writeUtf8("a").readByteString();
    ByteString bc = new Buffer().write(commonPrefix).writeUtf8("bc").readByteString();
    ByteString bd = new Buffer().write(commonPrefix).writeUtf8("bd").readByteString();
    Options options = Options.Companion.of(a, bc, bd);

    sink.write(bd);
    sink.write(a);
    sink.write(bc);
    sink.emit();

    assertEquals(2, source.select(options));
    assertEquals(0, source.select(options));
    assertEquals(1, source.select(options));
    assertTrue(source.exhausted());
  }

  @Test public void selectNotFound() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("ROCK"),
        ByteString.encodeUtf8("SCISSORS"),
        ByteString.encodeUtf8("PAPER"));

    sink.writeUtf8("SPOCK");
    sink.emit();
    assertEquals(-1, source.select(options));
    assertEquals("SPOCK", source.readUtf8());
  }

  @Test public void selectValuesHaveCommonPrefix() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("abcd"),
        ByteString.encodeUtf8("abce"),
        ByteString.encodeUtf8("abcc"));

    sink.writeUtf8("abcc").writeUtf8("abcd").writeUtf8("abce");
    sink.emit();
    assertEquals(2, source.select(options));
    assertEquals(0, source.select(options));
    assertEquals(1, source.select(options));
  }

  @Test public void selectLongerThanSource() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("abcd"),
        ByteString.encodeUtf8("abce"),
        ByteString.encodeUtf8("abcc"));
    sink.writeUtf8("abc");
    sink.emit();
    assertEquals(-1, source.select(options));
    assertEquals("abc", source.readUtf8());
  }

  @Test public void selectReturnsFirstByteStringThatMatches() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("abcd"),
        ByteString.encodeUtf8("abc"),
        ByteString.encodeUtf8("abcde"));
    sink.writeUtf8("abcdef");
    sink.emit();
    assertEquals(0, source.select(options));
    assertEquals("ef", source.readUtf8());
  }

  @Test public void selectFromEmptySource() throws IOException {
    Options options = Options.Companion.of(
        ByteString.encodeUtf8("abc"),
        ByteString.encodeUtf8("def"));
    assertEquals(-1, source.select(options));
  }

  @Test public void selectNoByteStringsFromEmptySource() throws IOException {
    Options options = Options.of();
    assertEquals(-1, source.select(options));
  }

  @Test public void peek() throws IOException {
    sink.writeUtf8("abcdefghi");
    sink.emit();

    assertEquals("abc", source.readUtf8(3));

    BufferedSource peek = source.peek();
    assertEquals("def", peek.readUtf8(3));
    assertEquals("ghi", peek.readUtf8(3));
    assertFalse(peek.request(1));

    assertEquals("def", source.readUtf8(3));
  }

  @Test public void peekMultiple() throws IOException {
    sink.writeUtf8("abcdefghi");
    sink.emit();

    assertEquals("abc", source.readUtf8(3));

    BufferedSource peek1 = source.peek();
    BufferedSource peek2 = source.peek();

    assertEquals("def", peek1.readUtf8(3));

    assertEquals("def", peek2.readUtf8(3));
    assertEquals("ghi", peek2.readUtf8(3));
    assertFalse(peek2.request(1));

    assertEquals("ghi", peek1.readUtf8(3));
    assertFalse(peek1.request(1));

    assertEquals("def", source.readUtf8(3));
  }

  @Test public void peekLarge() throws IOException {
    sink.writeUtf8("abcdef");
    sink.writeUtf8(repeat("g", 2 * SEGMENT_SIZE));
    sink.writeUtf8("hij");
    sink.emit();

    assertEquals("abc", source.readUtf8(3));

    BufferedSource peek = source.peek();
    assertEquals("def", peek.readUtf8(3));
    peek.skip(2 * SEGMENT_SIZE);
    assertEquals("hij", peek.readUtf8(3));
    assertFalse(peek.request(1));

    assertEquals("def", source.readUtf8(3));
    source.skip(2 * SEGMENT_SIZE);
    assertEquals("hij", source.readUtf8(3));
  }

  @Test public void peekInvalid() throws IOException {
    sink.writeUtf8("abcdefghi");
    sink.emit();

    assertEquals("abc", source.readUtf8(3));

    BufferedSource peek = source.peek();
    assertEquals("def", peek.readUtf8(3));
    assertEquals("ghi", peek.readUtf8(3));
    assertFalse(peek.request(1));

    assertEquals("def", source.readUtf8(3));

    try {
      peek.readUtf8();
      fail();
    } catch (IllegalStateException e) {
      assertEquals("Peek source is invalid because upstream source was used", e.getMessage());
    }
  }

  @Test public void peekSegmentThenInvalid() throws IOException {
    sink.writeUtf8("abc");
    sink.writeUtf8(repeat("d", 2 * SEGMENT_SIZE));
    sink.emit();

    assertEquals("abc", source.readUtf8(3));

    // Peek a little data and skip the rest of the upstream source
    BufferedSource peek = source.peek();
    assertEquals("ddd", peek.readUtf8(3));
    source.readAll(Okio.blackhole());

    // Skip the rest of the buffered data
    peek.skip(peek.getBuffer().size());

    try {
      peek.readByte();
      fail();
    } catch (IllegalStateException e) {
      assertEquals("Peek source is invalid because upstream source was used", e.getMessage());
    }
  }

  @Test public void peekDoesntReadTooMuch() throws IOException {
    // 6 bytes in source's buffer plus 3 bytes upstream.
    sink.writeUtf8("abcdef");
    sink.emit();
    source.require(6L);
    sink.writeUtf8("ghi");
    sink.emit();

    BufferedSource peek = source.peek();

    // Read 3 bytes. This reads some of the buffered data.
    assertTrue(peek.request(3));
    if (!(source instanceof Buffer)) {
      assertEquals(6, source.getBuffer().size());
      assertEquals(6, peek.getBuffer().size());
    }
    assertEquals("abc", peek.readUtf8(3L));

    // Read 3 more bytes. This exhausts the buffered data.
    assertTrue(peek.request(3));
    if (!(source instanceof Buffer)) {
      assertEquals(6, source.getBuffer().size());
      assertEquals(3, peek.getBuffer().size());
    }
    assertEquals("def", peek.readUtf8(3L));

    // Read 3 more bytes. This draws new bytes.
    assertTrue(peek.request(3));
    assertEquals(9, source.getBuffer().size());
    assertEquals(3, peek.getBuffer().size());
    assertEquals("ghi", peek.readUtf8(3L));
  }

  @Test public void rangeEquals() throws IOException {
    sink.writeUtf8("A man, a plan, a canal. Panama.");
    sink.emit();
    assertTrue(source.rangeEquals(7 , ByteString.encodeUtf8("a plan")));
    assertTrue(source.rangeEquals(0 , ByteString.encodeUtf8("A man")));
    assertTrue(source.rangeEquals(24, ByteString.encodeUtf8("Panama")));
    assertFalse(source.rangeEquals(24, ByteString.encodeUtf8("Panama. Panama. Panama.")));
  }

  @Test public void rangeEqualsWithOffsetAndCount() throws IOException {
    sink.writeUtf8("A man, a plan, a canal. Panama.");
    sink.emit();
    assertTrue(source.rangeEquals(7 , ByteString.encodeUtf8("aaa plannn"), 2, 6));
    assertTrue(source.rangeEquals(0 , ByteString.encodeUtf8("AAA mannn"), 2, 5));
    assertTrue(source.rangeEquals(24, ByteString.encodeUtf8("PPPanamaaa"), 2, 6));
  }

  @Test public void rangeEqualsOnlyReadsUntilMismatch() throws IOException {
    assumeTrue(factory == Factory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE); // Other sources read in chunks anyway.

    sink.writeUtf8("A man, a plan, a canal. Panama.");
    sink.emit();
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A man.")));
    assertEquals("A man,", source.getBuffer().readUtf8());
  }

  @Test public void rangeEqualsArgumentValidation() throws IOException {
    // Negative source offset.
    assertFalse(source.rangeEquals(-1, ByteString.encodeUtf8("A")));
    // Negative bytes offset.
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), -1, 1));
    // Bytes offset longer than bytes length.
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 2, 1));
    // Negative byte count.
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 0, -1));
    // Byte count longer than bytes length.
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 0, 2));
    // Bytes offset plus byte count longer than bytes length.
    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 1, 1));
  }

  @Test public void readNioBuffer() throws Exception {
    String expected = factory.isOneByteAtATime() ? "a" : "abcdefg";
    sink.writeUtf8("abcdefg");
    sink.emit();

    ByteBuffer nioByteBuffer = ByteBuffer.allocate(1024);
    int byteCount = source.read(nioByteBuffer);
    assertEquals(expected.length(), byteCount);
    assertEquals(expected.length(), nioByteBuffer.position());
    assertEquals(nioByteBuffer.capacity(), nioByteBuffer.limit());

    nioByteBuffer.flip();
    byte[] data = new byte[expected.length()];
    nioByteBuffer.get(data);
    assertEquals(expected, new String(data));
  }

  /** Note that this test crashes the VM on Android. */
  @Test public void readLargeNioBufferOnlyReadsOneSegment() throws Exception {
    String expected = factory.isOneByteAtATime()
        ? "a"
        : repeat("a", SEGMENT_SIZE);
    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 4));
    sink.emit();

    ByteBuffer nioByteBuffer = ByteBuffer.allocate(SEGMENT_SIZE * 3);
    int byteCount = source.read(nioByteBuffer);
    assertEquals(expected.length(), byteCount);
    assertEquals(expected.length(), nioByteBuffer.position());
    assertEquals(nioByteBuffer.capacity(), nioByteBuffer.limit());

    nioByteBuffer.flip();
    byte[] data = new byte[expected.length()];
    nioByteBuffer.get(data);
    assertEquals(expected, new String(data));
  }

  @Test public void factorySegmentSizes() throws Exception {
    sink.writeUtf8("abc");
    sink.emit();
    source.require(3);
    if (factory.isOneByteAtATime()) {
      assertEquals(Arrays.asList(1, 1, 1), TestUtil.segmentSizes(source.getBuffer()));
    } else {
      assertEquals(Collections.singletonList(3), TestUtil.segmentSizes(source.getBuffer()));
    }
  }
}
