3 *******************************************************************************
4 * Copyright (C) 1996-2009, International Business Machines Corporation and *
5 * others. All Rights Reserved. *
6 *******************************************************************************
9 package com.ibm.icu.util;
11 //#if defined(FOUNDATION10) || defined(J2SE13)
12 //##import com.ibm.icu.impl.ByteBuffer;
14 import java.nio.ByteBuffer;
16 import com.ibm.icu.impl.Utility;
20 * A simple utility class to wrap a byte array.
23 * Generally passed as an argument object into a method. The method takes
24 * responsibility of writing into the internal byte array and increasing its
25 * size when necessary.
30 public class ByteArrayWrapper implements Comparable
32 // public data member ------------------------------------------------
35 * Internal byte array.
41 * Size of the internal byte array used.
42 * Different from bytes.length, size will be <= bytes.length.
43 * Semantics of size is similar to java.util.Vector.size().
48 // public constructor ------------------------------------------------
51 * Construct a new ByteArrayWrapper with no data.
54 public ByteArrayWrapper() {
55 // leave bytes null, don't allocate twice
59 * Construct a new ByteArrayWrapper from a byte array and size
60 * @param bytesToAdopt the byte array to adopt
61 * @param size the length of valid data in the byte array
62 * @throws IndexOutOfBoundsException if bytesToAdopt == null and size != 0, or
63 * size < 0, or size > bytesToAdopt.length.
66 public ByteArrayWrapper(byte[] bytesToAdopt, int size) {
67 if ((bytesToAdopt == null && size != 0) || size < 0 || size > bytesToAdopt.length) {
68 throw new IndexOutOfBoundsException("illegal size: " + size);
70 this.bytes = bytesToAdopt;
75 * Construct a new ByteArrayWrapper from the contents of a ByteBuffer.
76 * @param source the ByteBuffer from which to get the data.
79 public ByteArrayWrapper(ByteBuffer source) {
80 size = source.limit();
81 bytes = new byte[size];
82 source.get(bytes,0,size);
86 * Create from ByteBuffer
88 public ByteArrayWrapper(ByteArrayWrapper source) {
90 bytes = new byte[size];
91 copyBytes(source.bytes, 0, bytes, 0, size);
96 * create from byte buffer
100 public ByteArrayWrapper(byte[] src, int start, int limit) {
101 size = limit - start;
102 bytes = new byte[size];
103 copyBytes(src, start, bytes, 0, size);
107 // public methods ----------------------------------------------------
110 * Ensure that the internal byte array is at least of length capacity.
111 * If the byte array is null or its length is less than capacity, a new
112 * byte array of length capacity will be allocated.
113 * The contents of the array (between 0 and size) remain unchanged.
114 * @param capacity minimum length of internal byte array.
115 * @return this ByteArrayWrapper
118 public ByteArrayWrapper ensureCapacity(int capacity)
120 if (bytes == null || bytes.length < capacity) {
121 byte[] newbytes = new byte[capacity];
122 copyBytes(bytes, 0, newbytes, 0, size);
129 * Set the internal byte array from offset 0 to (limit - start) with the
130 * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new
131 * byte array of length (limit - start) will be allocated.
132 * This resets the size of the internal byte array to (limit - start).
133 * @param src source byte array to copy from
134 * @param start start offset of src to copy from
135 * @param limit end + 1 offset of src to copy from
136 * @return this ByteArrayWrapper
139 public final ByteArrayWrapper set(byte[] src, int start, int limit)
142 append(src, start, limit);
147 public final ByteArrayWrapper get(byte[] target, int start, int limit)
149 int len = limit - start;
150 if (len > size) throw new IllegalArgumentException("limit too long");
151 copyBytes(bytes, 0, target, start, len);
157 * Appends the internal byte array from offset size with the
158 * contents of src from offset start to limit. This increases the size of
159 * the internal byte array to (size + limit - start).
160 * @param src source byte array to copy from
161 * @param start start offset of src to copy from
162 * @param limit end + 1 offset of src to copy from
163 * @return this ByteArrayWrapper
166 public final ByteArrayWrapper append(byte[] src, int start, int limit)
168 int len = limit - start;
169 ensureCapacity(size + len);
170 copyBytes(src, start, bytes, size, len);
176 public final ByteArrayWrapper append(ByteArrayWrapper other)
178 return append(other.bytes, 0, other.size);
183 * Releases the internal byte array to the caller, resets the internal
184 * byte array to null and its size to 0.
185 * @return internal byte array.
188 public final byte[] releaseBytes()
190 byte result[] = bytes;
196 // Boilerplate ----------------------------------------------------
199 * Returns string value for debugging
202 public String toString() {
203 StringBuffer result = new StringBuffer();
204 for (int i = 0; i < size; ++i) {
205 if (i != 0) result.append(" ");
206 result.append(Utility.hex(bytes[i]&0xFF,2));
208 return result.toString();
212 * Return true if the bytes in each wrapper are equal.
213 * @param other the object to compare to.
214 * @return true if the two objects are equal.
217 public boolean equals(Object other) {
218 if (this == other) return true;
219 if (other == null) return false;
221 ByteArrayWrapper that = (ByteArrayWrapper)other;
222 if (size != that.size) return false;
223 for (int i = 0; i < size; ++i) {
224 if (bytes[i] != that.bytes[i]) return false;
228 catch (ClassCastException e) {
234 * Return the hashcode.
235 * @return the hashcode.
238 public int hashCode() {
239 int result = bytes.length;
240 for (int i = 0; i < size; ++i) {
241 result = 37*result + bytes[i];
247 * Compare this object to another ByteArrayWrapper, which must not be null.
248 * @param other the object to compare to.
249 * @return a value <0, 0, or >0 as this compares less than, equal to, or
250 * greater than other.
251 * @throws ClassCastException if the other object is not a ByteArrayWrapper
254 public int compareTo(Object other) {
255 if (this == other) return 0;
256 ByteArrayWrapper that = (ByteArrayWrapper) other;
257 int minSize = size < that.size ? size : that.size;
258 for (int i = 0; i < minSize; ++i) {
259 if (bytes[i] != that.bytes[i]) {
260 return (bytes[i] & 0xFF) - (that.bytes[i] & 0xFF);
263 return size - that.size;
266 // private methods -----------------------------------------------------
269 * Copies the contents of src byte array from offset srcoff to the
270 * target of tgt byte array at the offset tgtoff.
271 * @param src source byte array to copy from
272 * @param srcoff start offset of src to copy from
273 * @param tgt target byte array to copy to
274 * @param tgtoff start offset of tgt to copy to
275 * @param length size of contents to copy
277 private static final void copyBytes(byte[] src, int srcoff, byte[] tgt,
278 int tgtoff, int length) {
280 for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {
285 System.arraycopy(src, srcoff, tgt, tgtoff, length);