1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License"); 5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License. 6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at 7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0 9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software 11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS, 12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and 14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License. 15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.io; 18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 20bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport com.google.common.base.Preconditions; 21bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 22bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.ByteArrayInputStream; 23bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.ByteArrayOutputStream; 24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.DataInput; 25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.DataInputStream; 26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.DataOutput; 27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.DataOutputStream; 28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.EOFException; 29bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.IOException; 30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.InputStream; 31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.OutputStream; 32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.nio.ByteBuffer; 33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.nio.channels.ReadableByteChannel; 34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.nio.channels.WritableByteChannel; 35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.security.MessageDigest; 36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Arrays; 37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.zip.Checksum; 38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/** 40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Provides utility methods for working with byte arrays and I/O streams. 41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>All method parameters must be non-null unless documented otherwise. 43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Chris Nokleberg 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0 46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic final class ByteStreams { 49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private static final int BUF_SIZE = 0x1000; // 4K 50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private ByteStreams() {} 52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 53bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a factory that will supply instances of 55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@link ByteArrayInputStream} that read from the given byte array. 56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the input buffer 58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the factory 59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier( 61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] b) { 62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return newInputStreamSupplier(b, 0, b.length); 63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a factory that will supply instances of 67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@link ByteArrayInputStream} that read from the given byte array. 68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the input buffer 70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param off the offset in the buffer of the first byte to read 71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param len the maximum number of bytes to read from the buffer 72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the factory 73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier( 75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final byte[] b, final int off, final int len) { 76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new InputSupplier<ByteArrayInputStream>() { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public ByteArrayInputStream getInput() { 79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ByteArrayInputStream(b, off, len); 80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor }; 82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Writes a byte array to an output stream from the given supplier. 86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param from the bytes to write 88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param to the output supplier 89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static void write(byte[] from, 92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor OutputSupplier<? extends OutputStream> to) throws IOException { 93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkNotNull(from); 94bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 95bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor OutputStream out = to.getOutput(); 96bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 97bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor out.write(from); 98bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 99bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 100bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(out, threw); 101bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 102bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 103bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 104bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 105bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Opens input and output streams from the given suppliers, copies all 106bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * bytes from the input to the output, and closes the streams. 107bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 108bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param from the input factory 109bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param to the output factory 110bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the number of bytes copied 111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 113bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long copy(InputSupplier<? extends InputStream> from, 114bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor OutputSupplier<? extends OutputStream> to) throws IOException { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int successfulOps = 0; 116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = from.getInput(); 117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor OutputStream out = to.getOutput(); 119bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long count = copy(in, out); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert successfulOps++; 122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return count; 123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(out, successfulOps < 1); 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert successfulOps++; 126bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 127bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(in, successfulOps < 2); 129bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 130bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 131bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 132bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 133bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Opens an input stream from the supplier, copies all bytes from the 134bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * input to the output, and closes the input stream. Does not close 135bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * or flush the output stream. 136bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 137bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param from the input factory 138bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param to the output stream to write to 139bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the number of bytes copied 140bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 141bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 142bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long copy(InputSupplier<? extends InputStream> from, 143bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor OutputStream to) throws IOException { 144bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 145bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = from.getInput(); 146bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 147bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long count = copy(in, to); 148bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 149bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return count; 150bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 151bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in, threw); 152bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 153bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 154bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 155bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Opens an output stream from the supplier, copies all bytes from the input 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to the output, and closes the output stream. Does not close or flush the 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * output stream. 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param from the input stream to read from 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param to the output factory 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the number of bytes copied 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IOException if an I/O error occurs 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static long copy(InputStream from, 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert OutputSupplier<? extends OutputStream> to) throws IOException { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean threw = true; 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert OutputStream out = to.getOutput(); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long count = copy(from, out); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threw = false; 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return count; 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } finally { 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(out, threw); 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Copies all bytes from the input stream to the output stream. 181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Does not close or flush either stream. 182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param from the input stream to read from 184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param to the output stream to write to 185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the number of bytes copied 186bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 187bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 188bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long copy(InputStream from, OutputStream to) 189bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throws IOException { 190bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] buf = new byte[BUF_SIZE]; 191bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long total = 0; 192bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (true) { 193bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int r = from.read(buf); 194bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (r == -1) { 195bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor break; 196bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 197bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor to.write(buf, 0, r); 198bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor total += r; 199bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 200bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return total; 201bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 202bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 203bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 204bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Copies all bytes from the readable channel to the writable channel. 205bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Does not close or flush either channel. 206bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 207bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param from the readable channel to read from 208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param to the writable channel to write to 209bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the number of bytes copied 210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long copy(ReadableByteChannel from, 213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor WritableByteChannel to) throws IOException { 214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE); 215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long total = 0; 216bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (from.read(buf) != -1) { 217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor buf.flip(); 218bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (buf.hasRemaining()) { 219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor total += to.write(buf); 220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor buf.clear(); 222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return total; 224bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 225bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 226bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 227bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Reads all bytes from an input stream into a byte array. 228bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Does not close the stream. 229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to read from 231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a byte array containing all the bytes from the stream 232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static byte[] toByteArray(InputStream in) throws IOException { 235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayOutputStream out = new ByteArrayOutputStream(); 236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor copy(in, out); 237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return out.toByteArray(); 238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 239bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 240bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns the data from a {@link InputStream} factory as a byte array. 242bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 243bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param supplier the factory 244bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 245bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 246bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static byte[] toByteArray( 247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputSupplier<? extends InputStream> supplier) throws IOException { 248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = supplier.getInput(); 250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] result = toByteArray(in); 252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 254bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in, threw); 256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a new {@link ByteArrayDataInput} instance to read from the {@code 261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * bytes} array from the beginning. 262bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 263bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static ByteArrayDataInput newDataInput(byte[] bytes) { 264bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ByteArrayDataInputStream(bytes); 265bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 266bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 267bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 268bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a new {@link ByteArrayDataInput} instance to read from the {@code 269bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * bytes} array, starting at the given position. 270bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 271bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IndexOutOfBoundsException if {@code start} is negative or greater 272bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * than the length of the array 273bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 274bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static ByteArrayDataInput newDataInput(byte[] bytes, int start) { 275bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkPositionIndex(start, bytes.length); 276bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ByteArrayDataInputStream(bytes, start); 277bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 278bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 279bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private static class ByteArrayDataInputStream implements ByteArrayDataInput { 280bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final DataInput input; 281bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 282bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayDataInputStream(byte[] bytes) { 283bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.input = new DataInputStream(new ByteArrayInputStream(bytes)); 284bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 285bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 286bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayDataInputStream(byte[] bytes, int start) { 287bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.input = new DataInputStream( 288bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor new ByteArrayInputStream(bytes, start, bytes.length - start)); 289bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 290bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void readFully(byte b[]) { 292bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 293bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor input.readFully(b); 294bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 295bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 296bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 297bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 298bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void readFully(byte b[], int off, int len) { 300bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 301bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor input.readFully(b, off, len); 302bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 303bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 304bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 305bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 306bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int skipBytes(int n) { 308bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 309bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.skipBytes(n); 310bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 311bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 312bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 313bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 314bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean readBoolean() { 316bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 317bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readBoolean(); 318bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 319bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 320bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 321bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 322bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public byte readByte() { 324bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 325bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readByte(); 326bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (EOFException e) { 327bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 328bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 329bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 330bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 331bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 332bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int readUnsignedByte() { 334bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 335bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readUnsignedByte(); 336bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 337bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 338bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 339bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 340bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public short readShort() { 342bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 343bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readShort(); 344bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 345bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 346bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 347bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 348bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int readUnsignedShort() { 350bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 351bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readUnsignedShort(); 352bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 353bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 354bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 355bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 356bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public char readChar() { 358bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 359bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readChar(); 360bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 361bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 362bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 363bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 364bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int readInt() { 366bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 367bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readInt(); 368bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 369bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 370bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 371bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 372bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public long readLong() { 374bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 375bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readLong(); 376bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 377bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 378bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 379bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 380bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public float readFloat() { 382bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 383bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readFloat(); 384bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 385bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 386bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 387bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 388bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public double readDouble() { 390bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 391bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readDouble(); 392bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 393bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 394bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 395bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 396bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String readLine() { 398bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 399bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readLine(); 400bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 401bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 402bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 403bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 404bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String readUTF() { 406bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 407bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return input.readUTF(); 408bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 409bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IllegalStateException(e); 410bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 411bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 412bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 413bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 414bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 415bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a new {@link ByteArrayDataOutput} instance with a default size. 416bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 417bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static ByteArrayDataOutput newDataOutput() { 418bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ByteArrayDataOutputStream(); 419bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 420bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 421bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 422bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns a new {@link ByteArrayDataOutput} instance sized to hold 423bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code size} bytes before resizing. 424bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 425bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IllegalArgumentException if {@code size} is negative 426bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 427bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static ByteArrayDataOutput newDataOutput(int size) { 428bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkArgument(size >= 0, "Invalid size: %s", size); 429bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new ByteArrayDataOutputStream(size); 430bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 431bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 432bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor @SuppressWarnings("deprecation") // for writeBytes 433bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor private static class ByteArrayDataOutputStream 434bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor implements ByteArrayDataOutput { 435bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 436bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final DataOutput output; 437bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final ByteArrayOutputStream byteArrayOutputSteam; 438bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 439bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayDataOutputStream() { 440bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this(new ByteArrayOutputStream()); 441bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 442bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 443bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayDataOutputStream(int size) { 444bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this(new ByteArrayOutputStream(size)); 445bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 446bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 447bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteArrayDataOutputStream(ByteArrayOutputStream byteArrayOutputSteam) { 448bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor this.byteArrayOutputSteam = byteArrayOutputSteam; 449bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output = new DataOutputStream(byteArrayOutputSteam); 450bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 451bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void write(int b) { 453bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 454bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.write(b); 455bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 456bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 457bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 458bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 459bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void write(byte[] b) { 461bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 462bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.write(b); 463bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 464bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 465bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 466bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 467bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void write(byte[] b, int off, int len) { 469bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 470bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.write(b, off, len); 471bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 472bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 473bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 474bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 475bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeBoolean(boolean v) { 477bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 478bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeBoolean(v); 479bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 480bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 481bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 482bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 483bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeByte(int v) { 485bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 486bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeByte(v); 487bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 488bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 489bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 490bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 491bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeBytes(String s) { 493bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 494bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeBytes(s); 495bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 496bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 497bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 498bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 499bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeChar(int v) { 501bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 502bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeChar(v); 503bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 504bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 505bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 506bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 507bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeChars(String s) { 509bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 510bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeChars(s); 511bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 512bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 513bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 514bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 515bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeDouble(double v) { 517bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 518bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeDouble(v); 519bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 520bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 521bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 522bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 523bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeFloat(float v) { 525bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 526bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeFloat(v); 527bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 528bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 529bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 530bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 531bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeInt(int v) { 533bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 534bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeInt(v); 535bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 536bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 537bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 538bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 539bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeLong(long v) { 541bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 542bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeLong(v); 543bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 544bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 545bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 546bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 547bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeShort(int v) { 549bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 550bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeShort(v); 551bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 552bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 553bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 554bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 555bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void writeUTF(String s) { 557bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 558bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor output.writeUTF(s); 559bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException impossible) { 560bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new AssertionError(impossible); 561bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 562bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 563bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public byte[] toByteArray() { 565bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return byteArrayOutputSteam.toByteArray(); 566bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 567bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 568bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 569bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(chrisn): Not all streams support skipping. 571bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** Returns the length of a supplied input stream, in bytes. */ 572bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long length(InputSupplier<? extends InputStream> supplier) 573bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throws IOException { 574bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long count = 0; 575bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 576bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = supplier.getInput(); 577bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 578bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (true) { 579bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // We skip only Integer.MAX_VALUE due to JDK overflow bugs. 580bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long amt = in.skip(Integer.MAX_VALUE); 581bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (amt == 0) { 582bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (in.read() == -1) { 583bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 584bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return count; 585bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 586bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count++; 587bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } else { 588bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor count += amt; 589bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 590bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 591bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 592bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in, threw); 593bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 594bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 595bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 596bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 597bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns true if the supplied input streams contain the same bytes. 598bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 599bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 600bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 601bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static boolean equal(InputSupplier<? extends InputStream> supplier1, 602bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputSupplier<? extends InputStream> supplier2) throws IOException { 603bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] buf1 = new byte[BUF_SIZE]; 604bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] buf2 = new byte[BUF_SIZE]; 605bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 606bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 607bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in1 = supplier1.getInput(); 608bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 609bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in2 = supplier2.getInput(); 610bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 611bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (true) { 612bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int read1 = read(in1, buf1, 0, BUF_SIZE); 613bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int read2 = read(in2, buf2, 0, BUF_SIZE); 614bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (read1 != read2 || !Arrays.equals(buf1, buf2)) { 615bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 616bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 617bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } else if (read1 != BUF_SIZE) { 618bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 619bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 620bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 621bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 622bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 623bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in2, threw); 624bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 625bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 626bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in1, threw); 627bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 628bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 629bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 630bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 631bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Attempts to read enough bytes from the stream to fill the given byte array, 632bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * with the same behavior as {@link DataInput#readFully(byte[])}. 633bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Does not close the stream. 634bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 635bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to read from. 636bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the buffer into which the data is read. 637bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws EOFException if this stream reaches the end before reading all 638bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the bytes. 639bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs. 640bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 641bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static void readFully(InputStream in, byte[] b) throws IOException { 642bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor readFully(in, b, 0, b.length); 643bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 644bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 645bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 646bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Attempts to read {@code len} bytes from the stream into the given array 647bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * starting at {@code off}, with the same behavior as 648bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@link DataInput#readFully(byte[], int, int)}. Does not close the 649bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * stream. 650bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 651bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to read from. 652bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the buffer into which the data is read. 653bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param off an int specifying the offset into the data. 654bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param len an int specifying the number of bytes to read. 655bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws EOFException if this stream reaches the end before reading all 656bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the bytes. 657bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs. 658bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 659bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static void readFully(InputStream in, byte[] b, int off, int len) 660bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throws IOException { 661bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (read(in, b, off, len) != len) { 662bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new EOFException(); 663bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 664bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 665bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 666bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 667bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Discards {@code n} bytes of data from the input stream. This method 668bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * will block until the full amount has been skipped. Does not close the 669bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * stream. 670bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 671bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to read from 672bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param n the number of bytes to skip 673bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws EOFException if this stream reaches the end before skipping all 674bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the bytes 675bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs, or the stream does not 676bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * support skipping 677bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 678bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static void skipFully(InputStream in, long n) throws IOException { 679bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (n > 0) { 680bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long amt = in.skip(n); 681bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (amt == 0) { 682bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Force a blocking read to avoid infinite loop 683bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (in.read() == -1) { 684bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new EOFException(); 685bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 686bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor n--; 687bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } else { 688bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor n -= amt; 689bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 690bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 691bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 692bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 693bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 694bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Process the bytes of a supplied stream 695bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 696bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param supplier the input stream factory 697bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param processor the object to which to pass the bytes of the stream 698bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the result of the byte processor 699bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 700bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 701bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static <T> T readBytes(InputSupplier<? extends InputStream> supplier, 702bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ByteProcessor<T> processor) throws IOException { 703bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor byte[] buf = new byte[BUF_SIZE]; 704bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor boolean threw = true; 705bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = supplier.getInput(); 706bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 707bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int amt; 708bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor do { 709bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor amt = in.read(buf); 710bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (amt == -1) { 711bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor threw = false; 712bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor break; 713bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 714bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } while (processor.processBytes(buf, 0, amt)); 715bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return processor.getResult(); 716bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } finally { 717bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.close(in, threw); 718bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 719bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 720bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 721bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 722bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Computes and returns the checksum value for a supplied input stream. 723bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * The checksum object is reset when this method returns successfully. 724bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 725bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param supplier the input stream factory 726bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param checksum the checksum object 727bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the result of {@link Checksum#getValue} after updating the 728bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * checksum object with all of the bytes in the stream 729bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 730bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 731bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static long getChecksum(InputSupplier<? extends InputStream> supplier, 732bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final Checksum checksum) throws IOException { 733bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return readBytes(supplier, new ByteProcessor<Long>() { 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 735bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public boolean processBytes(byte[] buf, int off, int len) { 736bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checksum.update(buf, off, len); 737bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 738bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 739bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 741bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public Long getResult() { 742bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor long result = checksum.getValue(); 743bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor checksum.reset(); 744bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return result; 745bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 746bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor }); 747bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 748bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 749bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 750bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Computes and returns the digest value for a supplied input stream. 751bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * The digest object is reset when this method returns successfully. 752bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 753bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param supplier the input stream factory 754bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param md the digest object 755bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the result of {@link MessageDigest#digest()} after updating the 756bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * digest object with all of the bytes in the stream 757bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 758bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 759bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static byte[] getDigest(InputSupplier<? extends InputStream> supplier, 760bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final MessageDigest md) throws IOException { 761bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return readBytes(supplier, new ByteProcessor<byte[]>() { 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 763bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public boolean processBytes(byte[] buf, int off, int len) { 764bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor md.update(buf, off, len); 765bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return true; 766bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 767bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 769bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public byte[] getResult() { 770bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return md.digest(); 771bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 772bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor }); 773bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 774bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 775bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 776bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Reads some bytes from an input stream and stores them into the buffer array 777bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code b}. This method blocks until {@code len} bytes of input data have 778bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * been read into the array, or end of file is detected. The number of bytes 779bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * read is returned, possibly zero. Does not close the stream. 780bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 781bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>A caller can detect EOF if the number of bytes read is less than 782bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code len}. All subsequent calls on the same stream will return zero. 783bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 784bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>If {@code b} is null, a {@code NullPointerException} is thrown. If 785bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code off} is negative, or {@code len} is negative, or {@code off+len} is 786bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * greater than the length of the array {@code b}, then an 787bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code IndexOutOfBoundsException} is thrown. If {@code len} is zero, then 788bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * no bytes are read. Otherwise, the first byte read is stored into element 789bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code b[off]}, the next one into {@code b[off+1]}, and so on. The number 790bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * of bytes read is, at most, equal to {@code len}. 791bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 792bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param in the input stream to read from 793bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param b the buffer into which the data is read 794bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param off an int specifying the offset into the data 795bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param len an int specifying the number of bytes to read 796bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return the number of bytes read 797bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IOException if an I/O error occurs 798bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 799bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static int read(InputStream in, byte[] b, int off, int len) 800bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throws IOException { 801bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (len < 0) { 802bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw new IndexOutOfBoundsException("len is negative"); 803bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 804bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int total = 0; 805bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor while (total < len) { 806bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor int result = in.read(b, off + total, len - total); 807bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (result == -1) { 808bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor break; 809bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 810bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor total += result; 811bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 812bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return total; 813bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 814bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 815bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 816bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Returns an {@link InputSupplier} that returns input streams from the 817bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * an underlying supplier, where each stream starts at the given 818bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * offset and is limited to the specified number of bytes. 819bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 820bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param supplier the supplier from which to get the raw streams 821bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param offset the offset in bytes into the underlying stream where 822bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the returned streams will start 823bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param length the maximum length of the returned streams 824bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @throws IllegalArgumentException if offset or length are negative 825bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 826bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static InputSupplier<InputStream> slice( 827bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final InputSupplier<? extends InputStream> supplier, 828bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final long offset, 829bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor final long length) { 830bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkNotNull(supplier); 831bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkArgument(offset >= 0, "offset is negative"); 832bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Preconditions.checkArgument(length >= 0, "length is negative"); 833bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new InputSupplier<InputStream>() { 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public InputStream getInput() throws IOException { 835bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputStream in = supplier.getInput(); 836bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (offset > 0) { 837bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor try { 838bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor skipFully(in, offset); 839bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } catch (IOException e) { 840bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Closeables.closeQuietly(in); 841bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor throw e; 842bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 843bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 844bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new LimitInputStream(in, length); 845bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 846bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor }; 847bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 848bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 849bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** 850bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Joins multiple {@link InputStream} suppliers into a single supplier. 851bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Streams returned from the supplier will contain the concatenated data from 852bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * the streams of the underlying suppliers. 853bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 854bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>Only one underlying input stream will be open at a time. Closing the 855bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * joined stream will close the open underlying stream. 856bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 857bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>Reading from the joined stream will throw a {@link NullPointerException} 858bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * if any of the suppliers are null or return null. 859bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * 860bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @param suppliers the suppliers to concatenate 861bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @return a supplier that will return a stream containing the concatenated 862bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * stream data 863bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */ 864bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static InputSupplier<InputStream> join( 8651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Iterable<? extends InputSupplier<? extends InputStream>> suppliers) { 866bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new InputSupplier<InputStream>() { 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public InputStream getInput() throws IOException { 868bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return new MultiInputStream(suppliers.iterator()); 869bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 870bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor }; 871bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 872bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 873bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /** Varargs form of {@link #join(Iterable)}. */ 874bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor public static InputSupplier<InputStream> join( 875bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor InputSupplier<? extends InputStream>... suppliers) { 876bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return join(Arrays.asList(suppliers)); 877bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 878bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor} 879