1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.util;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.ObjectInputStream;
33 import java.io.ObjectOutputStream;
34 import java.nio.ByteBuffer;
35 import java.nio.charset.StandardCharsets;
36
37 import org.junit.Assert;
38 import org.junit.Test;
39
40
41
42
43
44 public class TestByteArrayBuffer {
45
46 @Test
47 public void testConstructor() throws Exception {
48 final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
49 Assert.assertEquals(16, buffer.capacity());
50 Assert.assertEquals(0, buffer.length());
51 Assert.assertNotNull(buffer.array());
52 Assert.assertEquals(16, buffer.array().length);
53 try {
54 new ByteArrayBuffer(-1);
55 Assert.fail("IllegalArgumentException should have been thrown");
56 } catch (final IllegalArgumentException ex) {
57
58 }
59 }
60
61 @Test
62 public void testSimpleAppend() throws Exception {
63 final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
64 Assert.assertEquals(16, buffer.capacity());
65 Assert.assertEquals(0, buffer.length());
66 final byte[] b1 = buffer.toByteArray();
67 Assert.assertNotNull(b1);
68 Assert.assertEquals(0, b1.length);
69 Assert.assertTrue(buffer.isEmpty());
70 Assert.assertFalse(buffer.isFull());
71
72 final byte[] tmp = new byte[] { 1, 2, 3, 4};
73 buffer.append(tmp, 0, tmp.length);
74 Assert.assertEquals(16, buffer.capacity());
75 Assert.assertEquals(4, buffer.length());
76 Assert.assertFalse(buffer.isEmpty());
77 Assert.assertFalse(buffer.isFull());
78
79 final byte[] b2 = buffer.toByteArray();
80 Assert.assertNotNull(b2);
81 Assert.assertEquals(4, b2.length);
82 for (int i = 0; i < tmp.length; i++) {
83 Assert.assertEquals(tmp[i], b2[i]);
84 Assert.assertEquals(tmp[i], buffer.byteAt(i));
85 }
86 buffer.clear();
87 Assert.assertEquals(16, buffer.capacity());
88 Assert.assertEquals(0, buffer.length());
89 Assert.assertTrue(buffer.isEmpty());
90 Assert.assertFalse(buffer.isFull());
91 }
92
93 @Test
94 public void testExpandAppend() throws Exception {
95 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
96 Assert.assertEquals(4, buffer.capacity());
97
98 final byte[] tmp = new byte[] { 1, 2, 3, 4};
99 buffer.append(tmp, 0, 2);
100 buffer.append(tmp, 0, 4);
101 buffer.append(tmp, 0, 0);
102
103 Assert.assertEquals(8, buffer.capacity());
104 Assert.assertEquals(6, buffer.length());
105
106 buffer.append(tmp, 0, 4);
107
108 Assert.assertEquals(16, buffer.capacity());
109 Assert.assertEquals(10, buffer.length());
110 }
111
112 @Test
113 public void testAppendHeapByteBuffer() {
114 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
115 Assert.assertEquals(4, buffer.capacity());
116
117 final ByteBuffer tmp = ByteBuffer.wrap(new byte[] { 1, 2, 3, 4, 5, 6});
118 buffer.append(tmp);
119
120 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
121 Assert.assertEquals(8, buffer.capacity());
122 Assert.assertEquals(6, buffer.length());
123
124 tmp.clear();
125 buffer.append(tmp);
126
127 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
128 Assert.assertEquals(16, buffer.capacity());
129 Assert.assertEquals(12, buffer.length());
130 Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6}, buffer.toByteArray());
131 }
132
133 @Test
134 public void testAppendHeapByteBufferWithOffset() {
135 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
136 Assert.assertEquals(4, buffer.capacity());
137
138 final ByteBuffer tmp = ByteBuffer.wrap(new byte[] { 7, 7, 1, 2, 3, 4, 5, 6, 7, 7}, 2, 6).slice();
139 Assert.assertTrue("Validate this is testing a buffer with an array offset", tmp.arrayOffset() > 0);
140
141 buffer.append(tmp);
142
143 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
144 Assert.assertEquals(8, buffer.capacity());
145 Assert.assertEquals(6, buffer.length());
146
147 tmp.clear();
148 Assert.assertEquals(6, tmp.remaining());
149 buffer.append(tmp);
150
151 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
152 Assert.assertEquals(16, buffer.capacity());
153 Assert.assertEquals(12, buffer.length());
154 Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6}, buffer.toByteArray());
155 }
156
157 @Test
158 public void testAppendDirectByteBuffer() {
159 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
160 Assert.assertEquals(4, buffer.capacity());
161
162 final ByteBuffer tmp = ByteBuffer.allocateDirect(6);
163 tmp.put(new byte[] { 1, 2, 3, 4, 5, 6}).flip();
164 buffer.append(tmp);
165
166 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
167 Assert.assertEquals(8, buffer.capacity());
168 Assert.assertEquals(6, buffer.length());
169
170 tmp.clear();
171 buffer.append(tmp);
172
173 Assert.assertFalse("The input buffer should be drained", tmp.hasRemaining());
174 Assert.assertEquals(16, buffer.capacity());
175 Assert.assertEquals(12, buffer.length());
176 Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6}, buffer.toByteArray());
177 }
178
179 @Test
180 public void testInvalidAppend() throws Exception {
181 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
182 buffer.append((byte[])null, 0, 0);
183
184 final byte[] tmp = new byte[] { 1, 2, 3, 4};
185 try {
186 buffer.append(tmp, -1, 0);
187 Assert.fail("IndexOutOfBoundsException should have been thrown");
188 } catch (final IndexOutOfBoundsException ex) {
189
190 }
191 try {
192 buffer.append(tmp, 0, -1);
193 Assert.fail("IndexOutOfBoundsException should have been thrown");
194 } catch (final IndexOutOfBoundsException ex) {
195
196 }
197 try {
198 buffer.append(tmp, 0, 8);
199 Assert.fail("IndexOutOfBoundsException should have been thrown");
200 } catch (final IndexOutOfBoundsException ex) {
201
202 }
203 try {
204 buffer.append(tmp, 10, Integer.MAX_VALUE);
205 Assert.fail("IndexOutOfBoundsException should have been thrown");
206 } catch (final IndexOutOfBoundsException ex) {
207
208 }
209 try {
210 buffer.append(tmp, 2, 4);
211 Assert.fail("IndexOutOfBoundsException should have been thrown");
212 } catch (final IndexOutOfBoundsException ex) {
213
214 }
215 }
216
217 @Test
218 public void testAppendOneByte() throws Exception {
219 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
220 Assert.assertEquals(4, buffer.capacity());
221
222 final byte[] tmp = new byte[] { 1, 127, -1, -128, 1, -2};
223 for (final byte element : tmp) {
224 buffer.append(element);
225 }
226 Assert.assertEquals(8, buffer.capacity());
227 Assert.assertEquals(6, buffer.length());
228
229 for (int i = 0; i < tmp.length; i++) {
230 Assert.assertEquals(tmp[i], buffer.byteAt(i));
231 }
232 }
233
234 @Test
235 public void testSetLength() throws Exception {
236 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
237 buffer.setLength(2);
238 Assert.assertEquals(2, buffer.length());
239 }
240
241 @Test
242 public void testSetInvalidLength() throws Exception {
243 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
244 try {
245 buffer.setLength(-2);
246 Assert.fail("IndexOutOfBoundsException should have been thrown");
247 } catch (final IndexOutOfBoundsException ex) {
248
249 }
250 try {
251 buffer.setLength(200);
252 Assert.fail("IndexOutOfBoundsException should have been thrown");
253 } catch (final IndexOutOfBoundsException ex) {
254
255 }
256 }
257
258 @Test
259 public void testEnsureCapacity() throws Exception {
260 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
261 buffer.ensureCapacity(2);
262 Assert.assertEquals(4, buffer.capacity());
263 buffer.ensureCapacity(8);
264 Assert.assertEquals(8, buffer.capacity());
265 }
266
267 @Test
268 public void testIndexOf() throws Exception {
269 final byte COLON = (byte) ':';
270 final byte COMMA = (byte) ',';
271 final byte[] bytes = "name1: value1; name2: value2".getBytes(StandardCharsets.US_ASCII);
272 final int index1 = 5;
273 final int index2 = 20;
274
275 final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
276 buffer.append(bytes, 0, bytes.length);
277
278 Assert.assertEquals(index1, buffer.indexOf(COLON));
279 Assert.assertEquals(-1, buffer.indexOf(COMMA));
280 Assert.assertEquals(index1, buffer.indexOf(COLON, -1, 11));
281 Assert.assertEquals(index1, buffer.indexOf(COLON, 0, 1000));
282 Assert.assertEquals(-1, buffer.indexOf(COLON, 2, 1));
283 Assert.assertEquals(index2, buffer.indexOf(COLON, index1 + 1, buffer.length()));
284 }
285
286 @Test
287 public void testAppendCharArrayAsAscii() throws Exception {
288 final String s1 = "stuff";
289 final String s2 = " and more stuff";
290 final char[] b1 = s1.toCharArray();
291 final char[] b2 = s2.toCharArray();
292
293 final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
294 buffer.append(b1, 0, b1.length);
295 buffer.append(b2, 0, b2.length);
296
297 Assert.assertEquals(s1 + s2, new String(buffer.toByteArray(), StandardCharsets.US_ASCII));
298 }
299
300 @Test
301 public void testAppendNullCharArray() throws Exception {
302 final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
303 buffer.append((char[])null, 0, 0);
304 Assert.assertEquals(0, buffer.length());
305 }
306
307 @Test
308 public void testAppendEmptyCharArray() throws Exception {
309 final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
310 buffer.append(new char[] {}, 0, 0);
311 Assert.assertEquals(0, buffer.length());
312 }
313
314 @Test
315 public void testAppendNullCharArrayBuffer() throws Exception {
316 final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
317 buffer.append((CharArrayBuffer)null, 0, 0);
318 Assert.assertEquals(0, buffer.length());
319 }
320
321 @Test
322 public void testAppendNullByteBuffer() throws Exception {
323 final ByteArrayBuffer buffer = new ByteArrayBuffer(8);
324 final ByteBuffer nullBuffer = null;
325 buffer.append(nullBuffer);
326 Assert.assertEquals(0, buffer.length());
327 }
328
329 @Test
330 public void testInvalidAppendCharArrayAsAscii() throws Exception {
331 final ByteArrayBuffer buffer = new ByteArrayBuffer(4);
332 buffer.append((char[])null, 0, 0);
333
334 final char[] tmp = new char[] { '1', '2', '3', '4'};
335 try {
336 buffer.append(tmp, -1, 0);
337 Assert.fail("IndexOutOfBoundsException should have been thrown");
338 } catch (final IndexOutOfBoundsException ex) {
339
340 }
341 try {
342 buffer.append(tmp, 0, -1);
343 Assert.fail("IndexOutOfBoundsException should have been thrown");
344 } catch (final IndexOutOfBoundsException ex) {
345
346 }
347 try {
348 buffer.append(tmp, 0, 8);
349 Assert.fail("IndexOutOfBoundsException should have been thrown");
350 } catch (final IndexOutOfBoundsException ex) {
351
352 }
353 try {
354 buffer.append(tmp, 10, Integer.MAX_VALUE);
355 Assert.fail("IndexOutOfBoundsException should have been thrown");
356 } catch (final IndexOutOfBoundsException ex) {
357
358 }
359 try {
360 buffer.append(tmp, 2, 4);
361 Assert.fail("IndexOutOfBoundsException should have been thrown");
362 } catch (final IndexOutOfBoundsException ex) {
363
364 }
365 }
366
367 @Test
368 public void testSerialization() throws Exception {
369 final ByteArrayBuffer orig = new ByteArrayBuffer(32);
370 orig.append(1);
371 orig.append(2);
372 orig.append(3);
373 final ByteArrayOutputStream outbuffer = new ByteArrayOutputStream();
374 try (final ObjectOutputStream outStream = new ObjectOutputStream(outbuffer)) {
375 outStream.writeObject(orig);
376 }
377 final byte[] raw = outbuffer.toByteArray();
378 final ByteArrayInputStream inBuffer = new ByteArrayInputStream(raw);
379 final ObjectInputStream inStream = new ObjectInputStream(inBuffer);
380 final ByteArrayBuffer clone = (ByteArrayBuffer) inStream.readObject();
381 Assert.assertEquals(orig.capacity(), clone.capacity());
382 Assert.assertEquals(orig.length(), clone.length());
383 final byte[] data = clone.toByteArray();
384 Assert.assertNotNull(data);
385 Assert.assertEquals(3, data.length);
386 Assert.assertEquals(1, data[0]);
387 Assert.assertEquals(2, data[1]);
388 Assert.assertEquals(3, data[2]);
389 }
390
391 @Test
392 public void testControlCharFiltering() throws Exception {
393 final char[] chars = new char[256];
394 for (char i = 0; i < 256; i++) {
395 chars[i] = i;
396 }
397
398 final byte[] bytes = asByteArray(chars);
399
400 Assert.assertEquals(
401 "?????????\t??????????????????????"
402 + " !\"#$%&'()*+,-./0123456789:;<=>?"
403 + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
404 + "`abcdefghijklmnopqrstuvwxyz"
405 + "{|}~???????????????????????"
406 + "??????????\u00A0¡¢£¤¥¦§¨©ª«¬\u00AD®¯"
407 + "°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ"
408 + "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîï"
409 + "ðñòóôõö÷øùúûüýþÿ",
410 new String(bytes, StandardCharsets.ISO_8859_1));
411 }
412
413 @Test
414 public void testUnicodeFiltering() throws Exception {
415
416 Assert.assertEquals("?????", new String(asByteArray("буквы".toCharArray()), StandardCharsets.ISO_8859_1));
417 Assert.assertEquals("????", new String(asByteArray("四字熟語".toCharArray()), StandardCharsets.ISO_8859_1));
418
419
420 Assert.assertEquals("?", new String(asByteArray("☃".toCharArray()), StandardCharsets.ISO_8859_1));
421
422
423 Assert.assertEquals("??", new String(asByteArray("\uD83D\uDE00".toCharArray()), StandardCharsets.ISO_8859_1));
424 }
425
426 private static byte[] asByteArray(final char[] chars) {
427 final ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(chars.length);
428 byteArrayBuffer.append(chars, 0, chars.length);
429 return byteArrayBuffer.toByteArray();
430 }
431 }