![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.commons.compress.utils.ByteUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-compress Show documentation
Show all versions of commons-compress Show documentation
Apache Commons Compress defines an API for working with
compression and archive formats. These include bzip2, gzip, pack200,
LZMA, XZ, Snappy, traditional Unix Compress, DEFLATE, DEFLATE64, LZ4,
Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj.
/*
* 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.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Utility methods for reading and writing bytes.
*
* @since 1.14
*/
public final class ByteUtils {
/**
* Used to consume bytes.
*
* @since 1.14
*/
public interface ByteConsumer {
/**
* The contract is similar to {@link OutputStream#write(int)}, consume the lower eight bytes of the int as a byte.
*
* @param b the byte to consume
* @throws IOException if consuming fails
*/
void accept(int b) throws IOException;
}
/**
* Used to supply bytes.
*
* @since 1.14
*/
public interface ByteSupplier {
/**
* The contract is similar to {@link InputStream#read()}, return the byte as an unsigned int, -1 if there are no more bytes.
*
* @return the supplied byte or -1 if there are no more bytes
* @throws IOException if supplying fails
*/
int getAsByte() throws IOException;
}
/**
* {@link ByteSupplier} based on {@link InputStream}.
*
* @since 1.14
* @deprecated Unused
*/
@Deprecated
public static class InputStreamByteSupplier implements ByteSupplier {
private final InputStream is;
public InputStreamByteSupplier(final InputStream is) {
this.is = is;
}
@Override
public int getAsByte() throws IOException {
return is.read();
}
}
/**
* {@link ByteConsumer} based on {@link OutputStream}.
*
* @since 1.14
*/
public static class OutputStreamByteConsumer implements ByteConsumer {
private final OutputStream os;
public OutputStreamByteConsumer(final OutputStream os) {
this.os = os;
}
@Override
public void accept(final int b) throws IOException {
os.write(b);
}
}
/**
* Empty array.
*
* @since 1.21
*/
public static final byte[] EMPTY_BYTE_ARRAY = {};
private static void checkReadLength(final int length) {
if (length > 8) {
throw new IllegalArgumentException("Can't read more than eight bytes into a long value");
}
}
/**
* Reads the given byte array as a little-endian long.
*
* @param bytes the byte array to convert
* @return the number read
*/
public static long fromLittleEndian(final byte[] bytes) {
return fromLittleEndian(bytes, 0, bytes.length);
}
/**
* Reads the given byte array as a little-endian long.
*
* @param bytes the byte array to convert
* @param off the offset into the array that starts the value
* @param length the number of bytes representing the value
* @return the number read
* @throws IllegalArgumentException if len is bigger than eight
*/
public static long fromLittleEndian(final byte[] bytes, final int off, final int length) {
checkReadLength(length);
long l = 0;
for (int i = 0; i < length; i++) {
l |= (bytes[off + i] & 0xffL) << 8 * i;
}
return l;
}
/**
* Reads the given number of bytes from the given supplier as a little-endian long.
*
*
* Typically used by our InputStreams that need to count the bytes read as well.
*
*
* @param supplier the supplier for bytes
* @param length the number of bytes representing the value
* @return the number read
* @throws IllegalArgumentException if len is bigger than eight
* @throws IOException if the supplier fails or doesn't supply the given number of bytes anymore
*/
public static long fromLittleEndian(final ByteSupplier supplier, final int length) throws IOException {
checkReadLength(length);
long l = 0;
for (int i = 0; i < length; i++) {
final long b = supplier.getAsByte();
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 input as little-endian long.
*
* @param in the input to read from
* @param length the number of bytes representing the value
* @return the number read
* @throws IllegalArgumentException if len is bigger than eight
* @throws IOException if reading fails or the stream doesn't contain the given number of bytes anymore
*/
public static long fromLittleEndian(final DataInput in, final int length) throws IOException {
// somewhat duplicates the ByteSupplier version in order to save the creation of a wrapper object
checkReadLength(length);
long l = 0;
for (int i = 0; i < length; i++) {
final long b = in.readUnsignedByte();
l |= b << i * 8;
}
return l;
}
/**
* Reads the given number of bytes from the given stream as a little-endian long.
*
* @param in the stream to read from
* @param length the number of bytes representing the value
* @return the number read
* @throws IllegalArgumentException if len is bigger than eight
* @throws IOException if reading fails or the stream doesn't contain the given number of bytes anymore
* @deprecated Unused
*/
@Deprecated
public static long fromLittleEndian(final InputStream in, final int length) throws IOException {
// somewhat duplicates the ByteSupplier version in order to save the creation of a wrapper object
checkReadLength(length);
long l = 0;
for (int i = 0; i < length; i++) {
final long b = in.read();
if (b == -1) {
throw new IOException("Premature end of data");
}
l |= b << i * 8;
}
return l;
}
/**
* Inserts the given value into the array as a little-endian sequence of the given length starting at the given offset.
*
* @param b the array to write into
* @param value the value to insert
* @param off the offset into the array that receives the first byte
* @param length the number of bytes to use to represent the value
*/
public static void toLittleEndian(final byte[] b, final long value, final int off, final int length) {
long num = value;
for (int i = 0; i < length; i++) {
b[off + i] = (byte) (num & 0xff);
num >>= 8;
}
}
/**
* Provides the given value to the given consumer as a little-endian sequence of the given length.
*
* @param consumer the consumer to provide the bytes to
* @param value the value to provide
* @param length the number of bytes to use to represent the value
* @throws IOException if writing fails
*/
public static void toLittleEndian(final ByteConsumer consumer, final long value, final int length) throws IOException {
long num = value;
for (int i = 0; i < length; i++) {
consumer.accept((int) (num & 0xff));
num >>= 8;
}
}
/**
* Writes the given value to the given stream as a little-endian array of the given length.
*
* @param out the output to write to
* @param value the value to write
* @param length the number of bytes to use to represent the value
* @throws IOException if writing fails
* @deprecated Unused
*/
@Deprecated
public static void toLittleEndian(final DataOutput out, final long value, final int length) throws IOException {
// somewhat duplicates the ByteConsumer version in order to save the creation of a wrapper object
long num = value;
for (int i = 0; i < length; i++) {
out.write((int) (num & 0xff));
num >>= 8;
}
}
/**
* Writes the given value to the given stream as a little-endian array of the given length.
*
* @param out the stream to write to
* @param value the value to write
* @param length the number of bytes to use to represent the value
* @throws IOException if writing fails
*/
public static void toLittleEndian(final OutputStream out, final long value, final int length) throws IOException {
// somewhat duplicates the ByteConsumer version in order to save the creation of a wrapper object
long num = value;
for (int i = 0; i < length; i++) {
out.write((int) (num & 0xff));
num >>= 8;
}
}
private ByteUtils() {
/* no instances */ }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy