Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.io;
     18 
     19 import static com.google.common.base.Charsets.UTF_16;
     20 import com.google.common.base.Charsets;
     21 import com.google.common.jdk5backport.Arrays;
     22 
     23 import java.io.ByteArrayInputStream;
     24 import java.io.ByteArrayOutputStream;
     25 import java.io.EOFException;
     26 import java.io.FilterInputStream;
     27 import java.io.IOException;
     28 import java.io.InputStream;
     29 import java.io.OutputStream;
     30 import java.io.UnsupportedEncodingException;
     31 import java.nio.channels.Channels;
     32 import java.nio.channels.ReadableByteChannel;
     33 import java.nio.channels.WritableByteChannel;
     34 import java.util.zip.CRC32;
     35 import java.util.zip.Checksum;
     36 
     37 /**
     38  * Unit test for {@link ByteStreams}.
     39  *
     40  * @author Chris Nokleberg
     41  */
     42 public class ByteStreamsTest extends IoTestCase {
     43 
     44   public void testCopyChannel() throws IOException {
     45     byte[] expected = newPreFilledByteArray(100);
     46     ByteArrayOutputStream out = new ByteArrayOutputStream();
     47     WritableByteChannel outChannel = Channels.newChannel(out);
     48 
     49     ReadableByteChannel inChannel =
     50         Channels.newChannel(new ByteArrayInputStream(expected));
     51     ByteStreams.copy(inChannel, outChannel);
     52     assertEquals(expected, out.toByteArray());
     53   }
     54 
     55   public void testReadFully() throws IOException {
     56     byte[] b = new byte[10];
     57 
     58     try {
     59       ByteStreams.readFully(newTestStream(10), null, 0, 10);
     60       fail("expected exception");
     61     } catch (NullPointerException e) {
     62     }
     63 
     64     try {
     65       ByteStreams.readFully(null, b, 0, 10);
     66       fail("expected exception");
     67     } catch (NullPointerException e) {
     68     }
     69 
     70     try {
     71       ByteStreams.readFully(newTestStream(10), b, -1, 10);
     72       fail("expected exception");
     73     } catch (IndexOutOfBoundsException e) {
     74     }
     75 
     76     try {
     77       ByteStreams.readFully(newTestStream(10), b, 0, -1);
     78       fail("expected exception");
     79     } catch (IndexOutOfBoundsException e) {
     80     }
     81 
     82     try {
     83       ByteStreams.readFully(newTestStream(10), b, 0, -1);
     84       fail("expected exception");
     85     } catch (IndexOutOfBoundsException e) {
     86     }
     87 
     88     try {
     89       ByteStreams.readFully(newTestStream(10), b, 2, 10);
     90       fail("expected exception");
     91     } catch (IndexOutOfBoundsException e) {
     92     }
     93 
     94     try {
     95       ByteStreams.readFully(newTestStream(5), b, 0, 10);
     96       fail("expected exception");
     97     } catch (EOFException e) {
     98     }
     99 
    100     Arrays.fill(b, (byte) 0);
    101     ByteStreams.readFully(newTestStream(10), b, 0, 0);
    102     assertEquals(new byte[10], b);
    103 
    104     Arrays.fill(b, (byte) 0);
    105     ByteStreams.readFully(newTestStream(10), b, 0, 10);
    106     assertEquals(newPreFilledByteArray(10), b);
    107 
    108     Arrays.fill(b, (byte) 0);
    109     ByteStreams.readFully(newTestStream(10), b, 0, 5);
    110     assertEquals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b);
    111   }
    112 
    113   public void testSkipFully() throws IOException {
    114     byte[] bytes = newPreFilledByteArray(100);
    115     skipHelper(0, 0, new ByteArrayInputStream(bytes));
    116     skipHelper(50, 50, new ByteArrayInputStream(bytes));
    117     skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 1));
    118     skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 0));
    119     skipHelper(100, -1, new ByteArrayInputStream(bytes));
    120     try {
    121       skipHelper(101, 0, new ByteArrayInputStream(bytes));
    122       fail("expected exception");
    123     } catch (EOFException e) {
    124     }
    125   }
    126 
    127   private static void skipHelper(long n, int expect, InputStream in)
    128       throws IOException {
    129     ByteStreams.skipFully(in, n);
    130     assertEquals(expect, in.read());
    131     in.close();
    132   }
    133 
    134   private static final byte[] bytes =
    135       new byte[] { 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
    136 
    137   public void testNewDataInput_empty() {
    138     byte[] b = new byte[0];
    139     ByteArrayDataInput in = ByteStreams.newDataInput(b);
    140     try {
    141       in.readInt();
    142       fail("expected exception");
    143     } catch (IllegalStateException expected) {
    144     }
    145   }
    146 
    147   public void testNewDataInput_normal() {
    148     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    149     assertEquals(0x12345678, in.readInt());
    150     assertEquals(0x76543210, in.readInt());
    151     try {
    152       in.readInt();
    153       fail("expected exception");
    154     } catch (IllegalStateException expected) {
    155     }
    156   }
    157 
    158   public void testNewDataInput_readFully() {
    159     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    160     byte[] actual = new byte[bytes.length];
    161     in.readFully(actual);
    162     assertEquals(bytes, actual);
    163   }
    164 
    165   public void testNewDataInput_readFullyAndThenSome() {
    166     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    167     byte[] actual = new byte[bytes.length * 2];
    168     try {
    169       in.readFully(actual);
    170       fail("expected exception");
    171     } catch (IllegalStateException ex) {
    172       assertTrue(ex.getCause() instanceof EOFException);
    173     }
    174   }
    175 
    176   public void testNewDataInput_readFullyWithOffset() {
    177     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    178     byte[] actual = new byte[4];
    179     in.readFully(actual, 2, 2);
    180     assertEquals(0, actual[0]);
    181     assertEquals(0, actual[1]);
    182     assertEquals(bytes[0], actual[2]);
    183     assertEquals(bytes[1], actual[3]);
    184   }
    185 
    186   public void testNewDataInput_readLine() throws UnsupportedEncodingException {
    187     ByteArrayDataInput in = ByteStreams.newDataInput(
    188         "This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8.name()));
    189     assertEquals("This is a line", in.readLine());
    190     assertEquals("This too", in.readLine());
    191     assertEquals("and this", in.readLine());
    192     assertEquals("and also this", in.readLine());
    193   }
    194 
    195   public void testNewDataInput_readFloat() {
    196     byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
    197     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    198     assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0);
    199     assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0);
    200   }
    201 
    202   public void testNewDataInput_readDouble() {
    203     byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
    204     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    205     assertEquals(Double.longBitsToDouble(0x1234567876543210L), in.readDouble(), 0.0);
    206   }
    207 
    208   public void testNewDataInput_readUTF() throws UnsupportedEncodingException {
    209     byte[] data = new byte[17];
    210     data[1] = 15;
    211     System.arraycopy("Kilroy was here".getBytes(Charsets.UTF_8.name()), 0, data, 2, 15);
    212     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    213     assertEquals("Kilroy was here", in.readUTF());
    214   }
    215 
    216   public void testNewDataInput_readChar() throws UnsupportedEncodingException {
    217     byte[] data = "qed".getBytes(Charsets.UTF_16BE.name());
    218     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    219     assertEquals('q', in.readChar());
    220     assertEquals('e', in.readChar());
    221     assertEquals('d', in.readChar());
    222   }
    223 
    224   public void testNewDataInput_readUnsignedShort() {
    225     byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34};
    226     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    227     assertEquals(0, in.readUnsignedShort());
    228     assertEquals(1, in.readUnsignedShort());
    229     assertEquals(65535, in.readUnsignedShort());
    230     assertEquals(0x1234, in.readUnsignedShort());
    231   }
    232 
    233   public void testNewDataInput_readLong() {
    234     byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
    235     ByteArrayDataInput in = ByteStreams.newDataInput(data);
    236     assertEquals(0x1234567876543210L, in.readLong());
    237   }
    238 
    239   public void testNewDataInput_readBoolean() {
    240     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    241     assertTrue(in.readBoolean());
    242   }
    243 
    244   public void testNewDataInput_readByte() {
    245     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    246     for (int i = 0; i < bytes.length; i++) {
    247       assertEquals(bytes[i], in.readByte());
    248     }
    249     try {
    250       in.readByte();
    251       fail("expected exception");
    252     } catch (IllegalStateException ex) {
    253       assertTrue(ex.getCause() instanceof EOFException);
    254     }
    255   }
    256 
    257   public void testNewDataInput_readUnsignedByte() {
    258     ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
    259     for (int i = 0; i < bytes.length; i++) {
    260       assertEquals(bytes[i], in.readUnsignedByte());
    261     }
    262     try {
    263       in.readUnsignedByte();
    264       fail("expected exception");
    265     } catch (IllegalStateException ex) {
    266       assertTrue(ex.getCause() instanceof EOFException);
    267     }
    268   }
    269 
    270   public void testNewDataInput_offset() {
    271     ByteArrayDataInput in = ByteStreams.newDataInput(bytes, 2);
    272     assertEquals(0x56787654, in.readInt());
    273     try {
    274       in.readInt();
    275       fail("expected exception");
    276     } catch (IllegalStateException expected) {
    277     }
    278   }
    279 
    280   public void testNewDataInput_skip() {
    281     ByteArrayDataInput in = ByteStreams.newDataInput(new byte[2]);
    282     assertEquals(2, in.skipBytes(2));
    283     assertEquals(0, in.skipBytes(1));
    284   }
    285 
    286   public void testNewDataInput_BAIS() {
    287     ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] {0x12, 0x34, 0x56, 0x78});
    288     ByteArrayDataInput in = ByteStreams.newDataInput(bais);
    289     assertEquals(0x12345678, in.readInt());
    290   }
    291 
    292   public void testNewDataOutput_empty() {
    293     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    294     assertEquals(0, out.toByteArray().length);
    295   }
    296 
    297   public void testNewDataOutput_writeInt() {
    298     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    299     out.writeInt(0x12345678);
    300     out.writeInt(0x76543210);
    301     assertEquals(bytes, out.toByteArray());
    302   }
    303 
    304   public void testNewDataOutput_sized() {
    305     ByteArrayDataOutput out = ByteStreams.newDataOutput(4);
    306     out.writeInt(0x12345678);
    307     out.writeInt(0x76543210);
    308     assertEquals(bytes, out.toByteArray());
    309   }
    310 
    311   public void testNewDataOutput_writeLong() {
    312     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    313     out.writeLong(0x1234567876543210L);
    314     assertEquals(bytes, out.toByteArray());
    315   }
    316 
    317   public void testNewDataOutput_writeByteArray() {
    318     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    319     out.write(bytes);
    320     assertEquals(bytes, out.toByteArray());
    321   }
    322 
    323   public void testNewDataOutput_writeByte() {
    324     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    325     out.write(0x12);
    326     out.writeByte(0x34);
    327     assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
    328   }
    329 
    330   public void testNewDataOutput_writeByteOffset() {
    331     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    332     out.write(bytes, 4, 2);
    333     byte[] expected = {bytes[4], bytes[5]};
    334     assertEquals(expected, out.toByteArray());
    335   }
    336 
    337   public void testNewDataOutput_writeBoolean() {
    338     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    339     out.writeBoolean(true);
    340     out.writeBoolean(false);
    341     byte[] expected = {(byte) 1, (byte) 0};
    342     assertEquals(expected, out.toByteArray());
    343   }
    344 
    345   public void testNewDataOutput_writeChar() {
    346     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    347     out.writeChar('a');
    348     assertEquals(new byte[] {0, 97}, out.toByteArray());
    349   }
    350 
    351   public void testNewDataOutput_writeChars() throws UnsupportedEncodingException {
    352     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    353     out.writeChars("r\u00C9sum\u00C9");
    354     // need to remove byte order mark before comparing
    355     byte[] expected = Arrays.copyOfRange("r\u00C9sum\u00C9".getBytes(UTF_16.name()), 2, 14);
    356     assertEquals(expected, out.toByteArray());
    357   }
    358 
    359   public void testNewDataOutput_writeUTF() throws UnsupportedEncodingException {
    360     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    361     out.writeUTF("r\u00C9sum\u00C9");
    362     byte[] expected ="r\u00C9sum\u00C9".getBytes(Charsets.UTF_8.name());
    363     byte[] actual = out.toByteArray();
    364     // writeUTF writes the length of the string in 2 bytes
    365     assertEquals(0, actual[0]);
    366     assertEquals(expected.length, actual[1]);
    367     assertEquals(expected, Arrays.copyOfRange(actual, 2, actual.length));
    368   }
    369 
    370   public void testNewDataOutput_writeShort() {
    371     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    372     out.writeShort(0x1234);
    373     assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
    374   }
    375 
    376   public void testNewDataOutput_writeDouble() {
    377     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    378     out.writeDouble(Double.longBitsToDouble(0x1234567876543210L));
    379     assertEquals(bytes, out.toByteArray());
    380   }
    381 
    382   public void testNewDataOutput_writeFloat() {
    383     ByteArrayDataOutput out = ByteStreams.newDataOutput();
    384     out.writeFloat(Float.intBitsToFloat(0x12345678));
    385     out.writeFloat(Float.intBitsToFloat(0x76543210));
    386     assertEquals(bytes, out.toByteArray());
    387   }
    388 
    389   public void testChecksum() throws IOException {
    390     InputSupplier<ByteArrayInputStream> asciiBytes =
    391         ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII.name()));
    392     InputSupplier<ByteArrayInputStream> i18nBytes =
    393         ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8.name()));
    394 
    395     Checksum checksum = new CRC32();
    396     assertEquals(0L, checksum.getValue());
    397     assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
    398     assertEquals(0L, checksum.getValue());
    399     assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
    400     assertEquals(1138302340L, ByteStreams.getChecksum(i18nBytes, checksum));
    401     assertEquals(0L, checksum.getValue());
    402   }
    403 
    404   public void testNewDataOutput_BAOS() {
    405     ByteArrayOutputStream baos = new ByteArrayOutputStream();
    406     ByteArrayDataOutput out = ByteStreams.newDataOutput(baos);
    407     out.writeInt(0x12345678);
    408     assertEquals(4, baos.size());
    409     assertEquals(new byte[] {0x12, 0x34, 0x56, 0x78}, baos.toByteArray());
    410   }
    411 
    412   public void testToByteArray_withSize_givenCorrectSize() throws IOException {
    413     InputStream in = newTestStream(100);
    414     byte[] b = ByteStreams.toByteArray(in, 100);
    415     assertEquals(100, b.length);
    416   }
    417 
    418   public void testToByteArray_withSize_givenSmallerSize() throws IOException {
    419     InputStream in = newTestStream(100);
    420     byte[] b = ByteStreams.toByteArray(in, 80);
    421     assertEquals(100, b.length);
    422   }
    423 
    424   public void testToByteArray_withSize_givenLargerSize() throws IOException {
    425     InputStream in = newTestStream(100);
    426     byte[] b = ByteStreams.toByteArray(in, 120);
    427     assertEquals(100, b.length);
    428   }
    429 
    430   public void testToByteArray_withSize_givenSizeZero() throws IOException {
    431     InputStream in = newTestStream(100);
    432     byte[] b = ByteStreams.toByteArray(in, 0);
    433     assertEquals(100, b.length);
    434   }
    435 
    436   private static InputStream newTestStream(int n) {
    437     return new ByteArrayInputStream(newPreFilledByteArray(n));
    438   }
    439 
    440   /** Stream that will skip a maximum number of bytes at a time. */
    441   private static class SlowSkipper extends FilterInputStream {
    442     private final long max;
    443 
    444     public SlowSkipper(InputStream in, long max) {
    445       super(in);
    446       this.max = max;
    447     }
    448 
    449     @Override public long skip(long n) throws IOException {
    450       return super.skip(Math.min(max, n));
    451     }
    452   }
    453 
    454   public void testReadBytes() throws IOException {
    455     final byte[] array = newPreFilledByteArray(1000);
    456     assertEquals(array, ByteStreams.readBytes(
    457       new ByteArrayInputStream(array), new TestByteProcessor()));
    458   }
    459 
    460   private class TestByteProcessor implements ByteProcessor<byte[]> {
    461     private final ByteArrayOutputStream out = new ByteArrayOutputStream();
    462 
    463     @Override
    464     public boolean processBytes(byte[] buf, int off, int len)
    465         throws IOException {
    466       out.write(buf, off, len);
    467       return true;
    468     }
    469 
    470     @Override
    471     public byte[] getResult() {
    472       return out.toByteArray();
    473     }
    474   }
    475 
    476   public void testByteProcessorStopEarly() throws IOException {
    477     byte[] array = newPreFilledByteArray(6000);
    478     assertEquals((Integer) 42,
    479         ByteStreams.readBytes(new ByteArrayInputStream(array),
    480             new ByteProcessor<Integer>() {
    481               @Override
    482               public boolean processBytes(byte[] buf, int off, int len) {
    483                 assertEquals(
    484                     copyOfRange(buf, off, off + len),
    485                     newPreFilledByteArray(4096));
    486                 return false;
    487               }
    488 
    489               @Override
    490               public Integer getResult() {
    491                 return 42;
    492               }
    493             }));
    494   }
    495 
    496   public void testNullOutputStream() throws Exception {
    497     // create a null output stream
    498     OutputStream nos = ByteStreams.nullOutputStream();
    499     // write to the output stream
    500     nos.write('n');
    501     String test = "Test string for NullOutputStream";
    502     nos.write(test.getBytes());
    503     nos.write(test.getBytes(), 2, 10);
    504     // nothing really to assert?
    505     assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream());
    506   }
    507 
    508   public void testLimit() throws Exception {
    509     byte[] big = newPreFilledByteArray(5);
    510     InputStream bin = new ByteArrayInputStream(big);
    511     InputStream lin = ByteStreams.limit(bin, 2);
    512 
    513     // also test available
    514     lin.mark(2);
    515     assertEquals(2, lin.available());
    516     int read = lin.read();
    517     assertEquals(big[0], read);
    518     assertEquals(1, lin.available());
    519     read = lin.read();
    520     assertEquals(big[1], read);
    521     assertEquals(0, lin.available());
    522     read = lin.read();
    523     assertEquals(-1, read);
    524 
    525     lin.reset();
    526     byte[] small = new byte[5];
    527     read = lin.read(small);
    528     assertEquals(2, read);
    529     assertEquals(big[0], small[0]);
    530     assertEquals(big[1], small[1]);
    531 
    532     lin.reset();
    533     read = lin.read(small, 2, 3);
    534     assertEquals(2, read);
    535     assertEquals(big[0], small[2]);
    536     assertEquals(big[1], small[3]);
    537   }
    538 
    539   public void testLimit_mark() throws Exception {
    540     byte[] big = newPreFilledByteArray(5);
    541     InputStream bin = new ByteArrayInputStream(big);
    542     InputStream lin = ByteStreams.limit(bin, 2);
    543 
    544     int read = lin.read();
    545     assertEquals(big[0], read);
    546     lin.mark(2);
    547 
    548     read = lin.read();
    549     assertEquals(big[1], read);
    550     read = lin.read();
    551     assertEquals(-1, read);
    552 
    553     lin.reset();
    554     read = lin.read();
    555     assertEquals(big[1], read);
    556     read = lin.read();
    557     assertEquals(-1, read);
    558   }
    559 
    560   public void testLimit_skip() throws Exception {
    561     byte[] big = newPreFilledByteArray(5);
    562     InputStream bin = new ByteArrayInputStream(big);
    563     InputStream lin = ByteStreams.limit(bin, 2);
    564 
    565     // also test available
    566     lin.mark(2);
    567     assertEquals(2, lin.available());
    568     lin.skip(1);
    569     assertEquals(1, lin.available());
    570 
    571     lin.reset();
    572     assertEquals(2, lin.available());
    573     lin.skip(3);
    574     assertEquals(0, lin.available());
    575   }
    576 
    577   public void testLimit_markNotSet() {
    578     byte[] big = newPreFilledByteArray(5);
    579     InputStream bin = new ByteArrayInputStream(big);
    580     InputStream lin = ByteStreams.limit(bin, 2);
    581 
    582     try {
    583       lin.reset();
    584       fail();
    585     } catch (IOException expected) {
    586       assertEquals("Mark not set", expected.getMessage());
    587     }
    588   }
    589 
    590   public void testLimit_markNotSupported() {
    591     InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2);
    592 
    593     try {
    594       lin.reset();
    595       fail();
    596     } catch (IOException expected) {
    597       assertEquals("Mark not supported", expected.getMessage());
    598     }
    599   }
    600 
    601   private static class UnmarkableInputStream extends InputStream {
    602     @Override
    603     public int read() throws IOException {
    604       return 0;
    605     }
    606 
    607     @Override
    608     public boolean markSupported() {
    609       return false;
    610     }
    611   }
    612 
    613   private static byte[] copyOfRange(byte[] in, int from, int to) {
    614     byte[] out = new byte[to - from];
    615     for (int i = 0; i < to - from; i++) {
    616       out[i] = in[from + i];
    617     }
    618     return out;
    619   }
    620 
    621   private static void assertEquals(byte[] expected, byte[] actual) {
    622     assertTrue(Arrays.equals(expected, actual));
    623   }
    624 }
    625