All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.compress.utils.ByteUtils Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * 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 com.feilong.lib.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{

    private ByteUtils(){
        /* no instances */ }

    /**
     * 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;
    }

    /**
     * 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;
    }

    /**
     * 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(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(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 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
     */
    public static long fromLittleEndian(InputStream in,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++){
            long 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.
     *
     * 

* 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(ByteSupplier supplier,final int length) throws IOException{ checkReadLength(length); long l = 0; for (int i = 0; i < length; i++){ 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(DataInput in,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++){ long b = in.readUnsignedByte(); 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; } } /** * 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(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; } } /** * 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(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 */ public static void toLittleEndian(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; } } /** * {@link ByteSupplier} based on {@link InputStream}. * * @since 1.14 */ public static class InputStreamByteSupplier implements ByteSupplier{ private final InputStream is; public InputStreamByteSupplier(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(OutputStream os){ this.os = os; } @Override public void accept(int b) throws IOException{ 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"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy