1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package libcore.java.nio.charset; 18 19import java.nio.ByteBuffer; 20import java.nio.CharBuffer; 21import java.nio.charset.CharacterCodingException; 22import java.nio.charset.Charset; 23import java.nio.charset.CharsetDecoder; 24import java.nio.charset.CharsetEncoder; 25import java.nio.charset.CoderResult; 26import java.nio.charset.CodingErrorAction; 27 28public class CharsetDecoderTest extends junit.framework.TestCase { 29 // None of the harmony or jtreg tests actually check that replaceWith does the right thing! 30 public void test_replaceWith() throws Exception { 31 CharsetDecoder d = Charset.forName("UTF-16").newDecoder(); 32 d.replaceWith("x"); 33 d.onMalformedInput(CodingErrorAction.REPLACE); 34 d.onUnmappableCharacter(CodingErrorAction.REPLACE); 35 ByteBuffer in = ByteBuffer.wrap(new byte[] { 109, 97, 109 }); 36 assertEquals("\u6d61x", d.decode(in).toString()); 37 } 38 39 // http://code.google.com/p/android/issues/detail?id=4237 40 public void test_ByteArray_decode_no_offset() throws Exception { 41 CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder(); 42 byte[] arr = encode("UTF-16", "Android"); 43 ByteBuffer inBuffer = ByteBuffer.wrap(arr, 0, arr.length).slice(); 44 CharBuffer outBuffer = CharBuffer.allocate(arr.length); 45 decoder.reset(); 46 CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true); 47 assertFalse(coderResult.toString(), coderResult.isError()); 48 decoder.flush(outBuffer); 49 outBuffer.flip(); 50 assertEquals("Android", outBuffer.toString().trim()); 51 } 52 53 // http://code.google.com/p/android/issues/detail?id=4237 54 public void test_ByteArray_decode_with_offset() throws Exception { 55 CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder(); 56 byte[] arr = encode("UTF-16", "Android"); 57 arr = prependByteToByteArray(arr, new Integer(1).byteValue()); 58 int offset = 1; 59 ByteBuffer inBuffer = ByteBuffer.wrap(arr, offset, arr.length - offset).slice(); 60 CharBuffer outBuffer = CharBuffer.allocate(arr.length - offset); 61 decoder.reset(); 62 CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true); 63 assertFalse(coderResult.toString(), coderResult.isError()); 64 decoder.flush(outBuffer); 65 outBuffer.flip(); 66 assertEquals("Android", outBuffer.toString().trim()); 67 } 68 69 // http://code.google.com/p/android/issues/detail?id=4237 70 public void test_ByteArray_decode_with_offset_using_facade_method() throws Exception { 71 CharsetDecoder decoder = Charset.forName("UTF-16").newDecoder(); 72 byte[] arr = encode("UTF-16", "Android"); 73 arr = prependByteToByteArray(arr, new Integer(1).byteValue()); 74 int offset = 1; 75 CharBuffer outBuffer = decoder.decode(ByteBuffer.wrap(arr, offset, arr.length - offset)); 76 assertEquals("Android", outBuffer.toString().trim()); 77 } 78 79 private static byte[] prependByteToByteArray(byte[] arr, byte b) { 80 byte[] result = new byte[arr.length + 1]; 81 result[0] = b; 82 System.arraycopy(arr, 0, result, 1, arr.length); 83 return result; 84 } 85 86 private static byte[] encode(String charsetName, String s) throws Exception { 87 CharsetEncoder encoder = Charset.forName(charsetName).newEncoder(); 88 ByteBuffer buf = encoder.encode(CharBuffer.wrap(s)); 89 byte[] out = new byte[buf.remaining()]; 90 buf.get(out); 91 assertEquals(0, buf.remaining()); 92 return out; 93 } 94 95 public void testUtf8BytesSplitAcrossMultipleWrites() throws Exception { 96 CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 97 CharBuffer cb = CharBuffer.allocate(128); 98 CoderResult cr; 99 cr = decoder.decode(ByteBuffer.wrap(new byte[] { (byte) 0xe2 }), cb, false); 100 assertEquals(CoderResult.UNDERFLOW, cr); 101 cr = decoder.decode(ByteBuffer.wrap(new byte[] { (byte) 0x98 }), cb, false); 102 assertEquals(CoderResult.UNDERFLOW, cr); 103 cr = decoder.decode(ByteBuffer.wrap(new byte[] { (byte) 0x83 }), cb, false); 104 assertEquals(CoderResult.UNDERFLOW, cr); 105 cr = decoder.decode(ByteBuffer.wrap(new byte[0]), cb, true); 106 assertEquals(CoderResult.UNDERFLOW, cr); 107 cr = decoder.flush(cb); 108 assertEquals(CoderResult.UNDERFLOW, cr); 109 assertEquals(1, cb.position()); 110 assertEquals('\u2603', cb.get(0)); 111 } 112 113 public void testBufferWithNonZeroOffset() { 114 CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 115 CharBuffer cb = CharBuffer.allocate(128); 116 cb.position(42); 117 CharBuffer out = cb.slice(); 118 CoderResult cr = decoder.decode( 119 ByteBuffer.wrap(new byte[] { 'h', 'e', 'l', 'l', 'o'}), out, false); 120 assertTrue(cr.isUnderflow()); 121 assertEquals(5, out.position()); 122 } 123} 124