]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/util/ByteArrayWrapper.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / util / ByteArrayWrapper.java
1 //##header J2SE15
2 /**
3  *******************************************************************************
4  * Copyright (C) 1996-2009, International Business Machines Corporation and    *
5  * others. All Rights Reserved.                                                *
6  *******************************************************************************
7  */
8
9 package com.ibm.icu.util;
10
11 //#if defined(FOUNDATION10) || defined(J2SE13)
12 //##import com.ibm.icu.impl.ByteBuffer;
13 //#else
14 import java.nio.ByteBuffer;
15 //#endif
16 import com.ibm.icu.impl.Utility;
17
18 /**
19  * <p>
20  * A simple utility class to wrap a byte array.
21  * </p>
22  * <p>
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.
26  * </p> 
27  * @author syn wee
28  * @stable ICU 2.8
29  */
30 public class ByteArrayWrapper implements Comparable
31 {
32     // public data member ------------------------------------------------
33     
34     /**
35      * Internal byte array.
36      * @stable ICU 2.8
37      */
38     public byte[] bytes;
39
40     /**
41      * Size of the internal byte array used. 
42      * Different from bytes.length, size will be &lt;= bytes.length. 
43      * Semantics of size is similar to java.util.Vector.size().
44      * @stable ICU 2.8
45      */
46     public int size;
47     
48     // public constructor ------------------------------------------------
49
50     /** 
51      * Construct a new ByteArrayWrapper with no data.
52      * @stable ICU 2.8
53      */
54     public ByteArrayWrapper() {
55         // leave bytes null, don't allocate twice
56     }
57
58     /**
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.
64      * @stable ICU 3.2
65      */
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);
69         }
70         this.bytes = bytesToAdopt;
71         this.size = size;
72     }
73
74     /**
75      * Construct a new ByteArrayWrapper from the contents of a ByteBuffer.
76      * @param source the ByteBuffer from which to get the data.
77      * @stable ICU 3.2
78      */
79     public ByteArrayWrapper(ByteBuffer source) {
80         size = source.limit();
81         bytes = new byte[size];
82         source.get(bytes,0,size);
83     }
84
85     /**
86      * Create from ByteBuffer
87      * @param byteBuffer
88     public ByteArrayWrapper(ByteArrayWrapper source) {
89         size = source.size;
90         bytes = new byte[size];
91         copyBytes(source.bytes, 0, bytes, 0, size);
92     }
93      */
94
95     /**
96      * create from byte buffer
97      * @param src
98      * @param start
99      * @param limit
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);
104     }
105      */
106
107     // public methods ----------------------------------------------------
108
109     /**
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
116      * @stable ICU 3.2
117      */
118     public ByteArrayWrapper ensureCapacity(int capacity) 
119     {
120         if (bytes == null || bytes.length < capacity) {
121             byte[] newbytes = new byte[capacity];
122             copyBytes(bytes, 0, newbytes, 0, size);
123             bytes = newbytes;
124         }
125         return this;
126     }
127     
128     /**
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
137      * @stable ICU 3.2
138      */
139     public final ByteArrayWrapper set(byte[] src, int start, int limit) 
140     {
141         size = 0;
142         append(src, start, limit);
143         return this;
144     }
145     
146     /*
147     public final ByteArrayWrapper get(byte[] target, int start, int limit) 
148     {
149         int len = limit - start;
150         if (len > size) throw new IllegalArgumentException("limit too long");
151         copyBytes(bytes, 0, target, start, len);
152         return this;
153     }
154     */
155
156     /**
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
164      * @stable ICU 3.2
165      */
166     public final ByteArrayWrapper append(byte[] src, int start, int limit) 
167     {
168         int len = limit - start;
169         ensureCapacity(size + len);
170         copyBytes(src, start, bytes, size, len);
171         size += len;
172         return this;
173     }
174
175     /*
176     public final ByteArrayWrapper append(ByteArrayWrapper other) 
177     {
178         return append(other.bytes, 0, other.size);
179     }
180     */
181
182     /**
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.
186      * @stable ICU 2.8
187      */
188     public final byte[] releaseBytes()
189     {
190         byte result[] = bytes;
191         bytes = null;
192         size = 0;
193         return result;
194     }
195     
196     // Boilerplate ----------------------------------------------------
197     
198     /**
199      * Returns string value for debugging
200      * @stable ICU 3.2
201      */
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));
207         }
208         return result.toString();
209     }
210
211     /**
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.
215      * @stable ICU 3.2
216      */
217     public boolean equals(Object other) {
218         if (this == other) return true;
219         if (other == null) return false;
220         try {
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;
225             }
226             return true;
227         }
228         catch (ClassCastException e) {
229         }
230         return false;
231     }
232
233     /**
234      * Return the hashcode.
235      * @return the hashcode.
236      * @stable ICU 3.2
237      */
238     public int hashCode() {
239         int result = bytes.length;
240         for (int i = 0; i < size; ++i) {
241             result = 37*result + bytes[i];
242         }
243         return result;
244     }
245
246     /**
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
252      * @stable ICU 3.2
253      */
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);
261             }
262         }
263         return size - that.size;
264     }
265     
266     // private methods -----------------------------------------------------
267     
268     /**
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
276      */
277     private static final void copyBytes(byte[] src, int srcoff, byte[] tgt, 
278                                        int tgtoff, int length) {
279         if (length < 64) {
280             for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {
281                 tgt[n] = src[i];
282             }
283         } 
284         else {
285             System.arraycopy(src, srcoff, tgt, tgtoff, length);
286         }
287     }      
288 }