]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/util/ByteArrayWrapper.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / util / ByteArrayWrapper.java
1 //##header\r
2 /**\r
3  *******************************************************************************\r
4  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
5  * others. All Rights Reserved.                                                *\r
6  *******************************************************************************\r
7  */\r
8 \r
9 package com.ibm.icu.util;\r
10 \r
11 //#if defined(FOUNDATION10) || defined(J2SE13)\r
12 //##import com.ibm.icu.impl.ByteBuffer;\r
13 //#else\r
14 import java.nio.ByteBuffer;\r
15 //#endif\r
16 import com.ibm.icu.impl.Utility;\r
17 \r
18 /**\r
19  * <p>\r
20  * A simple utility class to wrap a byte array.\r
21  * </p>\r
22  * <p>\r
23  * Generally passed as an argument object into a method. The method takes\r
24  * responsibility of writing into the internal byte array and increasing its\r
25  * size when necessary.\r
26  * </p> \r
27  * @author syn wee\r
28  * @stable ICU 2.8\r
29  */\r
30 public class ByteArrayWrapper implements Comparable\r
31 {\r
32     // public data member ------------------------------------------------\r
33     \r
34     /**\r
35      * Internal byte array.\r
36      * @stable ICU 2.8\r
37      */\r
38     public byte[] bytes;\r
39 \r
40     /**\r
41      * Size of the internal byte array used. \r
42      * Different from bytes.length, size will be &lt;= bytes.length. \r
43      * Semantics of size is similar to java.util.Vector.size().\r
44      * @stable ICU 2.8\r
45      */\r
46     public int size;\r
47     \r
48     // public constructor ------------------------------------------------\r
49 \r
50     /** \r
51      * Construct a new ByteArrayWrapper with no data.\r
52      * @stable ICU 2.8\r
53      */\r
54     public ByteArrayWrapper() {\r
55         // leave bytes null, don't allocate twice\r
56     }\r
57 \r
58     /**\r
59      * Construct a new ByteArrayWrapper from a byte array and size\r
60      * @param bytesToAdopt the byte array to adopt\r
61      * @param size the length of valid data in the byte array\r
62      * @throws IndexOutOfBoundsException if bytesToAdopt == null and size != 0, or\r
63      * size < 0, or size > bytesToAdopt.length.\r
64      * @stable ICU 3.2\r
65      */\r
66     public ByteArrayWrapper(byte[] bytesToAdopt, int size) {\r
67         if ((bytesToAdopt == null && size != 0) || size < 0 || size > bytesToAdopt.length) {\r
68             throw new IndexOutOfBoundsException("illegal size: " + size);\r
69         }\r
70         this.bytes = bytesToAdopt;\r
71         this.size = size;\r
72     }\r
73 \r
74     /**\r
75      * Construct a new ByteArrayWrapper from the contents of a ByteBuffer.\r
76      * @param source the ByteBuffer from which to get the data.\r
77      * @stable ICU 3.2\r
78      */\r
79     public ByteArrayWrapper(ByteBuffer source) {\r
80         size = source.limit();\r
81         bytes = new byte[size];\r
82         source.get(bytes,0,size);\r
83     }\r
84 \r
85     /**\r
86      * Create from ByteBuffer\r
87      * @param byteBuffer\r
88     public ByteArrayWrapper(ByteArrayWrapper source) {\r
89         size = source.size;\r
90         bytes = new byte[size];\r
91         copyBytes(source.bytes, 0, bytes, 0, size);\r
92     }\r
93      */\r
94 \r
95     /**\r
96      * create from byte buffer\r
97      * @param src\r
98      * @param start\r
99      * @param limit\r
100     public ByteArrayWrapper(byte[] src, int start, int limit) {\r
101         size = limit - start;\r
102         bytes = new byte[size];\r
103         copyBytes(src, start, bytes, 0, size);\r
104     }\r
105      */\r
106 \r
107     // public methods ----------------------------------------------------\r
108 \r
109     /**\r
110      * Ensure that the internal byte array is at least of length capacity.     \r
111      * If the byte array is null or its length is less than capacity, a new \r
112      * byte array of length capacity will be allocated.  \r
113      * The contents of the array (between 0 and size) remain unchanged. \r
114      * @param capacity minimum length of internal byte array.\r
115      * @return this ByteArrayWrapper\r
116      * @stable ICU 3.2\r
117      */\r
118     public ByteArrayWrapper ensureCapacity(int capacity) \r
119     {\r
120         if (bytes == null || bytes.length < capacity) {\r
121             byte[] newbytes = new byte[capacity];\r
122             copyBytes(bytes, 0, newbytes, 0, size);\r
123             bytes = newbytes;\r
124         }\r
125         return this;\r
126     }\r
127     \r
128     /**\r
129      * Set the internal byte array from offset 0 to (limit - start) with the \r
130      * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new \r
131      * byte array of length (limit - start) will be allocated.  \r
132      * This resets the size of the internal byte array to (limit - start).\r
133      * @param src source byte array to copy from\r
134      * @param start start offset of src to copy from\r
135      * @param limit end + 1 offset of src to copy from\r
136      * @return this ByteArrayWrapper\r
137      * @stable ICU 3.2\r
138      */\r
139     public final ByteArrayWrapper set(byte[] src, int start, int limit) \r
140     {\r
141         size = 0;\r
142         append(src, start, limit);\r
143         return this;\r
144     }\r
145     \r
146     /*\r
147     public final ByteArrayWrapper get(byte[] target, int start, int limit) \r
148     {\r
149         int len = limit - start;\r
150         if (len > size) throw new IllegalArgumentException("limit too long");\r
151         copyBytes(bytes, 0, target, start, len);\r
152         return this;\r
153     }\r
154     */\r
155 \r
156     /**\r
157      * Appends the internal byte array from offset size with the \r
158      * contents of src from offset start to limit. This increases the size of\r
159      * the internal byte array to (size + limit - start).\r
160      * @param src source byte array to copy from\r
161      * @param start start offset of src to copy from\r
162      * @param limit end + 1 offset of src to copy from\r
163      * @return this ByteArrayWrapper\r
164      * @stable ICU 3.2\r
165      */\r
166     public final ByteArrayWrapper append(byte[] src, int start, int limit) \r
167     {\r
168         int len = limit - start;\r
169         ensureCapacity(size + len);\r
170         copyBytes(src, start, bytes, size, len);\r
171         size += len;\r
172         return this;\r
173     }\r
174 \r
175     /*\r
176     public final ByteArrayWrapper append(ByteArrayWrapper other) \r
177     {\r
178         return append(other.bytes, 0, other.size);\r
179     }\r
180     */\r
181 \r
182     /**\r
183      * Releases the internal byte array to the caller, resets the internal\r
184      * byte array to null and its size to 0.\r
185      * @return internal byte array.\r
186      * @stable ICU 2.8\r
187      */\r
188     public final byte[] releaseBytes()\r
189     {\r
190         byte result[] = bytes;\r
191         bytes = null;\r
192         size = 0;\r
193         return result;\r
194     }\r
195     \r
196     // Boilerplate ----------------------------------------------------\r
197     \r
198     /**\r
199      * Returns string value for debugging\r
200      * @stable ICU 3.2\r
201      */\r
202     public String toString() {\r
203         StringBuffer result = new StringBuffer();\r
204         for (int i = 0; i < size; ++i) {\r
205             if (i != 0) result.append(" ");\r
206             result.append(Utility.hex(bytes[i]&0xFF,2));\r
207         }\r
208         return result.toString();\r
209     }\r
210 \r
211     /**\r
212      * Return true if the bytes in each wrapper are equal.\r
213      * @param other the object to compare to.\r
214      * @return true if the two objects are equal.\r
215      * @stable ICU 3.2\r
216      */\r
217     public boolean equals(Object other) {\r
218         if (this == other) return true;\r
219         if (other == null) return false;\r
220         try {\r
221             ByteArrayWrapper that = (ByteArrayWrapper)other;\r
222             if (size != that.size) return false;\r
223             for (int i = 0; i < size; ++i) {\r
224                 if (bytes[i] != that.bytes[i]) return false;\r
225             }\r
226             return true;\r
227         }\r
228         catch (ClassCastException e) {\r
229         }\r
230         return false;\r
231     }\r
232 \r
233     /**\r
234      * Return the hashcode.\r
235      * @return the hashcode.\r
236      * @stable ICU 3.2\r
237      */\r
238     public int hashCode() {\r
239         int result = bytes.length;\r
240         for (int i = 0; i < size; ++i) {\r
241             result = 37*result + bytes[i];\r
242         }\r
243         return result;\r
244     }\r
245 \r
246     /**\r
247      * Compare this object to another ByteArrayWrapper, which must not be null.\r
248      * @param other the object to compare to.\r
249      * @return a value <0, 0, or >0 as this compares less than, equal to, or\r
250      * greater than other.\r
251      * @throws ClassCastException if the other object is not a ByteArrayWrapper\r
252      * @stable ICU 3.2\r
253      */\r
254     public int compareTo(Object other) {\r
255         if (this == other) return 0;\r
256         ByteArrayWrapper that = (ByteArrayWrapper) other;\r
257         int minSize = size < that.size ? size : that.size;\r
258         for (int i = 0; i < minSize; ++i) {\r
259             if (bytes[i] != that.bytes[i]) {\r
260                 return (bytes[i] & 0xFF) - (that.bytes[i] & 0xFF);\r
261             }\r
262         }\r
263         return size - that.size;\r
264     }\r
265     \r
266     // private methods -----------------------------------------------------\r
267     \r
268     /**\r
269      * Copies the contents of src byte array from offset srcoff to the \r
270      * target of tgt byte array at the offset tgtoff.\r
271      * @param src source byte array to copy from\r
272      * @param srcoff start offset of src to copy from\r
273      * @param tgt target byte array to copy to\r
274      * @param tgtoff start offset of tgt to copy to\r
275      * @param length size of contents to copy\r
276      */\r
277     private static final void copyBytes(byte[] src, int srcoff, byte[] tgt, \r
278                                        int tgtoff, int length) {\r
279         if (length < 64) {\r
280             for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {\r
281                 tgt[n] = src[i];\r
282             }\r
283         } \r
284         else {\r
285             System.arraycopy(src, srcoff, tgt, tgtoff, length);\r
286         }\r
287     }      \r
288 }\r