| /* |
| * ==================================================================== |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| */ |
| |
| package org.apache.hc.core5.http.impl.nio; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.nio.ByteBuffer; |
| import java.nio.channels.Channels; |
| import java.nio.channels.ReadableByteChannel; |
| import java.nio.channels.WritableByteChannel; |
| import java.nio.charset.CharacterCodingException; |
| import java.nio.charset.Charset; |
| import java.nio.charset.CharsetDecoder; |
| import java.nio.charset.CharsetEncoder; |
| import java.nio.charset.CodingErrorAction; |
| import java.nio.charset.StandardCharsets; |
| |
| import org.apache.hc.core5.http.MessageConstraintException; |
| import org.apache.hc.core5.http.nio.SessionInputBuffer; |
| import org.apache.hc.core5.http.nio.SessionOutputBuffer; |
| import org.apache.hc.core5.util.CharArrayBuffer; |
| import org.junit.jupiter.api.Assertions; |
| import org.junit.jupiter.api.Test; |
| |
| /** |
| * Simple tests for {@link SessionInputBuffer} and {@link SessionOutputBuffer}. |
| */ |
| public class TestSessionInOutBuffers { |
| |
| private static WritableByteChannel newChannel(final ByteArrayOutputStream outStream) { |
| return Channels.newChannel(outStream); |
| } |
| |
| private static ReadableByteChannel newChannel(final byte[] bytes) { |
| return Channels.newChannel(new ByteArrayInputStream(bytes)); |
| } |
| |
| private static ReadableByteChannel newChannel(final String s, final Charset charset) { |
| return Channels.newChannel(new ByteArrayInputStream(s.getBytes(charset))); |
| } |
| |
| private static ReadableByteChannel newChannel(final String s) { |
| return newChannel(s, StandardCharsets.US_ASCII); |
| } |
| |
| @Test |
| public void testReadLineChunks() throws Exception { |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16); |
| |
| ReadableByteChannel channel = newChannel("One\r\nTwo\r\nThree"); |
| |
| inbuf.fill(channel); |
| |
| final CharArrayBuffer line = new CharArrayBuffer(64); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("One", line.toString()); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("Two", line.toString()); |
| |
| line.clear(); |
| Assertions.assertFalse(inbuf.readLine(line, false)); |
| |
| channel = newChannel("\r\nFour"); |
| inbuf.fill(channel); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("Three", line.toString()); |
| |
| inbuf.fill(channel); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, true)); |
| Assertions.assertEquals("Four", line.toString()); |
| |
| line.clear(); |
| Assertions.assertFalse(inbuf.readLine(line, true)); |
| } |
| |
| @Test |
| public void testLineLimit() throws Exception { |
| final String s = "LoooooooooooooooooooooooooOOOOOOOOOOOOOOOOOOoooooooooooooooooooooong line\r\n"; |
| final CharArrayBuffer line = new CharArrayBuffer(64); |
| final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(128, 128); |
| final ReadableByteChannel channel1 = newChannel(s); |
| inbuf1.fill(channel1); |
| |
| Assertions.assertTrue(inbuf1.readLine(line, false)); |
| |
| line.clear(); |
| final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(128, 128, 10); |
| final ReadableByteChannel channel2 = newChannel(s); |
| inbuf2.fill(channel2); |
| Assertions.assertThrows(MessageConstraintException.class, () -> inbuf2.readLine(line, false)); |
| } |
| |
| @Test |
| public void testLineLimitBufferFull() throws Exception { |
| final String s = "LoooooooooooooooooooooooooOOOOOOOOOOOOOOOOOOoooooooooooooooooooooong line\r\n"; |
| final CharArrayBuffer line = new CharArrayBuffer(64); |
| final SessionInputBuffer inbuf1 = new SessionInputBufferImpl(32, 32); |
| final ReadableByteChannel channel1 = newChannel(s); |
| inbuf1.fill(channel1); |
| |
| Assertions.assertFalse(inbuf1.readLine(line, false)); |
| |
| line.clear(); |
| final SessionInputBuffer inbuf2 = new SessionInputBufferImpl(32, 32,10); |
| final ReadableByteChannel channel2 = newChannel(s); |
| inbuf2.fill(channel2); |
| Assertions.assertThrows(MessageConstraintException.class, () -> inbuf2.readLine(line, false)); |
| } |
| |
| @Test |
| public void testWriteLineChunks() throws Exception { |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(16, 16); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0); |
| |
| ReadableByteChannel inChannel = newChannel("One\r\nTwo\r\nThree"); |
| |
| inbuf.fill(inChannel); |
| |
| final CharArrayBuffer line = new CharArrayBuffer(64); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("One", line.toString()); |
| |
| outbuf.writeLine(line); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("Two", line.toString()); |
| |
| outbuf.writeLine(line); |
| |
| line.clear(); |
| Assertions.assertFalse(inbuf.readLine(line, false)); |
| |
| inChannel = newChannel("\r\nFour"); |
| inbuf.fill(inChannel); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, false)); |
| Assertions.assertEquals("Three", line.toString()); |
| |
| outbuf.writeLine(line); |
| |
| inbuf.fill(inChannel); |
| |
| line.clear(); |
| Assertions.assertTrue(inbuf.readLine(line, true)); |
| Assertions.assertEquals("Four", line.toString()); |
| |
| outbuf.writeLine(line); |
| |
| line.clear(); |
| Assertions.assertFalse(inbuf.readLine(line, true)); |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel outChannel = newChannel(outStream); |
| outbuf.flush(outChannel); |
| |
| final String s = new String(outStream.toByteArray(), StandardCharsets.US_ASCII); |
| Assertions.assertEquals("One\r\nTwo\r\nThree\r\nFour\r\n", s); |
| } |
| |
| @Test |
| public void testBasicReadWriteLine() throws Exception { |
| |
| final String[] teststrs = new String[5]; |
| teststrs[0] = "Hello"; |
| teststrs[1] = "This string should be much longer than the size of the line buffer " + |
| "which is only 16 bytes for this test"; |
| final StringBuilder buffer = new StringBuilder(); |
| for (int i = 0; i < 15; i++) { |
| buffer.append("123456789 "); |
| } |
| buffer.append("and stuff like that"); |
| teststrs[2] = buffer.toString(); |
| teststrs[3] = ""; |
| teststrs[4] = "And goodbye"; |
| |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(32); |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16); |
| for (final String teststr : teststrs) { |
| chbuffer.clear(); |
| chbuffer.append(teststr); |
| outbuf.writeLine(chbuffer); |
| } |
| //this write operation should have no effect |
| outbuf.writeLine(null); |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel outChannel = newChannel(outStream); |
| outbuf.flush(outChannel); |
| |
| final ReadableByteChannel channel = newChannel(outStream.toByteArray()); |
| |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, 0); |
| inbuf.fill(channel); |
| |
| for (final String teststr : teststrs) { |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(teststr, chbuffer.toString()); |
| } |
| chbuffer.clear(); |
| Assertions.assertFalse(inbuf.readLine(chbuffer, true)); |
| chbuffer.clear(); |
| Assertions.assertFalse(inbuf.readLine(chbuffer, true)); |
| } |
| |
| @Test |
| public void testComplexReadWriteLine() throws Exception { |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16); |
| outbuf.write(ByteBuffer.wrap(new byte[] {'a', '\n'})); |
| outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\n'})); |
| outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\r', '\n'})); |
| outbuf.write(ByteBuffer.wrap(new byte[] {'\n'})); |
| |
| final StringBuilder buffer = new StringBuilder(); |
| for (int i = 0; i < 14; i++) { |
| buffer.append("a"); |
| } |
| final String s1 = buffer.toString(); |
| buffer.append("\r\n"); |
| outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(StandardCharsets.US_ASCII))); |
| |
| buffer.setLength(0); |
| for (int i = 0; i < 15; i++) { |
| buffer.append("a"); |
| } |
| final String s2 = buffer.toString(); |
| buffer.append("\r\n"); |
| outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(StandardCharsets.US_ASCII))); |
| |
| buffer.setLength(0); |
| for (int i = 0; i < 16; i++) { |
| buffer.append("a"); |
| } |
| final String s3 = buffer.toString(); |
| buffer.append("\r\n"); |
| outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes(StandardCharsets.US_ASCII))); |
| |
| outbuf.write(ByteBuffer.wrap(new byte[] {'a'})); |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel outChannel = newChannel(outStream); |
| outbuf.flush(outChannel); |
| |
| final ReadableByteChannel channel = newChannel(outStream.toByteArray()); |
| |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 16, 0); |
| inbuf.fill(channel); |
| |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(32); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("a", chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("", chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("\r", chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("", chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s1, chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s2, chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s3, chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("a", chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertFalse(inbuf.readLine(chbuffer, true)); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertFalse(inbuf.readLine(chbuffer, true)); |
| } |
| |
| @Test |
| public void testReadOneByte() throws Exception { |
| // make the buffer larger than that of transmitter |
| final byte[] out = new byte[40]; |
| for (int i = 0; i < out.length; i++) { |
| out[i] = (byte)('0' + i); |
| } |
| final ReadableByteChannel channel = newChannel(out); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0); |
| while (inbuf.fill(channel) > 0) { |
| } |
| |
| final byte[] in = new byte[40]; |
| for (int i = 0; i < in.length; i++) { |
| in[i] = (byte)inbuf.read(); |
| } |
| for (int i = 0; i < out.length; i++) { |
| Assertions.assertEquals(out[i], in[i]); |
| } |
| } |
| |
| @Test |
| public void testReadByteBuffer() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| final ReadableByteChannel channel = newChannel(pattern); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, 0); |
| while (inbuf.fill(channel) > 0) { |
| } |
| final ByteBuffer dst = ByteBuffer.allocate(10); |
| Assertions.assertEquals(10, inbuf.read(dst)); |
| dst.flip(); |
| Assertions.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10)); |
| dst.clear(); |
| Assertions.assertEquals(6, inbuf.read(dst)); |
| dst.flip(); |
| Assertions.assertEquals(dst, ByteBuffer.wrap(pattern, 10, 6)); |
| } |
| |
| @Test |
| public void testReadByteBufferWithMaxLen() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| final ReadableByteChannel channel = newChannel(pattern); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, 0); |
| while (inbuf.fill(channel) > 0) { |
| } |
| final ByteBuffer dst = ByteBuffer.allocate(16); |
| Assertions.assertEquals(10, inbuf.read(dst, 10)); |
| dst.flip(); |
| Assertions.assertEquals(dst, ByteBuffer.wrap(pattern, 0, 10)); |
| dst.clear(); |
| Assertions.assertEquals(3, inbuf.read(dst, 3)); |
| dst.flip(); |
| Assertions.assertEquals(dst, ByteBuffer.wrap(pattern, 10, 3)); |
| Assertions.assertEquals(3, inbuf.read(dst, 20)); |
| dst.flip(); |
| Assertions.assertEquals(dst, ByteBuffer.wrap(pattern, 13, 3)); |
| } |
| |
| @Test |
| public void testReadToChannel() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| final ReadableByteChannel channel = newChannel(pattern); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, 0); |
| while (inbuf.fill(channel) > 0) { |
| } |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel dst = newChannel(outStream); |
| |
| Assertions.assertEquals(16, inbuf.read(dst)); |
| Assertions.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray())); |
| } |
| |
| @Test |
| public void testReadToChannelWithMaxLen() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| final ReadableByteChannel channel = newChannel(pattern); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, 0); |
| while (inbuf.fill(channel) > 0) { |
| } |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel dst = newChannel(outStream); |
| |
| Assertions.assertEquals(10, inbuf.read(dst, 10)); |
| Assertions.assertEquals(3, inbuf.read(dst, 3)); |
| Assertions.assertEquals(3, inbuf.read(dst, 10)); |
| Assertions.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray())); |
| } |
| |
| @Test |
| public void testWriteByteBuffer() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024); |
| final ReadableByteChannel src = newChannel(pattern); |
| outbuf.write(src); |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel channel = newChannel(outStream); |
| while (outbuf.flush(channel) > 0) { |
| } |
| Assertions.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray())); |
| } |
| |
| @Test |
| public void testWriteFromChannel() throws Exception { |
| final byte[] pattern = "0123456789ABCDEF0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); |
| |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(4096, 1024); |
| outbuf.write(ByteBuffer.wrap(pattern, 0, 16)); |
| outbuf.write(ByteBuffer.wrap(pattern, 16, 10)); |
| outbuf.write(ByteBuffer.wrap(pattern, 26, 6)); |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel channel = newChannel(outStream); |
| while (outbuf.flush(channel) > 0) { |
| } |
| Assertions.assertEquals(ByteBuffer.wrap(pattern), ByteBuffer.wrap(outStream.toByteArray())); |
| } |
| |
| static final int SWISS_GERMAN_HELLO [] = { |
| 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4 |
| }; |
| |
| static final int RUSSIAN_HELLO [] = { |
| 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438, |
| 0x432, 0x435, 0x442 |
| }; |
| |
| private static String constructString(final int [] unicodeChars) { |
| final StringBuilder buffer = new StringBuilder(); |
| if (unicodeChars != null) { |
| for (final int unicodeChar : unicodeChars) { |
| buffer.append((char)unicodeChar); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| @Test |
| public void testMultibyteCodedReadWriteLine() throws Exception { |
| final String s1 = constructString(SWISS_GERMAN_HELLO); |
| final String s2 = constructString(RUSSIAN_HELLO); |
| final String s3 = "Like hello and stuff"; |
| |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, |
| StandardCharsets.UTF_8.newEncoder()); |
| |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(32); |
| for (int i = 0; i < 10; i++) { |
| chbuffer.clear(); |
| chbuffer.append(s1); |
| outbuf.writeLine(chbuffer); |
| chbuffer.clear(); |
| chbuffer.append(s2); |
| outbuf.writeLine(chbuffer); |
| chbuffer.clear(); |
| chbuffer.append(s3); |
| outbuf.writeLine(chbuffer); |
| } |
| |
| final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final WritableByteChannel outChannel = newChannel(outStream); |
| outbuf.flush(outChannel); |
| |
| final byte[] tmp = outStream.toByteArray(); |
| |
| final ReadableByteChannel channel = newChannel(tmp); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0, |
| StandardCharsets.UTF_8.newDecoder()); |
| |
| while (inbuf.fill(channel) > 0) { |
| } |
| |
| for (int i = 0; i < 10; i++) { |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s1, chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s2, chbuffer.toString()); |
| chbuffer.clear(); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals(s3, chbuffer.toString()); |
| } |
| } |
| |
| @Test |
| public void testInputMatchesBufferLength() throws Exception { |
| final String s1 = "abcde"; |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 5); |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| chbuffer.append(s1); |
| outbuf.writeLine(chbuffer); |
| } |
| |
| @Test |
| public void testMalformedInputActionReport() throws Exception { |
| final String s = constructString(SWISS_GERMAN_HELLO); |
| final byte[] tmp = s.getBytes(StandardCharsets.ISO_8859_1); |
| |
| final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); |
| decoder.onMalformedInput(CodingErrorAction.REPORT); |
| decoder.onUnmappableCharacter(CodingErrorAction.IGNORE); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0, decoder); |
| final ReadableByteChannel channel = newChannel(tmp); |
| while (inbuf.fill(channel) > 0) { |
| } |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| Assertions.assertThrows(CharacterCodingException.class, () -> |
| inbuf.readLine(chbuffer, true)); |
| } |
| |
| @Test |
| public void testMalformedInputActionIgnore() throws Exception { |
| final String s = constructString(SWISS_GERMAN_HELLO); |
| final byte[] tmp = s.getBytes(StandardCharsets.ISO_8859_1); |
| |
| final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); |
| decoder.onMalformedInput(CodingErrorAction.IGNORE); |
| decoder.onUnmappableCharacter(CodingErrorAction.IGNORE); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0, decoder); |
| final ReadableByteChannel channel = newChannel(tmp); |
| while (inbuf.fill(channel) > 0) { |
| } |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("Grezi_zm", chbuffer.toString()); |
| } |
| |
| @Test |
| public void testMalformedInputActionReplace() throws Exception { |
| final String s = constructString(SWISS_GERMAN_HELLO); |
| final byte[] tmp = s.getBytes(StandardCharsets.ISO_8859_1); |
| |
| final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); |
| decoder.onMalformedInput(CodingErrorAction.REPLACE); |
| decoder.onUnmappableCharacter(CodingErrorAction.IGNORE); |
| final SessionInputBuffer inbuf = new SessionInputBufferImpl(16, 16, 0, decoder); |
| final ReadableByteChannel channel = newChannel(tmp); |
| while (inbuf.fill(channel) > 0) { |
| } |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| inbuf.readLine(chbuffer, true); |
| Assertions.assertEquals("Gr\ufffdezi_z\ufffdm\ufffd", chbuffer.toString()); |
| } |
| |
| @Test |
| public void testUnmappableInputActionReport() throws Exception { |
| final String s = "This text contains a circumflex \u0302!!!"; |
| final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder(); |
| encoder.onMalformedInput(CodingErrorAction.IGNORE); |
| encoder.onUnmappableCharacter(CodingErrorAction.REPORT); |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder); |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| chbuffer.append(s); |
| Assertions.assertThrows(CharacterCodingException.class, () -> |
| outbuf.writeLine(chbuffer)); |
| } |
| |
| @Test |
| public void testUnmappableInputActionIgnore() throws Exception { |
| final String s = "This text contains a circumflex \u0302!!!"; |
| final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder(); |
| encoder.onMalformedInput(CodingErrorAction.IGNORE); |
| encoder.onUnmappableCharacter(CodingErrorAction.IGNORE); |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder); |
| final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| final WritableByteChannel channel = newChannel(baos); |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| chbuffer.append(s); |
| outbuf.writeLine(chbuffer); |
| outbuf.flush(channel); |
| |
| final String result = new String(baos.toByteArray(), StandardCharsets.US_ASCII); |
| Assertions.assertEquals("This text contains a circumflex !!!\r\n", result); |
| } |
| |
| @Test |
| public void testUnmappableInputActionReplace() throws Exception { |
| final String s = "This text contains a circumflex \u0302 !!!"; |
| final CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder(); |
| encoder.onMalformedInput(CodingErrorAction.IGNORE); |
| encoder.onUnmappableCharacter(CodingErrorAction.REPLACE); |
| final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 16, encoder); |
| final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| final WritableByteChannel channel = newChannel(baos); |
| final CharArrayBuffer chbuffer = new CharArrayBuffer(16); |
| chbuffer.append(s); |
| outbuf.writeLine(chbuffer); |
| outbuf.flush(channel); |
| |
| final String result = new String(baos.toByteArray(), StandardCharsets.US_ASCII); |
| Assertions.assertEquals("This text contains a circumflex ? !!!\r\n", result); |
| } |
| |
| } |