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.http.impl.io;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.InputStream;
33 import java.nio.charset.CharacterCodingException;
34 import java.nio.charset.CharsetDecoder;
35 import java.nio.charset.CharsetEncoder;
36 import java.nio.charset.CodingErrorAction;
37 import java.nio.charset.StandardCharsets;
38
39 import org.apache.hc.core5.http.MessageConstraintException;
40 import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
41 import org.apache.hc.core5.http.io.HttpTransportMetrics;
42 import org.apache.hc.core5.http.io.SessionInputBuffer;
43 import org.apache.hc.core5.http.io.SessionOutputBuffer;
44 import org.apache.hc.core5.util.CharArrayBuffer;
45 import org.junit.Assert;
46 import org.junit.Test;
47 import org.mockito.ArgumentMatchers;
48 import org.mockito.Mockito;
49
50 public class TestSessionInOutBuffers {
51
52 @Test
53 public void testBasicBufferProperties() throws Exception {
54 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
55 final ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] { 1, 2 , 3});
56 Assert.assertEquals(16, inBuffer.capacity());
57 Assert.assertEquals(16, inBuffer.available());
58 Assert.assertEquals(0, inBuffer.length());
59 inBuffer.read(inputStream);
60 Assert.assertEquals(14, inBuffer.available());
61 Assert.assertEquals(2, inBuffer.length());
62
63 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
64 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
65 Assert.assertEquals(16, outbuffer.capacity());
66 Assert.assertEquals(16, outbuffer.available());
67 Assert.assertEquals(0, outbuffer.length());
68 outbuffer.write(new byte[] {1, 2, 3}, outputStream);
69 Assert.assertEquals(13, outbuffer.available());
70 Assert.assertEquals(3, outbuffer.length());
71 }
72
73 @Test
74 public void testBasicReadWriteLine() throws Exception {
75
76 final String[] teststrs = new String[5];
77 teststrs[0] = "Hello";
78 teststrs[1] = "This string should be much longer than the size of the output buffer " +
79 "which is only 16 bytes for this test";
80 final StringBuilder buffer = new StringBuilder();
81 for (int i = 0; i < 15; i++) {
82 buffer.append("123456789 ");
83 }
84 buffer.append("and stuff like that");
85 teststrs[2] = buffer.toString();
86 teststrs[3] = "";
87 teststrs[4] = "And goodbye";
88
89 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
90 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
91 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
92 for (final String teststr : teststrs) {
93 chbuffer.clear();
94 chbuffer.append(teststr);
95 outbuffer.writeLine(chbuffer, outputStream);
96 }
97
98 outbuffer.writeLine(null, outputStream);
99 outbuffer.flush(outputStream);
100
101 HttpTransportMetrics tmetrics = outbuffer.getMetrics();
102 final long bytesWritten = tmetrics.getBytesTransferred();
103 long expected = 0;
104 for (final String teststr : teststrs) {
105 expected += (teststr.length() + 2);
106 }
107 Assert.assertEquals(expected, bytesWritten);
108
109 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
110 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
111
112 for (final String teststr : teststrs) {
113 chbuffer.clear();
114 inBuffer.readLine(chbuffer, inputStream);
115 Assert.assertEquals(teststr, chbuffer.toString());
116 }
117
118 chbuffer.clear();
119 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
120 chbuffer.clear();
121 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
122 tmetrics = inBuffer.getMetrics();
123 final long bytesRead = tmetrics.getBytesTransferred();
124 Assert.assertEquals(expected, bytesRead);
125 }
126
127 @Test
128 public void testComplexReadWriteLine() throws Exception {
129 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
130 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
131 outbuffer.write(new byte[] {'a', '\n'}, outputStream);
132 outbuffer.write(new byte[] {'\r', '\n'}, outputStream);
133 outbuffer.write(new byte[] {'\r', '\r', '\n'}, outputStream);
134 outbuffer.write(new byte[] {'\n'},outputStream);
135
136 outbuffer.write(null, outputStream);
137 outbuffer.write(null, 0, 12, outputStream);
138
139 outbuffer.flush(outputStream);
140
141 long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
142 Assert.assertEquals(8, bytesWritten);
143
144 final StringBuilder buffer = new StringBuilder();
145 for (int i = 0; i < 14; i++) {
146 buffer.append("a");
147 }
148 final String s1 = buffer.toString();
149 buffer.append("\r\n");
150 outbuffer.write(buffer.toString().getBytes(StandardCharsets.US_ASCII), outputStream);
151 outbuffer.flush(outputStream);
152 bytesWritten = outbuffer.getMetrics().getBytesTransferred();
153 Assert.assertEquals(8 + 14 +2, bytesWritten);
154
155 buffer.setLength(0);
156 for (int i = 0; i < 15; i++) {
157 buffer.append("a");
158 }
159 final String s2 = buffer.toString();
160 buffer.append("\r\n");
161 outbuffer.write(buffer.toString().getBytes(StandardCharsets.US_ASCII), outputStream);
162 outbuffer.flush(outputStream);
163 bytesWritten = outbuffer.getMetrics().getBytesTransferred();
164 Assert.assertEquals(8 + 14 + 2 + 15 + 2 , bytesWritten);
165
166 buffer.setLength(0);
167 for (int i = 0; i < 16; i++) {
168 buffer.append("a");
169 }
170 final String s3 = buffer.toString();
171 buffer.append("\r\n");
172 outbuffer.write(buffer.toString().getBytes(StandardCharsets.US_ASCII), outputStream);
173 outbuffer.flush(outputStream);
174 bytesWritten = outbuffer.getMetrics().getBytesTransferred();
175 Assert.assertEquals(8 + 14 + 2 + 15 + 2 + 16 + 2, bytesWritten);
176
177 outbuffer.write(new byte[] {'a'}, outputStream);
178 outbuffer.flush(outputStream);
179 bytesWritten = outbuffer.getMetrics().getBytesTransferred();
180 Assert.assertEquals(8 + 14 + 2 + 15 + 2 + 16 + 2 + 1, bytesWritten);
181
182 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
183 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
184
185 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
186 chbuffer.clear();
187 inBuffer.readLine(chbuffer, inputStream);
188 Assert.assertEquals("a", chbuffer.toString());
189 chbuffer.clear();
190 inBuffer.readLine(chbuffer, inputStream);
191 Assert.assertEquals("", chbuffer.toString());
192 chbuffer.clear();
193 inBuffer.readLine(chbuffer, inputStream);
194 Assert.assertEquals("\r", chbuffer.toString());
195 chbuffer.clear();
196 inBuffer.readLine(chbuffer, inputStream);
197 Assert.assertEquals("", chbuffer.toString());
198 chbuffer.clear();
199 inBuffer.readLine(chbuffer, inputStream);
200 Assert.assertEquals(s1, chbuffer.toString());
201 chbuffer.clear();
202 inBuffer.readLine(chbuffer, inputStream);
203 Assert.assertEquals(s2, chbuffer.toString());
204 chbuffer.clear();
205 inBuffer.readLine(chbuffer, inputStream);
206 Assert.assertEquals(s3, chbuffer.toString());
207 chbuffer.clear();
208 inBuffer.readLine(chbuffer, inputStream);
209 Assert.assertEquals("a", chbuffer.toString());
210 chbuffer.clear();
211 inBuffer.readLine(chbuffer, inputStream);
212 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
213 chbuffer.clear();
214 inBuffer.readLine(chbuffer, inputStream);
215 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
216 final long bytesRead = inBuffer.getMetrics().getBytesTransferred();
217 Assert.assertEquals(bytesWritten, bytesRead);
218 }
219
220 @Test
221 public void testBasicReadWriteLineLargeBuffer() throws Exception {
222
223 final String[] teststrs = new String[5];
224 teststrs[0] = "Hello";
225 teststrs[1] = "This string should be much longer than the size of the output buffer " +
226 "which is only 16 bytes for this test";
227 final StringBuilder buffer = new StringBuilder();
228 for (int i = 0; i < 15; i++) {
229 buffer.append("123456789 ");
230 }
231 buffer.append("and stuff like that");
232 teststrs[2] = buffer.toString();
233 teststrs[3] = "";
234 teststrs[4] = "And goodbye";
235
236 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
237 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
238 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
239 for (final String teststr : teststrs) {
240 chbuffer.clear();
241 chbuffer.append(teststr);
242 outbuffer.writeLine(chbuffer, outputStream);
243 }
244
245 outbuffer.writeLine(null, outputStream);
246 outbuffer.flush(outputStream);
247
248 final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
249 long expected = 0;
250 for (final String teststr : teststrs) {
251 expected += (teststr.length() + 2);
252 }
253 Assert.assertEquals(expected, bytesWritten);
254
255 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(1024);
256 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
257
258 for (final String teststr : teststrs) {
259 chbuffer.clear();
260 inBuffer.readLine(chbuffer, inputStream);
261 Assert.assertEquals(teststr, chbuffer.toString());
262 }
263 chbuffer.clear();
264 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
265 chbuffer.clear();
266 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
267 final long bytesRead = inBuffer.getMetrics().getBytesTransferred();
268 Assert.assertEquals(expected, bytesRead);
269 }
270
271 @Test
272 public void testReadWriteBytes() throws Exception {
273
274 final byte[] out = new byte[40];
275 for (int i = 0; i < out.length; i++) {
276 out[i] = (byte)('0' + i);
277 }
278 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
279 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
280 int off = 0;
281 int remaining = out.length;
282 while (remaining > 0) {
283 int chunk = 10;
284 if (chunk > remaining) {
285 chunk = remaining;
286 }
287 outbuffer.write(out, off, chunk, outputStream);
288 off += chunk;
289 remaining -= chunk;
290 }
291 outbuffer.flush(outputStream);
292 final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
293 Assert.assertEquals(out.length, bytesWritten);
294
295 final byte[] tmp = outputStream.toByteArray();
296 Assert.assertEquals(out.length, tmp.length);
297 for (int i = 0; i < out.length; i++) {
298 Assert.assertEquals(out[i], tmp[i]);
299 }
300
301 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
302 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
303
304
305 Assert.assertEquals(0, inBuffer.read(null, 0, 10, inputStream));
306 Assert.assertEquals(0, inBuffer.read(null, inputStream));
307 long bytesRead = inBuffer.getMetrics().getBytesTransferred();
308 Assert.assertEquals(0, bytesRead);
309
310 final byte[] in = new byte[40];
311 off = 0;
312 remaining = in.length;
313 while (remaining > 0) {
314 int chunk = 10;
315 if (chunk > remaining) {
316 chunk = remaining;
317 }
318 final int readLen = inBuffer.read(in, off, chunk, inputStream);
319 if (readLen == -1) {
320 break;
321 }
322 off += readLen;
323 remaining -= readLen;
324 }
325 for (int i = 0; i < out.length; i++) {
326 Assert.assertEquals(out[i], in[i]);
327 }
328 Assert.assertEquals(-1, inBuffer.read(tmp, inputStream));
329 Assert.assertEquals(-1, inBuffer.read(tmp, inputStream));
330 bytesRead = inBuffer.getMetrics().getBytesTransferred();
331 Assert.assertEquals(out.length, bytesRead);
332 }
333
334 @Test
335 public void testReadWriteByte() throws Exception {
336
337 final byte[] out = new byte[40];
338 for (int i = 0; i < out.length; i++) {
339 out[i] = (byte)(120 + i);
340 }
341 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
342 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
343 for (final byte element : out) {
344 outbuffer.write(element, outputStream);
345 }
346 outbuffer.flush(outputStream);
347 final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
348 Assert.assertEquals(out.length, bytesWritten);
349
350 final byte[] tmp = outputStream.toByteArray();
351 Assert.assertEquals(out.length, tmp.length);
352 for (int i = 0; i < out.length; i++) {
353 Assert.assertEquals(out[i], tmp[i]);
354 }
355
356 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16);
357 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
358 final byte[] in = new byte[40];
359 for (int i = 0; i < in.length; i++) {
360 in[i] = (byte)inBuffer.read(inputStream);
361 }
362 for (int i = 0; i < out.length; i++) {
363 Assert.assertEquals(out[i], in[i]);
364 }
365 Assert.assertEquals(-1, inBuffer.read(inputStream));
366 Assert.assertEquals(-1, inBuffer.read(inputStream));
367 final long bytesRead = inBuffer.getMetrics().getBytesTransferred();
368 Assert.assertEquals(out.length, bytesRead);
369 }
370
371 @Test
372 public void testWriteSmallFragmentBuffering() throws Exception {
373 final ByteArrayOutputStream outputStream = Mockito.spy(new ByteArrayOutputStream());
374 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(new BasicHttpTransportMetrics(), 16, 16, null);
375 outbuffer.write(1, outputStream);
376 outbuffer.write(2, outputStream);
377 outbuffer.write(new byte[] {1, 2}, outputStream);
378 outbuffer.write(new byte[]{3, 4}, outputStream);
379 outbuffer.flush(outputStream);
380 Mockito.verify(outputStream, Mockito.times(1)).write(ArgumentMatchers.<byte[]>any(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt());
381 Mockito.verify(outputStream, Mockito.never()).write(ArgumentMatchers.anyInt());
382 }
383
384 @Test
385 public void testWriteSmallFragmentNoBuffering() throws Exception {
386 final ByteArrayOutputStream outputStream = Mockito.spy(new ByteArrayOutputStream());
387 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(new BasicHttpTransportMetrics(), 16, 0, null);
388 outbuffer.write(1, outputStream);
389 outbuffer.write(2, outputStream);
390 outbuffer.write(new byte[] {1, 2}, outputStream);
391 outbuffer.write(new byte[]{3, 4}, outputStream);
392 Mockito.verify(outputStream, Mockito.times(2)).write(ArgumentMatchers.<byte []>any(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt());
393 Mockito.verify(outputStream, Mockito.times(2)).write(ArgumentMatchers.anyInt());
394 }
395
396 @Test
397 public void testLineLimit() throws Exception {
398 final String s = "a very looooooooooooooooooooooooooooooooooooooooooong line\r\n";
399 final byte[] tmp = s.getBytes(StandardCharsets.US_ASCII);
400
401 final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(5);
402 final InputStream inputStream1 = new ByteArrayInputStream(tmp);
403 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
404 inBuffer1.readLine(chbuffer, inputStream1);
405 final long bytesRead = inBuffer1.getMetrics().getBytesTransferred();
406 Assert.assertEquals(60, bytesRead);
407
408
409 final SessionInputBuffer inBuffer2 = new SessionInputBufferImpl(5, 15);
410 final InputStream inputStream2 = new ByteArrayInputStream(tmp);
411 try {
412 chbuffer.clear();
413 inBuffer2.readLine(chbuffer, inputStream2);
414 Assert.fail("MessageConstraintException expected");
415 } catch (final MessageConstraintException ex) {
416 }
417 }
418
419 @Test
420 public void testLineLimit2() throws Exception {
421 final String s = "just a line\r\n";
422 final byte[] tmp = s.getBytes(StandardCharsets.US_ASCII);
423
424 final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(25);
425 final InputStream inputStream1 = new ByteArrayInputStream(tmp);
426 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
427 inBuffer1.readLine(chbuffer, inputStream1);
428 final long bytesRead = inBuffer1.getMetrics().getBytesTransferred();
429 Assert.assertEquals(13, bytesRead);
430
431
432 final SessionInputBuffer inBuffer2 = new SessionInputBufferImpl(25, 10);
433 final InputStream inputStream2 = new ByteArrayInputStream(tmp);
434 try {
435 chbuffer.clear();
436 inBuffer2.readLine(chbuffer, inputStream2);
437 Assert.fail("MessageConstraintException expected");
438 } catch (final MessageConstraintException ex) {
439 }
440 }
441
442 @Test
443 public void testLineLimit3() throws Exception {
444 final String s = "012345678\r\nblaaaaaaaaaaaaaaaaaah";
445 final byte[] tmp = s.getBytes(StandardCharsets.US_ASCII);
446 final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(128);
447 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
448 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
449 inBuffer1.readLine(chbuffer, inputStream);
450 Assert.assertEquals("012345678", chbuffer.toString());
451 }
452
453 @Test
454 public void testReadLineFringeCase1() throws Exception {
455 final String s = "abc\r\n";
456 final byte[] tmp = s.getBytes(StandardCharsets.US_ASCII);
457 final SessionInputBuffer inBuffer1 = new SessionInputBufferImpl(128);
458 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
459 Assert.assertEquals('a', inBuffer1.read(inputStream));
460 Assert.assertEquals('b', inBuffer1.read(inputStream));
461 Assert.assertEquals('c', inBuffer1.read(inputStream));
462 Assert.assertEquals('\r', inBuffer1.read(inputStream));
463 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
464 Assert.assertEquals(0, inBuffer1.readLine(chbuffer, inputStream));
465 }
466
467 static final int SWISS_GERMAN_HELLO [] = {
468 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
469 };
470
471 static final int RUSSIAN_HELLO [] = {
472 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
473 0x432, 0x435, 0x442
474 };
475
476 private static String constructString(final int [] unicodeChars) {
477 final StringBuilder buffer = new StringBuilder();
478 if (unicodeChars != null) {
479 for (final int unicodeChar : unicodeChars) {
480 buffer.append((char)unicodeChar);
481 }
482 }
483 return buffer.toString();
484 }
485
486 @Test
487 public void testMultibyteCodedReadWriteLine() throws Exception {
488 final String s1 = constructString(SWISS_GERMAN_HELLO);
489 final String s2 = constructString(RUSSIAN_HELLO);
490 final String s3 = "Like hello and stuff";
491
492 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, StandardCharsets.UTF_8.newEncoder());
493 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
494
495 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
496 for (int i = 0; i < 10; i++) {
497 chbuffer.clear();
498 chbuffer.append(s1);
499 outbuffer.writeLine(chbuffer, outputStream);
500 chbuffer.clear();
501 chbuffer.append(s2);
502 outbuffer.writeLine(chbuffer, outputStream);
503 chbuffer.clear();
504 chbuffer.append(s3);
505 outbuffer.writeLine(chbuffer, outputStream);
506 }
507 outbuffer.flush(outputStream);
508 final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
509 final long expected = ((s1.getBytes(StandardCharsets.UTF_8).length + 2)+
510 (s2.getBytes(StandardCharsets.UTF_8).length + 2) +
511 (s3.getBytes(StandardCharsets.UTF_8).length + 2)) * 10;
512 Assert.assertEquals(expected, bytesWritten);
513
514 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, StandardCharsets.UTF_8.newDecoder());
515 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
516
517 for (int i = 0; i < 10; i++) {
518 chbuffer.clear();
519 inBuffer.readLine(chbuffer, inputStream);
520 Assert.assertEquals(s1, chbuffer.toString());
521 chbuffer.clear();
522 inBuffer.readLine(chbuffer, inputStream);
523 Assert.assertEquals(s2, chbuffer.toString());
524 chbuffer.clear();
525 inBuffer.readLine(chbuffer, inputStream);
526 Assert.assertEquals(s3, chbuffer.toString());
527 }
528 chbuffer.clear();
529 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
530 chbuffer.clear();
531 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
532 final long bytesRead = inBuffer.getMetrics().getBytesTransferred();
533 Assert.assertEquals(expected, bytesRead);
534 }
535
536 @Test
537 public void testMultibyteCodedReadWriteLongLine() throws Exception {
538 final String s1 = constructString(SWISS_GERMAN_HELLO);
539 final String s2 = constructString(RUSSIAN_HELLO);
540 final String s3 = "Like hello and stuff";
541 final StringBuilder buf = new StringBuilder();
542 for (int i = 0; i < 1024; i++) {
543 buf.append(s1).append(s2).append(s3);
544 }
545 final String s = buf.toString();
546
547 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, StandardCharsets.UTF_8.newEncoder());
548 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
549
550 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
551 chbuffer.append(s);
552 outbuffer.writeLine(chbuffer, outputStream);
553 outbuffer.flush(outputStream);
554
555 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, StandardCharsets.UTF_8.newDecoder());
556 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
557
558 chbuffer.clear();
559 inBuffer.readLine(chbuffer, inputStream);
560 Assert.assertEquals(s, chbuffer.toString());
561 }
562
563 @Test
564 public void testNonAsciiReadWriteLine() throws Exception {
565 final String s1 = constructString(SWISS_GERMAN_HELLO);
566
567 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, StandardCharsets.ISO_8859_1.newEncoder());
568 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
569
570 final CharArrayBuffer chbuffer = new CharArrayBuffer(16);
571 for (int i = 0; i < 10; i++) {
572 chbuffer.clear();
573 chbuffer.append(s1);
574 outbuffer.writeLine(chbuffer, outputStream);
575 }
576 chbuffer.clear();
577 outbuffer.writeLine(chbuffer, outputStream);
578 outbuffer.flush(outputStream);
579 final long bytesWritten = outbuffer.getMetrics().getBytesTransferred();
580 final long expected = ((s1.getBytes(StandardCharsets.ISO_8859_1).length + 2)) * 10 + 2;
581 Assert.assertEquals(expected, bytesWritten);
582
583 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, StandardCharsets.ISO_8859_1.newDecoder());
584 final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
585
586 for (int i = 0; i < 10; i++) {
587 chbuffer.clear();
588 final int len = inBuffer.readLine(chbuffer, inputStream);
589 Assert.assertEquals(len, SWISS_GERMAN_HELLO.length);
590 Assert.assertEquals(s1, chbuffer.toString());
591 }
592 chbuffer.clear();
593 Assert.assertEquals(0, inBuffer.readLine(chbuffer, inputStream));
594 chbuffer.clear();
595 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
596 chbuffer.clear();
597 Assert.assertEquals(-1, inBuffer.readLine(chbuffer, inputStream));
598 final long bytesRead = inBuffer.getMetrics().getBytesTransferred();
599 Assert.assertEquals(expected, bytesRead);
600 }
601
602 @Test(expected=CharacterCodingException.class)
603 public void testUnmappableInputActionReport() throws Exception {
604 final String s = "This text contains a circumflex \u0302 !!!";
605 final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
606 encoder.onMalformedInput(CodingErrorAction.IGNORE);
607 encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
608 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, encoder);
609 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
610 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
611 chbuffer.append(s);
612 outbuffer.writeLine(chbuffer, outputStream);
613 }
614
615 @Test
616 public void testUnmappableInputActionReplace() throws Exception {
617 final String s = "This text contains a circumflex \u0302 !!!";
618 final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
619 encoder.onMalformedInput(CodingErrorAction.IGNORE);
620 encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
621 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, encoder);
622 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
623 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
624 chbuffer.append(s);
625 outbuffer.writeLine(chbuffer, outputStream);
626 outbuffer.flush(outputStream);
627 final String result = new String(outputStream.toByteArray(), StandardCharsets.ISO_8859_1);
628 Assert.assertEquals("This text contains a circumflex ? !!!\r\n", result);
629 }
630
631 @Test
632 public void testUnmappableInputActionIgnore() throws Exception {
633 final String s = "This text contains a circumflex \u0302 !!!";
634 final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
635 encoder.onMalformedInput(CodingErrorAction.IGNORE);
636 encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
637 final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16, encoder);
638 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
639 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
640 chbuffer.append(s);
641 outbuffer.writeLine(chbuffer, outputStream);
642 outbuffer.flush(outputStream);
643 final String result = new String(outputStream.toByteArray(), StandardCharsets.ISO_8859_1);
644 Assert.assertEquals("This text contains a circumflex !!!\r\n", result);
645 }
646
647 @Test(expected=CharacterCodingException.class)
648 public void testMalformedInputActionReport() throws Exception {
649 final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(StandardCharsets.ISO_8859_1);
650 final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
651 decoder.onMalformedInput(CodingErrorAction.REPORT);
652 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
653 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, decoder);
654 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
655 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
656 inBuffer.readLine(chbuffer, inputStream);
657 }
658
659 @Test
660 public void testMalformedInputActionReplace() throws Exception {
661 final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(StandardCharsets.ISO_8859_1);
662 final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
663 decoder.onMalformedInput(CodingErrorAction.REPLACE);
664 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
665 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, decoder);
666 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
667 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
668 inBuffer.readLine(chbuffer, inputStream);
669 Assert.assertEquals("Gr\ufffdezi_z\ufffdm\ufffd", chbuffer.toString());
670 }
671
672 @Test
673 public void testMalformedInputActionIgnore() throws Exception {
674 final byte[] tmp = constructString(SWISS_GERMAN_HELLO).getBytes(StandardCharsets.ISO_8859_1);
675 final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
676 decoder.onMalformedInput(CodingErrorAction.IGNORE);
677 decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
678 final SessionInputBuffer inBuffer = new SessionInputBufferImpl(16, decoder);
679 final ByteArrayInputStream inputStream = new ByteArrayInputStream(tmp);
680 final CharArrayBuffer chbuffer = new CharArrayBuffer(32);
681 inBuffer.readLine(chbuffer, inputStream);
682 Assert.assertEquals("Grezi_zm", chbuffer.toString());
683 }
684
685 }
686