/* * Copyright 2011 Outerthought bvba * * Licensed 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.lilyproject.bytes.api; import java.util.Arrays; /** * A utility class providing read only access to a byte[]. * <p> * Upon construction, the byte[] to be wrapped needs to be given.</br> * * This byte[] is copied by the constructor {@link ByteArray#ByteArray(byte[])} * to avoid external changes to the byte[] from having an impact. * <p> * If the user is absolutely certain a byte[] will not be modified later on, the * factory method {@link ByteArray#wrap(byte[])} can be used which will not copy * the byte[] but just wrap it. */ public class ByteArray { private byte[] bytes; /** * Provides an uninitialized ByteArray. * <p> * For internal use only. */ private ByteArray() { } /** * Creates a ByteArray wrapper around a byte[] which is first copied. */ public ByteArray(byte[] bytes) { this.bytes = Arrays.copyOf(bytes, bytes.length); } /** * Wraps a byte[] instead of copying it like the constructor does. * <p> * Warning! This method should only be used when the user is absolutely * certain that the provided byte[] will not be modified anymore. * * @param bytes * the byte[] to wrap * @return a ByteArray */ public static ByteArray wrap(byte[] bytes) { ByteArray byteArray = new ByteArray(); byteArray.bytes = bytes; return byteArray; } /** * Returns a copy of the wrapped byte[]. */ public byte[] getBytes() { return Arrays.copyOf(this.bytes, this.bytes.length); } /** * Returns the wrapped byte[] without copying it first. * <p> * Warning! This method should only be used when the user is absolutely * certain that the returned byte[] will nog be modified anymore. */ public byte[] getBytesUnsafe() { return bytes; } /** * Returns the byte at index of the wrapped byte[]. * * @param index * of the byte to return * @return a byte * @throws ArrayIndexOutOfBoundsException * when the given index is outside the range of the wrapped * byte[] */ public byte get(int index) { return this.bytes[index]; } /** * Returns the length of the wrapped byte[] */ public int length() { return this.bytes.length; } /** * Returns a copy of the specified range of the wrapped byte[] * * @param from * the initial index of the range to be copied, inclusive * @param to * the final index of the range to be copied, exclusive. (This * index may lie outside the array in which case it is limited to * the last index of the original byte[].) **/ public byte[] getRange(int from, int to) { return Arrays.copyOfRange(this.bytes, from, to); } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(bytes); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ByteArray other = (ByteArray) obj; if (!Arrays.equals(bytes, other.bytes)) { return false; } return true; } @Override public String toString() { return "[ByteArray, length=" + bytes.length + "]"; } }