com.ibm.icu.util.ByteArrayWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
/**
*******************************************************************************
* Copyright (C) 1996-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.util;
import java.nio.ByteBuffer;
import com.ibm.icu.impl.Utility;
/**
*
* A simple utility class to wrap a byte array.
*
*
* Generally passed as an argument object into a method. The method takes
* responsibility of writing into the internal byte array and increasing its
* size when necessary.
*
* @author syn wee
* @stable ICU 2.8
*/
public class ByteArrayWrapper implements Comparable
{
// public data member ------------------------------------------------
/**
* Internal byte array.
* @stable ICU 2.8
*/
public byte[] bytes;
/**
* Size of the internal byte array used.
* Different from bytes.length, size will be <= bytes.length.
* Semantics of size is similar to java.util.Vector.size().
* @stable ICU 2.8
*/
public int size;
// public constructor ------------------------------------------------
/**
* Construct a new ByteArrayWrapper with no data.
* @stable ICU 2.8
*/
public ByteArrayWrapper() {
// leave bytes null, don't allocate twice
}
/**
* Construct a new ByteArrayWrapper from a byte array and size
* @param bytesToAdopt the byte array to adopt
* @param size the length of valid data in the byte array
* @throws IndexOutOfBoundsException if bytesToAdopt == null and size != 0, or
* size < 0, or size > bytesToAdopt.length.
* @stable ICU 3.2
*/
public ByteArrayWrapper(byte[] bytesToAdopt, int size) {
if ((bytesToAdopt == null && size != 0) || size < 0 || size > bytesToAdopt.length) {
throw new IndexOutOfBoundsException("illegal size: " + size);
}
this.bytes = bytesToAdopt;
this.size = size;
}
/**
* Construct a new ByteArrayWrapper from the contents of a ByteBuffer.
* @param source the ByteBuffer from which to get the data.
* @stable ICU 3.2
*/
public ByteArrayWrapper(ByteBuffer source) {
size = source.limit();
bytes = new byte[size];
source.get(bytes,0,size);
}
/**
* Create from ByteBuffer
* @param byteBuffer
public ByteArrayWrapper(ByteArrayWrapper source) {
size = source.size;
bytes = new byte[size];
copyBytes(source.bytes, 0, bytes, 0, size);
}
*/
/**
* create from byte buffer
* @param src
* @param start
* @param limit
public ByteArrayWrapper(byte[] src, int start, int limit) {
size = limit - start;
bytes = new byte[size];
copyBytes(src, start, bytes, 0, size);
}
*/
// public methods ----------------------------------------------------
/**
* Ensure that the internal byte array is at least of length capacity.
* If the byte array is null or its length is less than capacity, a new
* byte array of length capacity will be allocated.
* The contents of the array (between 0 and size) remain unchanged.
* @param capacity minimum length of internal byte array.
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
public ByteArrayWrapper ensureCapacity(int capacity)
{
if (bytes == null || bytes.length < capacity) {
byte[] newbytes = new byte[capacity];
copyBytes(bytes, 0, newbytes, 0, size);
bytes = newbytes;
}
return this;
}
/**
* Set the internal byte array from offset 0 to (limit - start) with the
* contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new
* byte array of length (limit - start) will be allocated.
* This resets the size of the internal byte array to (limit - start).
* @param src source byte array to copy from
* @param start start offset of src to copy from
* @param limit end + 1 offset of src to copy from
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
public final ByteArrayWrapper set(byte[] src, int start, int limit)
{
size = 0;
append(src, start, limit);
return this;
}
/*
public final ByteArrayWrapper get(byte[] target, int start, int limit)
{
int len = limit - start;
if (len > size) throw new IllegalArgumentException("limit too long");
copyBytes(bytes, 0, target, start, len);
return this;
}
*/
/**
* Appends the internal byte array from offset size with the
* contents of src from offset start to limit. This increases the size of
* the internal byte array to (size + limit - start).
* @param src source byte array to copy from
* @param start start offset of src to copy from
* @param limit end + 1 offset of src to copy from
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
public final ByteArrayWrapper append(byte[] src, int start, int limit)
{
int len = limit - start;
ensureCapacity(size + len);
copyBytes(src, start, bytes, size, len);
size += len;
return this;
}
/*
public final ByteArrayWrapper append(ByteArrayWrapper other)
{
return append(other.bytes, 0, other.size);
}
*/
/**
* Releases the internal byte array to the caller, resets the internal
* byte array to null and its size to 0.
* @return internal byte array.
* @stable ICU 2.8
*/
public final byte[] releaseBytes()
{
byte result[] = bytes;
bytes = null;
size = 0;
return result;
}
// Boilerplate ----------------------------------------------------
/**
* Returns string value for debugging
* @stable ICU 3.2
*/
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < size; ++i) {
if (i != 0) result.append(" ");
result.append(Utility.hex(bytes[i]&0xFF,2));
}
return result.toString();
}
/**
* Return true if the bytes in each wrapper are equal.
* @param other the object to compare to.
* @return true if the two objects are equal.
* @stable ICU 3.2
*/
public boolean equals(Object other) {
if (this == other) return true;
if (other == null) return false;
try {
ByteArrayWrapper that = (ByteArrayWrapper)other;
if (size != that.size) return false;
for (int i = 0; i < size; ++i) {
if (bytes[i] != that.bytes[i]) return false;
}
return true;
}
catch (ClassCastException e) {
}
return false;
}
/**
* Return the hashcode.
* @return the hashcode.
* @stable ICU 3.2
*/
public int hashCode() {
int result = bytes.length;
for (int i = 0; i < size; ++i) {
result = 37*result + bytes[i];
}
return result;
}
/**
* Compare this object to another ByteArrayWrapper, which must not be null.
* @param other the object to compare to.
* @return a value <0, 0, or >0 as this compares less than, equal to, or
* greater than other.
* @throws ClassCastException if the other object is not a ByteArrayWrapper
* @stable ICU 4.4
*/
public int compareTo(ByteArrayWrapper other) {
if (this == other) return 0;
int minSize = size < other.size ? size : other.size;
for (int i = 0; i < minSize; ++i) {
if (bytes[i] != other.bytes[i]) {
return (bytes[i] & 0xFF) - (other.bytes[i] & 0xFF);
}
}
return size - other.size;
}
// private methods -----------------------------------------------------
/**
* Copies the contents of src byte array from offset srcoff to the
* target of tgt byte array at the offset tgtoff.
* @param src source byte array to copy from
* @param srcoff start offset of src to copy from
* @param tgt target byte array to copy to
* @param tgtoff start offset of tgt to copy to
* @param length size of contents to copy
*/
private static final void copyBytes(byte[] src, int srcoff, byte[] tgt,
int tgtoff, int length) {
if (length < 64) {
for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {
tgt[n] = src[i];
}
}
else {
System.arraycopy(src, srcoff, tgt, tgtoff, length);
}
}
}