Repository: commons-compress Updated Branches: refs/heads/master b743bb24b -> 0d0dfb142
tweak ByteUtils Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/ea4d697c Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/ea4d697c Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/ea4d697c Branch: refs/heads/master Commit: ea4d697cb86beb3cab57a16a5c5ebb6e4e516c67 Parents: b743bb2 Author: Stefan Bodewig <[email protected]> Authored: Wed Jan 18 20:48:59 2017 +0100 Committer: Stefan Bodewig <[email protected]> Committed: Wed Jan 18 20:48:59 2017 +0100 ---------------------------------------------------------------------- .../commons/compress/utils/ByteUtils.java | 37 +++++-- .../commons/compress/utils/ByteUtilsTest.java | 104 +++++++++++++++++++ 2 files changed, 133 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/ea4d697c/src/main/java/org/apache/commons/compress/utils/ByteUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/utils/ByteUtils.java b/src/main/java/org/apache/commons/compress/utils/ByteUtils.java index 405a0e3..be4b83b 100644 --- a/src/main/java/org/apache/commons/compress/utils/ByteUtils.java +++ b/src/main/java/org/apache/commons/compress/utils/ByteUtils.java @@ -69,9 +69,7 @@ public final class ByteUtils { * @throws IllegalArgumentException if len is bigger than eight */ public static long fromLittleEndian(byte[] bytes, final int off, final int length) { - if (length > 8) { - throw new IllegalArgumentException("can't read more than eight bytes into a long value"); - } + checkReadLength(length); long l = 0; for (int i = 0; i < length; i++) { l |= (bytes[off + i] & 0xffl) << (8 * i); @@ -88,11 +86,25 @@ public final class ByteUtils { * contain the given number of bytes anymore */ public static long fromLittleEndian(InputStream in, int length) throws IOException { - return fromLittleEndian(new InputStreamByteSupplier(in), length); + // somewhat duplicates the ByteSupplier version in order to save othe creation of a wrapper object + checkReadLength(length); + long l = 0; + for (int i = 0; i < length; i++) { + int b = in.read(); + if (b == -1) { + throw new IOException("premature end of data"); + } + l |= (b << (i * 8)); + } + return l; } /** * Reads the given number of bytes from the given supplier as a little endian long. + * + * <p>Typically used by our InputStreams that need to count the + * bytes read as well.</p> + * * @param supplier the supplier for bytes * @param length the number of bytes representing the value * @throws IllegalArgumentException if len is bigger than eight @@ -100,9 +112,7 @@ public final class ByteUtils { * given number of bytes anymore */ public static long fromLittleEndian(ByteSupplier supplier, final int length) throws IOException { - if (length > 8) { - throw new IllegalArgumentException("can't read more than eight bytes into a long value"); - } + checkReadLength(length); long l = 0; for (int i = 0; i < length; i++) { int b = supplier.getAsByte(); @@ -124,7 +134,12 @@ public final class ByteUtils { */ public static void toLittleEndian(OutputStream out, final long value, final int length) throws IOException { - toLittleEndian(new OutputStreamByteConsumer(out), value, length); + // somewhat duplicates the ByteConsumer version in order to save othe creation of a wrapper object + long num = value; + for (int i = 0; i < length; i++) { + out.write((int) (num & 0xff)); + num >>= 8; + } } /** @@ -173,4 +188,10 @@ public final class ByteUtils { os.write(b); } } + + private static final void checkReadLength(int length) { + if (length > 8) { + throw new IllegalArgumentException("can't read more than eight bytes into a long value"); + } + } } http://git-wip-us.apache.org/repos/asf/commons-compress/blob/ea4d697c/src/test/java/org/apache/commons/compress/utils/ByteUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/utils/ByteUtilsTest.java b/src/test/java/org/apache/commons/compress/utils/ByteUtilsTest.java new file mode 100644 index 0000000..61e64f6 --- /dev/null +++ b/src/test/java/org/apache/commons/compress/utils/ByteUtilsTest.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.commons.compress.utils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.junit.Test; + +import static org.apache.commons.compress.utils.ByteUtils.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class ByteUtilsTest { + + @Test + public void fromLittleEndianFromArrayOneArg() { + byte[] b = new byte[] { 2, 3, 4 }; + assertEquals(2 + 3 * 256 + 4 * 256 * 256, fromLittleEndian(b)); + } + + @Test(expected = IllegalArgumentException.class) + public void fromLittleEndianFromArrayOneArgThrowsForLengthTooBig() { + fromLittleEndian(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); + } + + @Test + public void fromLittleEndianFromArray() { + byte[] b = new byte[] { 1, 2, 3, 4, 5 }; + assertEquals(2 + 3 * 256 + 4 * 256 * 256, fromLittleEndian(b, 1, 3)); + } + + @Test(expected = IllegalArgumentException.class) + public void fromLittleEndianFromArrayThrowsForLengthTooBig() { + fromLittleEndian(new byte[0], 0, 9); + } + + @Test + public void fromLittleEndianFromStream() throws IOException { + ByteArrayInputStream bin = new ByteArrayInputStream(new byte[] { 2, 3, 4, 5 }); + assertEquals(2 + 3 * 256 + 4 * 256 * 256, fromLittleEndian(bin, 3)); + } + + @Test(expected = IllegalArgumentException.class) + public void fromLittleEndianFromStreamThrowsForLengthTooBig() throws IOException { + fromLittleEndian(new ByteArrayInputStream(new byte[0]), 9); + } + + @Test(expected = IOException.class) + public void fromLittleEndianFromStreamThrowsForPrematureEnd() throws IOException { + ByteArrayInputStream bin = new ByteArrayInputStream(new byte[] { 2, 3 }); + fromLittleEndian(bin, 3); + } + + @Test + public void fromLittleEndianFromSupplier() throws IOException { + ByteArrayInputStream bin = new ByteArrayInputStream(new byte[] { 2, 3, 4, 5 }); + assertEquals(2 + 3 * 256 + 4 * 256 * 256, fromLittleEndian(new InputStreamByteSupplier(bin), 3)); + } + + @Test(expected = IllegalArgumentException.class) + public void fromLittleEndianFromSupplierThrowsForLengthTooBig() throws IOException { + fromLittleEndian(new InputStreamByteSupplier(new ByteArrayInputStream(new byte[0])), 9); + } + + @Test(expected = IOException.class) + public void fromLittleEndianFromSupplierThrowsForPrematureEnd() throws IOException { + ByteArrayInputStream bin = new ByteArrayInputStream(new byte[] { 2, 3 }); + fromLittleEndian(new InputStreamByteSupplier(bin), 3); + } + + @Test + public void toLittleEndianToStream() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + toLittleEndian(bos, 2 + 3 * 256 + 4 * 256 * 256, 3); + bos.close(); + assertArrayEquals(new byte[] { 2, 3, 4 }, bos.toByteArray()); + } + + @Test + public void toLittleEndianToConsumer() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + toLittleEndian(new OutputStreamByteConsumer(bos), 2 + 3 * 256 + 4 * 256 * 256, 3); + bos.close(); + assertArrayEquals(new byte[] { 2, 3, 4 }, bos.toByteArray()); + } +}
