/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.util.io; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import javax.annotation.concurrent.ThreadSafe; /** * A collection of utility functions to read/write primitive values from/to a byte array. */ @ThreadSafe public final class ByteIOUtils { private ByteIOUtils() {} // prevent instantiation. /** * Reads a specific byte value from the input byte array at the given offset. * * @param buf input byte array * @param pos offset into the byte buffer to read * @return the byte value read */ public static byte readByte(byte[] buf, int pos) { checkBoundary(buf, pos, 1); return (byte) (buf[pos] & 0xff); } /** * Reads a specific byte value from the input byte buffer at the given offset. * * @param buf input byte buffer * @param pos offset into the byte buffer to read * @return the byte value read */ public static byte readByte(ByteBuffer buf, int pos) { return (byte) (buf.get(pos) & 0xff); } /** * Reads a specific short byte value (2 bytes) from the input byte array at the given offset. * * @param buf input byte buffer * @param pos offset into the byte buffer to read * @return the short value read */ public static short readShort(byte[] buf, int pos) { checkBoundary(buf, pos, 2); return (short) (((short) (buf[pos] & 0xff) << 8) | ((short) (buf[pos + 1] & 0xff))); } /** * Reads a specific integer byte value (4 bytes) from the input byte array at the given offset. * * @param buf input byte array * @param pos offset into the byte buffer to read * @return the int value read */ public static int readInt(byte[] buf, int pos) { checkBoundary(buf, pos, 4); return (((buf[pos++] & 0xff) << 24) | ((buf[pos++] & 0xff) << 16) | ((buf[pos++] & 0xff) << 8) | (buf[pos] & 0xff)); } /** * Reads a specific integer byte value (4 bytes) from the input byte buffer at the given offset. * * @param buf input byte buffer * @param pos offset into the byte buffer to read * @return the int value read */ public static int readInt(ByteBuffer buf, int pos) { return (((buf.get(pos) & 0xff) << 24) | ((buf.get(pos + 1) & 0xff) << 16) | ((buf.get(pos + 2) & 0xff) << 8) | (buf.get(pos + 3) & 0xff)); } /** * Reads a specific long byte value (8 bytes) from the input byte array at the given offset. * * @param buf input byte buffer * @param pos offset into the byte buffer to read * @return the long value read */ public static long readLong(byte[] buf, int pos) { checkBoundary(buf, pos, 8); return (((long) (buf[pos++] & 0xff) << 56) | ((long) (buf[pos++] & 0xff) << 48) | ((long) (buf[pos++] & 0xff) << 40) | ((long) (buf[pos++] & 0xff) << 32) | ((long) (buf[pos++] & 0xff) << 24) | ((long) (buf[pos++] & 0xff) << 16) | ((long) (buf[pos++] & 0xff) << 8) | ((long) (buf[pos] & 0xff))); } /** * Writes a single byte value (1 byte) to the output byte array at the given offset. * * @param buf output byte buffer * @param pos offset into the byte buffer to write * @param v byte value to write */ public static void writeByte(byte[] buf, int pos, byte v) { checkBoundary(buf, pos, 1); buf[pos] = v; } /** * Writes a single byte value (1 byte) to the output byte buffer at the given offset. * * @param buf output byte buffer * @param pos offset into the byte buffer to write * @param v byte value to write */ public static void writeByte(ByteBuffer buf, int pos, byte v) { buf.put(pos, v); } /** * Writes a single byte value (1 byte) to the output stream. This is equivalent of * {@link OutputStream#write(int)}. * * @param out output stream * @param v byte value to write */ public static void writeByte(OutputStream out, byte v) throws IOException { out.write(v); } /** * Writes a specific short value (2 bytes) to the output byte buffer at the given offset. * * @param buf output byte buffer * @param pos offset into the byte buffer to write * @param v short value to write */ public static void writeShort(byte[] buf, int pos, short v) { checkBoundary(buf, pos, 2); buf[pos++] = (byte) (0xff & (v >> 8)); buf[pos] = (byte) (0xff & v); } /** * Writes a specific short value (2 bytes) to the output stream. * * @param out output stream * @param v short value to write */ public static void writeShort(OutputStream out, short v) throws IOException { out.write((byte) (0xff & (v >> 8))); out.write((byte) (0xff & v)); } /** * Writes a specific integer value (4 bytes) to the output byte array at the given offset. * * @param buf output byte array * @param pos offset into the byte buffer to write * @param v int value to write */ public static void writeInt(byte[] buf, int pos, int v) { checkBoundary(buf, pos, 4); buf[pos++] = (byte) (0xff & (v >> 24)); buf[pos++] = (byte) (0xff & (v >> 16)); buf[pos++] = (byte) (0xff & (v >> 8)); buf[pos] = (byte) (0xff & v); } /** * Writes a specific integer value (4 bytes) to the output byte buffer at the given offset. * * @param buf output byte buffer * @param pos offset into the byte buffer to write * @param v int value to write */ public static void writeInt(ByteBuffer buf, int pos, int v) { buf.put(pos++, (byte) (0xff & (v >> 24))); buf.put(pos++, (byte) (0xff & (v >> 16))); buf.put(pos++, (byte) (0xff & (v >> 8))); buf.put(pos, (byte) (0xff & v)); } /** * Writes a specific integer value (4 bytes) to the output stream. * * @param out output stream * @param v integer value to write */ public static void writeInt(OutputStream out, int v) throws IOException { out.write((byte) (0xff & (v >> 24))); out.write((byte) (0xff & (v >> 16))); out.write((byte) (0xff & (v >> 8))); out.write((byte) (0xff & v)); } /** * Writes a specific long value (8 bytes) to the output byte array at the given offset. * * @param buf output byte array * @param pos offset into the byte buffer to write * @param v long value to write */ public static void writeLong(byte[] buf, int pos, long v) { checkBoundary(buf, pos, 8); buf[pos++] = (byte) (0xff & (v >> 56)); buf[pos++] = (byte) (0xff & (v >> 48)); buf[pos++] = (byte) (0xff & (v >> 40)); buf[pos++] = (byte) (0xff & (v >> 32)); buf[pos++] = (byte) (0xff & (v >> 24)); buf[pos++] = (byte) (0xff & (v >> 16)); buf[pos++] = (byte) (0xff & (v >> 8)); buf[pos] = (byte) (0xff & v); } /** * Writes a specific long value (8 bytes) to the output stream. * * @param out output stream * @param v long value to write */ public static void writeLong(OutputStream out, long v) throws IOException { out.write((byte) (0xff & (v >> 56))); out.write((byte) (0xff & (v >> 48))); out.write((byte) (0xff & (v >> 40))); out.write((byte) (0xff & (v >> 32))); out.write((byte) (0xff & (v >> 24))); out.write((byte) (0xff & (v >> 16))); out.write((byte) (0xff & (v >> 8))); out.write((byte) (0xff & v)); } /** * Ensures that the given buffer contains at least the given number of bytes after the given * offset. * * @param buf input byte array * @param pos position in the byte array to start writing * @param len length of data to write from the given position */ private static void checkBoundary(byte[] buf, int pos, int len) { if (pos + len > buf.length) { throw new ArrayIndexOutOfBoundsException(); } } }