// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import com.google.protobuf.ByteString.Output;

import junit.framework.TestCase;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;

/**
 * Test methods with implementations in {@link ByteString}, plus do some top-level "integration"
 * tests.
 *
 * @author carlanton@google.com (Carl Haverl)
 */
public class ByteStringTest extends TestCase {

  private static final String UTF_16 = "UTF-16";

  static byte[] getTestBytes(int size, long seed) {
    Random random = new Random(seed);
    byte[] result = new byte[size];
    random.nextBytes(result);
    return result;
  }

  private byte[] getTestBytes(int size) {
    return getTestBytes(size, 445566L);
  }

  private byte[] getTestBytes() {
    return getTestBytes(1000);
  }

  // Compare the entire left array with a subset of the right array.
  private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) {
    boolean stillEqual = (left.length == length);
    for (int i = 0; (stillEqual && i < length); ++i) {
      stillEqual = (left[i] == right[rightOffset + i]);
    }
    return stillEqual;
  }

  // Returns true only if the given two arrays have identical contents.
  private boolean isArray(byte[] left, byte[] right) {
    return left.length == right.length && isArrayRange(left, right, 0, left.length);
  }

  public void testSubstring_BeginIndex() {
    byte[] bytes = getTestBytes();
    ByteString substring = ByteString.copyFrom(bytes).substring(500);
    assertTrue("substring must contain the tail of the string",
        isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500));
  }

  public void testCopyFrom_BytesOffsetSize() {
    byte[] bytes = getTestBytes();
    ByteString byteString = ByteString.copyFrom(bytes, 500, 200);
    assertTrue("copyFrom sub-range must contain the expected bytes",
        isArrayRange(byteString.toByteArray(), bytes, 500, 200));
  }

  public void testCopyFrom_Bytes() {
    byte[] bytes = getTestBytes();
    ByteString byteString = ByteString.copyFrom(bytes);
    assertTrue("copyFrom must contain the expected bytes",
        isArray(byteString.toByteArray(), bytes));
  }

  public void testCopyFrom_ByteBufferSize() {
    byte[] bytes = getTestBytes();
    ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
    byteBuffer.put(bytes);
    byteBuffer.position(500);
    ByteString byteString = ByteString.copyFrom(byteBuffer, 200);
    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
        isArrayRange(byteString.toByteArray(), bytes, 500, 200));
  }

  public void testCopyFrom_ByteBuffer() {
    byte[] bytes = getTestBytes();
    ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
    byteBuffer.put(bytes);
    byteBuffer.position(500);
    ByteString byteString = ByteString.copyFrom(byteBuffer);
    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
        isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500));
  }

  public void testCopyFrom_StringEncoding() throws UnsupportedEncodingException {
    String testString = "I love unicode \u1234\u5678 characters";
    ByteString byteString = ByteString.copyFrom(testString, UTF_16);
    byte[] testBytes = testString.getBytes(UTF_16);
    assertTrue("copyFrom string must respect the charset",
        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
  }

  public void testCopyFrom_Utf8() throws UnsupportedEncodingException {
    String testString = "I love unicode \u1234\u5678 characters";
    ByteString byteString = ByteString.copyFromUtf8(testString);
    byte[] testBytes = testString.getBytes("UTF-8");
    assertTrue("copyFromUtf8 string must respect the charset",
        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
  }

  public void testCopyFrom_Iterable() {
    byte[] testBytes = getTestBytes(77777, 113344L);
    final List<ByteString> pieces = makeConcretePieces(testBytes);
    // Call copyFrom() on a Collection
    ByteString byteString = ByteString.copyFrom(pieces);
    assertTrue("copyFrom a List must contain the expected bytes",
        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
    // Call copyFrom on an iteration that's not a collection
    ByteString byteStringAlt = ByteString.copyFrom(new Iterable<ByteString>() {
      public Iterator<ByteString> iterator() {
        return pieces.iterator();
      }
    });
    assertEquals("copyFrom from an Iteration must contain the expected bytes",
        byteString, byteStringAlt);
  }

  public void testCopyTo_TargetOffset() {
    byte[] bytes = getTestBytes();
    ByteString byteString = ByteString.copyFrom(bytes);
    byte[] target = new byte[bytes.length + 1000];
    byteString.copyTo(target, 400);
    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
        isArrayRange(bytes, target, 400, bytes.length));
  }

  public void testReadFrom_emptyStream() throws IOException {
    ByteString byteString =
        ByteString.readFrom(new ByteArrayInputStream(new byte[0]));
    assertSame("reading an empty stream must result in the EMPTY constant "
        + "byte string", ByteString.EMPTY, byteString);
  }

  public void testReadFrom_smallStream() throws IOException {
    assertReadFrom(getTestBytes(10));
  }

  public void testReadFrom_mutating() throws IOException {
    byte[] capturedArray = null;
    EvilInputStream eis = new EvilInputStream();
    ByteString byteString = ByteString.readFrom(eis);

    capturedArray = eis.capturedArray;
    byte[] originalValue = byteString.toByteArray();
    for (int x = 0; x < capturedArray.length; ++x) {
      capturedArray[x] = (byte) 0;
    }

    byte[] newValue = byteString.toByteArray();
    assertTrue("copyFrom byteBuffer must not grant access to underlying array",
        Arrays.equals(originalValue, newValue));
  }

  // Tests sizes that are near the rope copy-out threshold.
  public void testReadFrom_mediumStream() throws IOException {
    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE - 1));
    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE));
    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE + 1));
    assertReadFrom(getTestBytes(200));
  }

  // Tests sizes that are over multi-segment rope threshold.
  public void testReadFrom_largeStream() throws IOException {
    assertReadFrom(getTestBytes(0x100));
    assertReadFrom(getTestBytes(0x101));
    assertReadFrom(getTestBytes(0x110));
    assertReadFrom(getTestBytes(0x1000));
    assertReadFrom(getTestBytes(0x1001));
    assertReadFrom(getTestBytes(0x1010));
    assertReadFrom(getTestBytes(0x10000));
    assertReadFrom(getTestBytes(0x10001));
    assertReadFrom(getTestBytes(0x10010));
  }

  // Tests sizes that are near the read buffer size.
  public void testReadFrom_byteBoundaries() throws IOException {
    final int min = ByteString.MIN_READ_FROM_CHUNK_SIZE;
    final int max = ByteString.MAX_READ_FROM_CHUNK_SIZE;

    assertReadFrom(getTestBytes(min - 1));
    assertReadFrom(getTestBytes(min));
    assertReadFrom(getTestBytes(min + 1));

    assertReadFrom(getTestBytes(min * 2 - 1));
    assertReadFrom(getTestBytes(min * 2));
    assertReadFrom(getTestBytes(min * 2 + 1));

    assertReadFrom(getTestBytes(min * 4 - 1));
    assertReadFrom(getTestBytes(min * 4));
    assertReadFrom(getTestBytes(min * 4 + 1));

    assertReadFrom(getTestBytes(min * 8 - 1));
    assertReadFrom(getTestBytes(min * 8));
    assertReadFrom(getTestBytes(min * 8 + 1));

    assertReadFrom(getTestBytes(max - 1));
    assertReadFrom(getTestBytes(max));
    assertReadFrom(getTestBytes(max + 1));

    assertReadFrom(getTestBytes(max * 2 - 1));
    assertReadFrom(getTestBytes(max * 2));
    assertReadFrom(getTestBytes(max * 2 + 1));
  }

  // Tests that IOExceptions propagate through ByteString.readFrom().
  public void testReadFrom_IOExceptions() {
    try {
      ByteString.readFrom(new FailStream());
      fail("readFrom must throw the underlying IOException");

    } catch (IOException e) {
      assertEquals("readFrom must throw the expected exception",
                   "synthetic failure", e.getMessage());
    }
  }

  // Tests that ByteString.readFrom works with streams that don't
  // always fill their buffers.
  public void testReadFrom_reluctantStream() throws IOException {
    final byte[] data = getTestBytes(0x1000);

    ByteString byteString = ByteString.readFrom(new ReluctantStream(data));
    assertTrue("readFrom byte stream must contain the expected bytes",
        isArray(byteString.toByteArray(), data));

    // Same test as above, but with some specific chunk sizes.
    assertReadFromReluctantStream(data, 100);
    assertReadFromReluctantStream(data, 248);
    assertReadFromReluctantStream(data, 249);
    assertReadFromReluctantStream(data, 250);
    assertReadFromReluctantStream(data, 251);
    assertReadFromReluctantStream(data, 0x1000);
    assertReadFromReluctantStream(data, 0x1001);
  }

  // Fails unless ByteString.readFrom reads the bytes correctly from a
  // reluctant stream with the given chunkSize parameter.
  private void assertReadFromReluctantStream(byte[] bytes, int chunkSize)
      throws IOException {
    ByteString b = ByteString.readFrom(new ReluctantStream(bytes), chunkSize);
    assertTrue("readFrom byte stream must contain the expected bytes",
        isArray(b.toByteArray(), bytes));
  }

  // Tests that ByteString.readFrom works with streams that implement
  // available().
  public void testReadFrom_available() throws IOException {
    final byte[] data = getTestBytes(0x1001);

    ByteString byteString = ByteString.readFrom(new AvailableStream(data));
    assertTrue("readFrom byte stream must contain the expected bytes",
        isArray(byteString.toByteArray(), data));
  }

  // Fails unless ByteString.readFrom reads the bytes correctly.
  private void assertReadFrom(byte[] bytes) throws IOException {
    ByteString byteString =
        ByteString.readFrom(new ByteArrayInputStream(bytes));
    assertTrue("readFrom byte stream must contain the expected bytes",
        isArray(byteString.toByteArray(), bytes));
  }

  // A stream that fails when read.
  private static final class FailStream extends InputStream {
    @Override public int read() throws IOException {
      throw new IOException("synthetic failure");
    }
  }

  // A stream that simulates blocking by only producing 250 characters
  // per call to read(byte[]).
  private static class ReluctantStream extends InputStream {
    protected final byte[] data;
    protected int pos = 0;

    public ReluctantStream(byte[] data) {
      this.data = data;
    }

    @Override public int read() {
      if (pos == data.length) {
        return -1;
      } else {
        return data[pos++];
      }
    }

    @Override public int read(byte[] buf) {
      return read(buf, 0, buf.length);
    }

    @Override public int read(byte[] buf, int offset, int size) {
      if (pos == data.length) {
        return -1;
      }
      int count = Math.min(Math.min(size, data.length - pos), 250);
      System.arraycopy(data, pos, buf, offset, count);
      pos += count;
      return count;
    }
  }

  // Same as above, but also implements available().
  private static final class AvailableStream extends ReluctantStream {
    public AvailableStream(byte[] data) {
      super(data);
    }

    @Override public int available() {
      return Math.min(250, data.length - pos);
    }
  }

  // A stream which exposes the byte array passed into read(byte[], int, int).
  private static class EvilInputStream extends InputStream {
    public byte[] capturedArray = null;

    @Override
    public int read(byte[] buf, int off, int len) {
      if (capturedArray != null) {
        return -1;
      } else {
        capturedArray = buf;
        for (int x = 0; x < len; ++x) {
          buf[x] = (byte) x;
        }
        return len;
      }
    }

    @Override
    public int read() {
      // Purposefully do nothing.
      return -1;
    }
  }
  
  // A stream which exposes the byte array passed into write(byte[], int, int).
  private static class EvilOutputStream extends OutputStream {
    public byte[] capturedArray = null;

    @Override
    public void write(byte[] buf, int off, int len) {
      if (capturedArray == null) {
        capturedArray = buf;
      }
    }

    @Override
    public void write(int ignored) {
      // Purposefully do nothing.
    }
  }

  public void testToStringUtf8() throws UnsupportedEncodingException {
    String testString = "I love unicode \u1234\u5678 characters";
    byte[] testBytes = testString.getBytes("UTF-8");
    ByteString byteString = ByteString.copyFrom(testBytes);
    assertEquals("copyToStringUtf8 must respect the charset",
        testString, byteString.toStringUtf8());
  }

  public void testNewOutput_InitialCapacity() throws IOException {
    byte[] bytes = getTestBytes();
    ByteString.Output output = ByteString.newOutput(bytes.length + 100);
    output.write(bytes);
    ByteString byteString = output.toByteString();
    assertTrue(
        "String built from newOutput(int) must contain the expected bytes",
        isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
  }

  // Test newOutput() using a variety of buffer sizes and a variety of (fixed)
  // write sizes
  public void testNewOutput_ArrayWrite() throws IOException {
    byte[] bytes = getTestBytes();
    int length = bytes.length;
    int[] bufferSizes = {128, 256, length / 2, length - 1, length, length + 1,
                         2 * length, 3 * length};
    int[] writeSizes = {1, 4, 5, 7, 23, bytes.length};

    for (int bufferSize : bufferSizes) {
      for (int writeSize : writeSizes) {
        // Test writing the entire output writeSize bytes at a time.
        ByteString.Output output = ByteString.newOutput(bufferSize);
        for (int i = 0; i < length; i += writeSize) {
          output.write(bytes, i, Math.min(writeSize, length - i));
        }
        ByteString byteString = output.toByteString();
        assertTrue("String built from newOutput() must contain the expected bytes",
            isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
      }
    }
  }

  // Test newOutput() using a variety of buffer sizes, but writing all the
  // characters using write(byte);
  public void testNewOutput_WriteChar() throws IOException {
    byte[] bytes = getTestBytes();
    int length = bytes.length;
    int[] bufferSizes = {0, 1, 128, 256, length / 2,
                         length - 1, length, length + 1,
                         2 * length, 3 * length};
    for (int bufferSize : bufferSizes) {
      ByteString.Output output = ByteString.newOutput(bufferSize);
      for (byte byteValue : bytes) {
        output.write(byteValue);
      }
      ByteString byteString = output.toByteString();
      assertTrue("String built from newOutput() must contain the expected bytes",
          isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
    }
  }

  // Test newOutput() in which we write the bytes using a variety of methods
  // and sizes, and in which we repeatedly call toByteString() in the middle.
  public void testNewOutput_Mixed() throws IOException {
    Random rng = new Random(1);
    byte[] bytes = getTestBytes();
    int length = bytes.length;
    int[] bufferSizes = {0, 1, 128, 256, length / 2,
                         length - 1, length, length + 1,
                         2 * length, 3 * length};

    for (int bufferSize : bufferSizes) {
      // Test writing the entire output using a mixture of write sizes and
      // methods;
      ByteString.Output output = ByteString.newOutput(bufferSize);
      int position = 0;
      while (position < bytes.length) {
        if (rng.nextBoolean()) {
          int count = 1 + rng.nextInt(bytes.length - position);
          output.write(bytes, position, count);
          position += count;
        } else {
          output.write(bytes[position]);
          position++;
        }
        assertEquals("size() returns the right value", position, output.size());
        assertTrue("newOutput() substring must have correct bytes",
            isArrayRange(output.toByteString().toByteArray(),
                bytes, 0, position));
      }
      ByteString byteString = output.toByteString();
      assertTrue("String built from newOutput() must contain the expected bytes",
          isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
    }
  }
  
  public void testNewOutputEmpty() throws IOException {
    // Make sure newOutput() correctly builds empty byte strings
    ByteString byteString = ByteString.newOutput().toByteString();
    assertEquals(ByteString.EMPTY, byteString);
  }
  
  public void testNewOutput_Mutating() throws IOException {
    Output os = ByteString.newOutput(5);
    os.write(new byte[] {1, 2, 3, 4, 5});
    EvilOutputStream eos = new EvilOutputStream();
    os.writeTo(eos);
    byte[] capturedArray = eos.capturedArray;
    ByteString byteString = os.toByteString();
    byte[] oldValue = byteString.toByteArray();
    Arrays.fill(capturedArray, (byte) 0);
    byte[] newValue = byteString.toByteArray();
    assertTrue("Output must not provide access to the underlying byte array",
        Arrays.equals(oldValue, newValue));
  }

  public void testNewCodedBuilder() throws IOException {
    byte[] bytes = getTestBytes();
    ByteString.CodedBuilder builder = ByteString.newCodedBuilder(bytes.length);
    builder.getCodedOutput().writeRawBytes(bytes);
    ByteString byteString = builder.build();
    assertTrue("String built from newCodedBuilder() must contain the expected bytes",
        isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
  }

  public void testSubstringParity() {
    byte[] bigBytes = getTestBytes(2048 * 1024, 113344L);
    int start = 512 * 1024 - 3333;
    int end   = 512 * 1024 + 7777;
    ByteString concreteSubstring = ByteString.copyFrom(bigBytes).substring(start, end);
    boolean ok = true;
    for (int i = start; ok && i < end; ++i) {
      ok = (bigBytes[i] == concreteSubstring.byteAt(i - start));
    }
    assertTrue("Concrete substring didn't capture the right bytes", ok);

    ByteString literalString = ByteString.copyFrom(bigBytes, start, end - start);
    assertTrue("Substring must be equal to literal string",
        concreteSubstring.equals(literalString));
    assertEquals("Substring must have same hashcode as literal string",
        literalString.hashCode(), concreteSubstring.hashCode());
  }

  public void testCompositeSubstring() {
    byte[] referenceBytes = getTestBytes(77748, 113344L);

    List<ByteString> pieces = makeConcretePieces(referenceBytes);
    ByteString listString = ByteString.copyFrom(pieces);

    int from = 1000;
    int to = 40000;
    ByteString compositeSubstring = listString.substring(from, to);
    byte[] substringBytes = compositeSubstring.toByteArray();
    boolean stillEqual = true;
    for (int i = 0; stillEqual && i < to - from; ++i) {
      stillEqual = referenceBytes[from + i] == substringBytes[i];
    }
    assertTrue("Substring must return correct bytes", stillEqual);

    stillEqual = true;
    for (int i = 0; stillEqual && i < to - from; ++i) {
      stillEqual = referenceBytes[from + i] == compositeSubstring.byteAt(i);
    }
    assertTrue("Substring must support byteAt() correctly", stillEqual);

    ByteString literalSubstring = ByteString.copyFrom(referenceBytes, from, to - from);
    assertTrue("Composite substring must equal a literal substring over the same bytes",
        compositeSubstring.equals(literalSubstring));
    assertTrue("Literal substring must equal a composite substring over the same bytes",
        literalSubstring.equals(compositeSubstring));

    assertEquals("We must get the same hashcodes for composite and literal substrings",
        literalSubstring.hashCode(), compositeSubstring.hashCode());

    assertFalse("We can't be equal to a proper substring",
        compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1)));
  }

  public void testCopyFromList() {
    byte[] referenceBytes = getTestBytes(77748, 113344L);
    ByteString literalString = ByteString.copyFrom(referenceBytes);

    List<ByteString> pieces = makeConcretePieces(referenceBytes);
    ByteString listString = ByteString.copyFrom(pieces);

    assertTrue("Composite string must be equal to literal string",
        listString.equals(literalString));
    assertEquals("Composite string must have same hashcode as literal string",
        literalString.hashCode(), listString.hashCode());
  }

  public void testConcat() {
    byte[] referenceBytes = getTestBytes(77748, 113344L);
    ByteString literalString = ByteString.copyFrom(referenceBytes);

    List<ByteString> pieces = makeConcretePieces(referenceBytes);

    Iterator<ByteString> iter = pieces.iterator();
    ByteString concatenatedString = iter.next();
    while (iter.hasNext()) {
      concatenatedString = concatenatedString.concat(iter.next());
    }

    assertTrue("Concatenated string must be equal to literal string",
        concatenatedString.equals(literalString));
    assertEquals("Concatenated string must have same hashcode as literal string",
        literalString.hashCode(), concatenatedString.hashCode());
  }

  /**
   * Test the Rope implementation can deal with Empty nodes, even though we
   * guard against them. See also {@link LiteralByteStringTest#testConcat_empty()}.
   */
  public void testConcat_empty() {
    byte[] referenceBytes = getTestBytes(7748, 113344L);
    ByteString literalString = ByteString.copyFrom(referenceBytes);

    ByteString duo = RopeByteString.newInstanceForTest(literalString, literalString);
    ByteString temp = RopeByteString.newInstanceForTest(
        RopeByteString.newInstanceForTest(literalString, ByteString.EMPTY),
        RopeByteString.newInstanceForTest(ByteString.EMPTY, literalString));
    ByteString quintet = RopeByteString.newInstanceForTest(temp, ByteString.EMPTY);

    assertTrue("String with concatenated nulls must equal simple concatenate",
        duo.equals(quintet));
    assertEquals("String with concatenated nulls have same hashcode as simple concatenate",
        duo.hashCode(), quintet.hashCode());

    ByteString.ByteIterator duoIter = duo.iterator();
    ByteString.ByteIterator quintetIter = quintet.iterator();
    boolean stillEqual = true;
    while (stillEqual && quintetIter.hasNext()) {
      stillEqual = (duoIter.nextByte() == quintetIter.nextByte());
    }
    assertTrue("We must get the same characters by iterating", stillEqual);
    assertFalse("Iterator must be exhausted", duoIter.hasNext());
    try {
      duoIter.nextByte();
      fail("Should have thrown an exception.");
    } catch (NoSuchElementException e) {
      // This is success
    }
    try {
      quintetIter.nextByte();
      fail("Should have thrown an exception.");
    } catch (NoSuchElementException e) {
      // This is success
    }

    // Test that even if we force empty strings in as rope leaves in this
    // configuration, we always get a (possibly Bounded) LiteralByteString
    // for a length 1 substring.
    //
    // It is possible, using the testing factory method to create deeply nested
    // trees of empty leaves, to make a string that will fail this test.
    for (int i = 1; i < duo.size(); ++i) {
      assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
          duo.substring(i - 1, i) instanceof LiteralByteString);
    }
    for (int i = 1; i < quintet.size(); ++i) {
      assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
          quintet.substring(i - 1, i) instanceof LiteralByteString);
    }
  }

  public void testStartsWith() {
    byte[] bytes = getTestBytes(1000, 1234L);
    ByteString string = ByteString.copyFrom(bytes);
    ByteString prefix = ByteString.copyFrom(bytes, 0, 500);
    ByteString suffix = ByteString.copyFrom(bytes, 400, 600);
    assertTrue(string.startsWith(ByteString.EMPTY));
    assertTrue(string.startsWith(string));
    assertTrue(string.startsWith(prefix));
    assertFalse(string.startsWith(suffix));
    assertFalse(prefix.startsWith(suffix));
    assertFalse(suffix.startsWith(prefix));
    assertFalse(ByteString.EMPTY.startsWith(prefix));
    assertTrue(ByteString.EMPTY.startsWith(ByteString.EMPTY));
  }

  static List<ByteString> makeConcretePieces(byte[] referenceBytes) {
    List<ByteString> pieces = new ArrayList<ByteString>();
    // Starting length should be small enough that we'll do some concatenating by
    // copying if we just concatenate all these pieces together.
    for (int start = 0, length = 16; start < referenceBytes.length; start += length) {
      length = (length << 1) - 1;
      if (start + length > referenceBytes.length) {
        length = referenceBytes.length - start;
      }
      pieces.add(ByteString.copyFrom(referenceBytes, start, length));
    }
    return pieces;
  }
}
