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

de.schlichtherle.truezip.zip.LittleEndian Maven / Gradle / Ivy

/*
 * Copyright (C) 2005-2015 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package de.schlichtherle.truezip.zip;

import javax.annotation.concurrent.ThreadSafe;

/**
 * Provides static utility methods for reading and writing integer values in
 * little endian format from or to byte arrays.
 * 
 * @author  Christian Schlichtherle
 */
@ThreadSafe
final class LittleEndian {

    /** This class cannot get instantiated. */
    private LittleEndian() {
    }

    /**
     * Reads a signed byte integer value from the byte array
     * {@code buf} at the offset {@code off}.
     *
     * @param  buf The byte array to read the signed byte integer value from.
     * @param  off The zero based offset in the byte array where the signed
     *         byte integer value is read from.
     * @return The signed byte integer value read from the byte array.
     */
    static byte readByte(final byte[] buf, final int off) {
        return buf[off];
    }

    /**
     * Reads an unsigned byte integer value from the byte array
     * {@code buf} at the offset {@code off}.
     * Note that it is not necessary to check the return value with
     * {@link UByte#check}.
     *
     * @param  buf The byte array to read the unsigned byte integer value from.
     * @param  off The zero based offset in the byte array where the unsigned
     *         byte integer value is read from.
     * @return The unsigned byte integer value read from the byte array.
     *         Java does not provide {@code unsigned short} as a primitive
     *         type, hence an {@code int} is returned which's three most
     *         significant bytes are zero.
     */
    static int readUByte(final byte[] buf, final int off) {
        return buf[off] & UByte.MAX_VALUE;
    }

    /**
     * Reads a signed short integer value from the byte array
     * {@code buf} at the offset {@code off}
     * as two bytes, low byte first.
     *
     * @param  buf The byte array to read the signed short integer value from.
     * @param  off The zero based offset in the byte array where the first byte
     *         of the signed short integer value is read from.
     * @return The signed short integer value read from the byte array.
     */
    static int readShort(final byte[] buf, final int off) {
        return (buf[off + 1] << 8) | (buf[off] & UByte.MAX_VALUE);
    }

    /**
     * Reads an unsigned short integer value from the byte array
     * {@code buf} at the offset {@code off}
     * as two bytes, low byte first.
     * Note that it is not necessary to check the return value with
     * {@link UShort#check}.
     *
     * @param  buf The byte array to read the unsigned short integer value from.
     * @param  off The zero based offset in the byte array where the first byte
     *         of the unsigned short integer value is read from.
     * @return The unsigned short integer value read from the byte array.
     *         Java does not provide {@code unsigned short} as a primitive
     *         type, hence an {@code int} is returned which's two most
     *         significant bytes are zero.
     */
    static int readUShort(final byte[] buf, final int off) {
        return ((buf[off + 1] & UByte.MAX_VALUE) << 8) | (buf[off] & UByte.MAX_VALUE);
    }

    /**
     * Reads a signed integer value from the byte array
     * {@code buf} at the offset {@code off}
     * as four bytes, low byte first.
     *
     * @param  buf The byte array to read the signed integer value from.
     * @param  off The zero based offset in the byte array where the first byte
     *         of the signed integer value is read from.
     * @return The signed integer value read from the byte array.
     */
    static int readInt(final byte[] buf, int off) {
        off += 3;
        int i = buf[off--]; // expands sign
        i <<= 8;
        i |= buf[off--] & UByte.MAX_VALUE;
        i <<= 8;
        i |= buf[off--] & UByte.MAX_VALUE;
        i <<= 8;
        i |= buf[off] & UByte.MAX_VALUE;
        return i;
    }

    /**
     * Reads an unsigned integer value from the byte array
     * {@code buf} at the offset {@code off}
     * as four bytes, low byte first.
     * Note that it is not necessary to check the return value with
     * {@link UInt#check}.
     *
     * @param  buf The byte array to read the unsigned integer value from.
     * @param  off The zero based offset in the byte array where the first byte
     *         of the unsigned integer value is read from.
     * @return The unsigned integer value read from the byte array.
     *         Java does not provide {@code unsigned int} as a primitive
     *         type, hence a {@code long} is returned which's four most
     *         significant bytes are zero.
     */
    static long readUInt(final byte[] buf, int off) {
        return readInt(buf, off) & UInt.MAX_VALUE;
    }

    /**
     * Reads a (signed) long integer value from the byte array
     * {@code buf} at the offset {@code off}
     * as eight bytes, low byte first.
     *
     * @param  buf The byte array to read the signed long integer value from.
     * @param  off The zero based offset in the byte array where the first byte
     *         of the (signed) long integer value is read from.
     * @return The (signed) long integer value read from the byte array.
     */
    static long readLong(final byte[] buf, int off) {
        off += 7;
        long l = buf[off--]; // expands sign
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off--] & UByte.MAX_VALUE;
        l <<= 8;
        l |= buf[off] & UByte.MAX_VALUE;
        return l;
    }

    /**
     * Writes the integer value {@code b} to the byte array
     * {@code buf} at the zero based offset {@code off}
     * as one byte.
     * The most significant three bytes of the integer value are ignored.
     *
     * @param b The integer value to be written.
     * @param buf The byte array to write the integer value to.
     * @param off The zero based offset in the byte array where the byte
     *        of the integer value is written to.
     */
    static void writeByte(int b, byte[] buf, int off) {
        buf[off] = (byte) b;
    }

    /**
     * Writes the integer value {@code s} to the byte array
     * {@code buf} at the zero based offset {@code off}
     * as two bytes, low byte first.
     * The most significant two bytes of the integer value are ignored.
     *
     * @param s The integer value to be written.
     * @param buf The byte array to write the integer value to.
     * @param off The zero based offset in the byte array where the first byte
     *        of the integer value is written to.
     */
    static void writeShort(int s, final byte[] buf, final int off) {
        buf[off] = (byte) s;
        s >>= 8;
        buf[off + 1] = (byte) s;
    }

    /**
     * Writes the integer value {@code i} to the byte array
     * {@code buf} at the zero based offset {@code off}
     * as four bytes, low byte first.
     *
     * @param i The integer value to be written.
     * @param buf The byte array to write the integer value to.
     * @param off The zero based offset in the byte array where the first byte
     *        of the integer value is written to.
     */
    static void writeInt(int i, final byte[] buf, final int off) {
        buf[off] = (byte) i;
        i >>= 8;
        buf[off + 1] = (byte) i;
        i >>= 8;
        buf[off + 2] = (byte) i;
        i >>= 8;
        buf[off + 3] = (byte) i;
    }

    /**
     * Writes the long integer value {@code l} to the byte array
     * {@code buf} at the zero based offset {@code off}
     * as eight bytes, low byte first.
     *
     * @param l The long integer value to be written.
     * @param buf The byte array to write the long integer value to.
     * @param off The zero based offset in the byte array where the first byte
     *        of the long integer value is written to.
     */
    static void writeLong(long l, final byte[] buf, final int off) {
        buf[off] = (byte) l;
        l >>= 8;
        buf[off + 1] = (byte) l;
        l >>= 8;
        buf[off + 2] = (byte) l;
        l >>= 8;
        buf[off + 3] = (byte) l;
        l >>= 8;
        buf[off + 4] = (byte) l;
        l >>= 8;
        buf[off + 5] = (byte) l;
        l >>= 8;
        buf[off + 6] = (byte) l;
        l >>= 8;
        buf[off + 7] = (byte) l;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy