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