156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes/* Licensed to the Apache Software Foundation (ASF) under one or more
256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * contributor license agreements.  See the NOTICE file distributed with
356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * this work for additional information regarding copyright ownership.
456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * The ASF licenses this file to You under the Apache License, Version 2.0
556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * (the "License"); you may not use this file except in compliance with
656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * the License.  You may obtain a copy of the License at
76ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes *
856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
96ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes *
1056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * Unless required by applicable law or agreed to in writing, software
1156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
1256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * See the License for the specific language governing permissions and
1456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes * limitations under the License.
1556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes */
1656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
17e5fea3d504609d22337a5311d3ce0e72314bceeeNarayan Kamathpackage org.apache.harmony.tests.java.nio.charset;
1856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
1956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.io.IOException;
2056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.BufferOverflowException;
2156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.ByteBuffer;
2256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.CharBuffer;
2356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CharacterCodingException;
2456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.Charset;
2556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CharsetDecoder;
2656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CharsetEncoder;
2756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CoderMalfunctionError;
2856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CoderResult;
2956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.CodingErrorAction;
3056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.nio.charset.MalformedInputException;
3156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport java.util.Arrays;
3256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
3356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughesimport junit.framework.TestCase;
3456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
35e5fea3d504609d22337a5311d3ce0e72314bceeeNarayan Kamathpublic class CharsetDecoder2Test extends TestCase {
3656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
3756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes    /**
3856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * @tests java.nio.charset.CharsetDecoder.CharsetDecoder(Charset, float,
3956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 *        float)
4056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
4156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	public void test_ConstructorLjava_nio_charset_CharsetFF() {
4256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// Regression for HARMONY-142
4356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		try {
4456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			Charset cs = Charset.forName("UTF-8"); //$NON-NLS-1$
4556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			new MockCharsetDecoderForHarmony142(cs, 1.1f, 1);
4656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			fail("Assert 0: Should throw IllegalArgumentException."); //$NON-NLS-1$
4756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		} catch (IllegalArgumentException e) {
4856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			// expected
4956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
5056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
5156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
5256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
5356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * MockCharsetDecoderForHarmony142: for constructor test
5456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
5556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	static class MockCharsetDecoderForHarmony142 extends CharsetDecoder {
5656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		protected MockCharsetDecoderForHarmony142(Charset cs,
5756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				float averageBytesPerChar, float maxBytesPerChar) {
5856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			super(cs, averageBytesPerChar, maxBytesPerChar);
5956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
6056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
6156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
6256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			return null;
6356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
6456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
656ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes
6656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/**
6756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * @tests java.nio.charset.CharsetDecoder#decode(java.nio.ByteBuffer)
6856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
6956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	public void test_decode() throws CharacterCodingException {
7056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// Regression for HARMONY-33
7156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		ByteBuffer bb = ByteBuffer.allocate(1);
7256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		bb.put(0, (byte) 77);
7356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder();
7456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		decoder.onMalformedInput(CodingErrorAction.REPLACE);
7556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
7656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		decoder.decode(bb);
7756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
7856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// Regression for HARMONY-67
7956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		byte[] b = new byte[] { (byte) 1 };
8056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		ByteBuffer buf = ByteBuffer.wrap(b);
8156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		CharBuffer charbuf = Charset.forName("UTF-16").decode(buf);
8256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		assertEquals("Assert 0: charset UTF-16", 1, charbuf.length());
8356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//
8456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		charbuf = Charset.forName("UTF-16BE").decode(buf);
8556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		assertEquals("Assert 1: charset UTF-16BE", 0, charbuf.length());
8656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//
8756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		charbuf = Charset.forName("UTF-16LE").decode(buf);
8856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes//		assertEquals("Assert 2: charset UTF16LE", 0, charbuf.length());
896ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes
9056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// Regression for HARMONY-99
9156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		CharsetDecoder decoder2 = Charset.forName("UTF-16").newDecoder();
9256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		decoder2.onMalformedInput(CodingErrorAction.REPORT);
9356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		decoder2.onUnmappableCharacter(CodingErrorAction.REPORT);
9456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		ByteBuffer in = ByteBuffer.wrap(new byte[] { 109, 97, 109 });
9556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		try {
9656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			decoder2.decode(in);
9756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			fail("Assert 3: MalformedInputException should have thrown");
9856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		} catch (MalformedInputException e) {
9956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			//expected
1006ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes		}
10156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
1026ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes
10356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes    /*
10456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes     * Test malfunction decode(ByteBuffer)
10556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes     */
10656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes    public void test_decodeLjava_nio_ByteBuffer() throws Exception {
10756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		MockMalfunctionCharset cs1 = new MockMalfunctionCharset(
10856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				"Harmony-124-1", null); //$NON-NLS-1$
10956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		try {
11056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			cs1.newDecoder().onMalformedInput(CodingErrorAction.REPLACE)
11156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes					.onUnmappableCharacter(CodingErrorAction.REPLACE).decode(
11256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes							ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
11356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			fail("Assert 0: should throw CoderMalfunctionError");  // NON-NLS-1$
11456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		} catch (CoderMalfunctionError e) {
11556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			// expected
11656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
11756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
11856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		MockMalfunctionCharset cs2 = new MockMalfunctionCharset(
11956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				"Harmony-124-2", null); //$NON-NLS-1$
12056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		try {
12156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			cs2.decode(ByteBuffer.wrap(new byte[] { 0x00, 0x11 }));
12256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			fail("Assert 1: Charset.decode should throw CoderMalfunctionError");  // NON-NLS-1
12356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		} catch (CoderMalfunctionError e) {
12456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			// expected
12556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
12656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
1276ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes
12856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
12956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * Mock charset class with malfunction decode & encode.
13056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
13156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	static final class MockMalfunctionCharset extends Charset {
13256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
13356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public MockMalfunctionCharset(String canonicalName, String[] aliases) {
13456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			super(canonicalName, aliases);
13556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
13656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
13756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public boolean contains(Charset cs) {
13856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			return false;
13956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
14056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
14156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public CharsetDecoder newDecoder() {
14256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			return new MockMalfunctionDecoder(this);
14356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
14456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
14556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public CharsetEncoder newEncoder() {
14656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			return new MockMalfunctionEncoder(this);
14756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
14856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
14956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
15056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
15156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * Mock decoder. decodeLoop always throws unexpected exception.
15256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
15356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	static class MockMalfunctionDecoder extends java.nio.charset.CharsetDecoder {
15456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
15556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public MockMalfunctionDecoder(Charset cs) {
15656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			super(cs, 1, 10);
15756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
15856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
15956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
16056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			throw new BufferOverflowException();
16156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
16256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
16356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
16456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
16556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * Mock encoder. encodeLoop always throws unexpected exception.
16656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
16756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	static class MockMalfunctionEncoder extends java.nio.charset.CharsetEncoder {
16856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
16956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public MockMalfunctionEncoder(Charset cs) {
17056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			super(cs, 1, 3, new byte[] { (byte) '?' });
17156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
17256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
17356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
17456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			throw new BufferOverflowException();
17556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
1766ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes	}
1776ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes
17856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
17956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * Test the method decode(ByteBuffer) .
18056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
18156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	public void testDecodeLjava_nio_ByteBuffer_ReplaceOverflow()
18256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			throws Exception {
18356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		String replaceString = "a";
18456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		Charset cs = Charset.forName("UTF-8");
18556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		MockMalformedDecoder decoder = new MockMalformedDecoder(cs);
18656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		decoder.onMalformedInput(CodingErrorAction.REPLACE);
18756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		decoder.replaceWith(replaceString);
18856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		CharBuffer out = CharBuffer.allocate(1);
18956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// MockMalformedDecoder treats the second byte '0x38' as malformed,
19056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// but "out" doesn't have enough space for replace string.
19156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		ByteBuffer in = ByteBuffer.wrap(new byte[] { 0x45, 0x38, 0x45, 0x45 });
19256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		CoderResult result = decoder.decode(in, out, false);
19356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		assertTrue(result.isOverflow());
19456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
19556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// allocate enough space for "out"
19656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		out = CharBuffer.allocate(10);
19756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// replace string should be put into "out" firstly,
19856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		// and then decode "in".
19956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		result = decoder.decode(in, out, true);
20056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		out.flip();
20156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		assertTrue(result.isUnderflow());
20256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		assertEquals("bb", out.toString());
20356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
20456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
20556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	/*
20656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * Mock decoder. It treats byte whose value is less than "0x40" as
20756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 * malformed.
20856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	 */
20956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	static class MockMalformedDecoder extends java.nio.charset.CharsetDecoder {
21056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
21156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		public MockMalformedDecoder(Charset cs) {
21256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			super(cs, 1, 10);
21356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
21456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
21556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		/*
21656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		 * It treats byte whose value is less than "0x40" as malformed.
21756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		 * Otherwise, it's decoded as 'b'.
21856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		 */
21956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
22056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			while (in.hasRemaining()) {
22156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				byte b = in.get();
22256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				if (b < 0x40) {
22356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes					return CoderResult.malformedForLength(1);
22456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				}
22556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				if (!out.hasRemaining()) {
22656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes					return CoderResult.OVERFLOW;
22756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				}
22856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes				out.put((char) 'b');
22956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			}
23056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes			return CoderResult.UNDERFLOW;
23156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes		}
23256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes	}
23356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
23456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
23556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes    public void testInvalidDecoding() throws IOException {
23656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
23756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        byte[][] invalidSequences = new byte[][] {
23856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            // overlong NULL
23956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            { (byte) 0xC0, (byte) 0x80 },
24056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            // overlong ascii 'A'
24156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            { (byte) 0xC0, (byte) 0xC1 },
24256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            // overlong "/../"
24356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            { (byte) 0x2F, (byte) 0xC0, (byte) 0xAE, (byte) 0x2E, (byte) 0x2F },
24456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            // Invalid encoding 2r11111000 (sequence too long)
24556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            { (byte) 0xF8 },
24656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            // Invalid encoding 2r10000000 (sequence too short)
24756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            { (byte) 0x80 }
24856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        };
24956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
25056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
25156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        decoder.onMalformedInput(CodingErrorAction.REPORT);
2526ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes        decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
25356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
25456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        /*
25556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes         * When bytebuffer has a backing array...
25656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes         */
25756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        for (byte[] bytes : invalidSequences) {
25856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            try {
2596ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes                CharBuffer cb = decoder.decode(ByteBuffer.wrap(bytes));
2606ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes                fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
2616ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes            } catch (MalformedInputException expected) {
26256ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            }
26356ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        }
26456ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
26556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        /*
26656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes         * When bytebuffer has _not_ got a backing array...
26756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes         */
26856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        for (byte[] bytes : invalidSequences) {
26956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            try {
27056ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes                ByteBuffer bb = ByteBuffer.allocateDirect(8);
27156ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes                bb.put(bytes).flip();
2726ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes                CharBuffer cb = decoder.decode(bb);
2736ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes                fail("No exception thrown on " + Arrays.toString(bytes) + " '" + cb + "'");
2746ad37f500b023ef09fd177ad8cd8e2ba0b842caeElliott Hughes            } catch (MalformedInputException expected) {
27556ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes            }
27656ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes        }
27756ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes    }
27856ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes
27956ddb0af9c75dca21f10cd26e73b9f301c58771eElliott Hughes}
280