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