Home | History | Annotate | Download | only in charset
      1 /* Licensed to the Apache Software Foundation (ASF) under one or more
      2  * contributor license agreements.  See the NOTICE file distributed with
      3  * this work for additional information regarding copyright ownership.
      4  * The ASF licenses this file to You under the Apache License, Version 2.0
      5  * (the "License"); you may not use this file except in compliance with
      6  * the License.  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 package org.apache.harmony.tests.java.nio.charset;
     17 
     18 import java.io.UnsupportedEncodingException;
     19 import java.nio.ByteBuffer;
     20 import java.nio.CharBuffer;
     21 import java.nio.charset.CharacterCodingException;
     22 import java.nio.charset.Charset;
     23 import java.nio.charset.CharsetDecoder;
     24 import java.nio.charset.CoderResult;
     25 import java.nio.charset.CodingErrorAction;
     26 import java.nio.charset.MalformedInputException;
     27 import java.nio.charset.UnmappableCharacterException;
     28 
     29 import junit.framework.TestCase;
     30 
     31 /**
     32  * API unit test for java.nio.CharsetDecoder
     33  */
     34 public class CharsetDecoderTest extends TestCase {
     35 
     36     protected static final int MAX_BYTES = 3;
     37 
     38     protected static final double AVER_BYTES = 0.5;
     39 
     40     // default charset
     41     private static final Charset MOCKCS = new CharsetEncoderTest.MockCharset(
     42             "mock", new String[0]);
     43 
     44     Charset cs = MOCKCS;
     45 
     46     // default decoder
     47     protected static CharsetDecoder decoder;
     48 
     49     String bom = "";
     50 
     51     protected void setUp() throws Exception {
     52         super.setUp();
     53         decoder = cs.newDecoder();
     54     }
     55 
     56     protected void tearDown() throws Exception {
     57         super.tearDown();
     58     }
     59 
     60     // FIXME: give up this tests
     61     // /*
     62     // * test default value
     63     // */
     64     // public void testDefaultCharsPerByte() {
     65     // assertTrue(decoder.averageCharsPerByte() == AVER_BYTES);
     66     // assertTrue(decoder.maxCharsPerByte() == MAX_BYTES);
     67     // }
     68 
     69     public void testDefaultValues() {
     70         assertSame(cs, decoder.charset());
     71         try {
     72             decoder.detectedCharset();
     73             fail("should unsupported");
     74         } catch (UnsupportedOperationException e) {
     75         }
     76         try {
     77             assertTrue(decoder.isCharsetDetected());
     78             fail("should unsupported");
     79         } catch (UnsupportedOperationException e) {
     80         }
     81         assertFalse(decoder.isAutoDetecting());
     82         assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
     83         assertSame(CodingErrorAction.REPORT, decoder
     84                 .unmappableCharacterAction());
     85         assertEquals(decoder.replacement(), "\ufffd");
     86     }
     87 
     88     /*
     89      * test constructor
     90      */
     91     public void testCharsetDecoder() {
     92         // default value
     93         decoder = new MockCharsetDecoder(cs, (float) AVER_BYTES, MAX_BYTES);
     94 
     95         // normal case
     96         CharsetDecoder ec = new MockCharsetDecoder(cs, 1, MAX_BYTES);
     97         assertSame(ec.charset(), cs);
     98         assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
     99         assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
    100 
    101         /*
    102          * ------------------------ Exceptional cases -------------------------
    103          */
    104         // Normal case: null charset
    105         ec = new MockCharsetDecoder(null, 1, MAX_BYTES);
    106         assertNull(ec.charset());
    107         assertEquals(1.0, ec.averageCharsPerByte(), 0.0);
    108         assertTrue(ec.maxCharsPerByte() == MAX_BYTES);
    109 
    110         ec = new MockCharsetDecoder(new CharsetEncoderTest.MockCharset("mock",
    111                 new String[0]), 1, MAX_BYTES);
    112 
    113         // Commented out since the comment is wrong since MAX_BYTES > 1
    114         // // OK: average length less than max length
    115         // ec = new MockCharsetDecoder(cs, MAX_BYTES, 1);
    116         // assertTrue(ec.averageCharsPerByte() == MAX_BYTES);
    117         // assertTrue(ec.maxCharsPerByte() == 1);
    118 
    119         // Illegal Argument: zero length
    120         try {
    121             ec = new MockCharsetDecoder(cs, 0, MAX_BYTES);
    122             fail("should throw IllegalArgumentException");
    123         } catch (IllegalArgumentException e) {
    124         }
    125         try {
    126             ec = new MockCharsetDecoder(cs, 1, 0);
    127             fail("should throw IllegalArgumentException");
    128         } catch (IllegalArgumentException e) {
    129         }
    130 
    131         // Illegal Argument: negative length
    132         try {
    133             ec = new MockCharsetDecoder(cs, -1, MAX_BYTES);
    134             fail("should throw IllegalArgumentException");
    135         } catch (IllegalArgumentException e) {
    136         }
    137         try {
    138             ec = new MockCharsetDecoder(cs, 1, -1);
    139             fail("should throw IllegalArgumentException");
    140         } catch (IllegalArgumentException e) {
    141         }
    142     }
    143 
    144     /*
    145      * test onMalformedInput
    146      */
    147     public void testOnMalformedInput() {
    148         assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
    149         try {
    150             decoder.onMalformedInput(null);
    151             fail("should throw null pointer exception");
    152         } catch (IllegalArgumentException e) {
    153         }
    154         decoder.onMalformedInput(CodingErrorAction.IGNORE);
    155         assertSame(CodingErrorAction.IGNORE, decoder.malformedInputAction());
    156     }
    157 
    158     /*
    159      * test unmappableCharacter
    160      */
    161     public void testOnUnmappableCharacter() {
    162         assertSame(CodingErrorAction.REPORT, decoder
    163                 .unmappableCharacterAction());
    164         try {
    165             decoder.onUnmappableCharacter(null);
    166             fail("should throw null pointer exception");
    167         } catch (IllegalArgumentException e) {
    168         }
    169         decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
    170         assertSame(CodingErrorAction.IGNORE, decoder
    171                 .unmappableCharacterAction());
    172     }
    173 
    174     /*
    175      * test replaceWith
    176      */
    177     public void testReplaceWith() {
    178         try {
    179             decoder.replaceWith(null);
    180             fail("should throw null pointer exception");
    181         } catch (IllegalArgumentException e) {
    182         }
    183         try {
    184             decoder.replaceWith("");
    185             fail("should throw null pointer exception");
    186         } catch (IllegalArgumentException e) {
    187         }
    188         try {
    189             decoder.replaceWith("testReplaceWith");
    190             fail("should throw illegal argument exception");
    191         } catch (IllegalArgumentException e) {
    192         }
    193 
    194         decoder.replaceWith("a");
    195         assertSame("a", decoder.replacement());
    196     }
    197 
    198     /*
    199      * Class under test for CharBuffer decode(ByteBuffer)
    200      */
    201     public void testDecodeByteBuffer() throws CharacterCodingException {
    202         implTestDecodeByteBuffer();
    203     }
    204 
    205     void implTestDecodeByteBuffer() throws CharacterCodingException {
    206         // Null pointer
    207         try {
    208             decoder.decode(null);
    209             fail("should throw null pointer exception");
    210         } catch (NullPointerException e) {
    211         }
    212 
    213         // empty input buffer
    214         CharBuffer out = decoder.decode(ByteBuffer.allocate(0));
    215         assertCharBufferValue("", out);
    216 
    217         // normal case
    218         ByteBuffer in = getByteBuffer();
    219         out = decoder.decode(in);
    220         assertEquals(0, out.position());
    221         assertEquals(getString().length(), out.limit());
    222         assertEquals(getString().length(), out.remaining());
    223         assertCharBufferValue(getString(), out);
    224 
    225         // normal read only case
    226         in = getByteBuffer().asReadOnlyBuffer();
    227         out = decoder.decode(in);
    228         assertEquals(out.position(), 0);
    229         assertEquals(out.limit(), getString().length());
    230         assertEquals(out.remaining(), getString().length());
    231         assertCharBufferValue(getString(), out);
    232     }
    233 
    234     public void testDecodeByteBufferException()
    235             throws CharacterCodingException, UnsupportedEncodingException {
    236         CharBuffer out;
    237         ByteBuffer in;
    238         String replaceStr = decoder.replacement() + getString();
    239 
    240         // MalformedException:
    241         decoder.onMalformedInput(CodingErrorAction.REPORT);
    242         decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    243         in = getMalformedByteBuffer();
    244         if (in != null) {
    245             try {
    246                 CharBuffer buffer = decoder.decode(in);
    247                 assertTrue(buffer.remaining() > 0);
    248                 fail("should throw MalformedInputException");
    249             } catch (MalformedInputException e) {
    250             }
    251 
    252             decoder.reset();
    253             in.rewind();
    254             decoder.onMalformedInput(CodingErrorAction.IGNORE);
    255             out = decoder.decode(in);
    256             assertCharBufferValue(getString(), out);
    257 
    258             decoder.reset();
    259             in.rewind();
    260             decoder.onMalformedInput(CodingErrorAction.REPLACE);
    261             out = decoder.decode(in);
    262             assertCharBufferValue(replaceStr, out);
    263         }
    264 
    265         // Unmapped Exception:
    266         decoder.onMalformedInput(CodingErrorAction.REPORT);
    267         decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    268         in = getUnmappedByteBuffer();
    269         if (in != null) {
    270             try {
    271                 decoder.decode(in);
    272                 fail("should throw UnmappableCharacterException");
    273             } catch (UnmappableCharacterException e) {
    274             }
    275 
    276             decoder.reset();
    277             in.rewind();
    278             decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
    279             out = decoder.decode(in);
    280             assertCharBufferValue(getString(), out);
    281 
    282             decoder.reset();
    283             in.rewind();
    284             decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
    285             out = decoder.decode(in);
    286             assertCharBufferValue(replaceStr, out);
    287         }
    288 
    289         // RuntimeException
    290         try {
    291             decoder.decode(getExceptionByteArray());
    292             fail("should throw runtime exception");
    293         } catch (RuntimeException e) {
    294         }
    295     }
    296 
    297     /*
    298      * Class under test for CoderResult decode(ByteBuffer, CharBuffer, boolean)
    299      */
    300     public void testDecodeByteBufferCharBuffer() {
    301         implTestDecodeByteBufferCharBuffer(getByteBuffer());
    302     }
    303 
    304     public void testDecodeByteBufferCharBufferReadOnly() {
    305         implTestDecodeByteBufferCharBuffer(getByteBuffer());
    306     }
    307 
    308     void implTestDecodeByteBufferCharBuffer(ByteBuffer in) {
    309         CharBuffer out = CharBuffer.allocate(100);
    310 
    311         // Null pointer
    312         decoder.reset();
    313         try {
    314             decoder.decode(null, out, true);
    315             fail("NullPointerException expected");
    316         } catch (NullPointerException e) {
    317         }
    318         try {
    319             decoder.decode(in, null, true);
    320             fail("NullPointerException expected");
    321         } catch (NullPointerException e) {
    322         }
    323 
    324         // normal case, one complete operation
    325         decoder.reset();
    326         in.rewind();
    327         out.rewind();
    328         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
    329         assertEquals(out.limit(), 100);
    330         assertEquals(out.position(), getString().length());
    331         assertEquals(out.remaining(), 100 - getString().length());
    332         assertEquals(out.capacity(), 100);
    333         assertCharBufferValue(getString(), out);
    334         decoder.flush(out);
    335 
    336         // normal case, one complete operation, but call twice, first time set
    337         // endOfInput to false
    338         decoder.reset();
    339         in.rewind();
    340         out.clear();
    341         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
    342         assertEquals(out.limit(), 100);
    343         assertEquals(out.position(), getString().length());
    344         assertEquals(out.remaining(), 100 - getString().length());
    345         assertEquals(out.capacity(), 100);
    346         assertCharBufferValue(getString(), out);
    347 
    348         decoder.reset();
    349         in.rewind();
    350         out.clear();
    351         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
    352         in = getHeadlessByteBuffer();
    353         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
    354         in.rewind();
    355         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
    356         assertEquals(out.limit(), 100);
    357         assertTrue(out.position() > 0);
    358         assertEquals(out.remaining(), out.capacity() - out.position());
    359         assertEquals(out.capacity(), 100);
    360         assertCharBufferValue(getString() + getString() + getString(), out);
    361 
    362         // overflow
    363         out = CharBuffer.allocate(4);
    364         decoder.reset();
    365         in = getByteBuffer();
    366         out.rewind();
    367         assertSame(CoderResult.OVERFLOW, decoder.decode(in, out, false));
    368 
    369         assertCharBufferValue(getString().substring(0, 4), out);
    370         out = CharBuffer.allocate(100);
    371         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
    372         assertCharBufferValue(getString().substring(4), out);
    373         in.rewind();
    374         out = CharBuffer.allocate(100);
    375         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
    376         assertCharBufferValue(bom + getString(), out);
    377     }
    378 
    379     public void testDecodeCharBufferByteBufferUnmappedException()
    380             throws CharacterCodingException, UnsupportedEncodingException {
    381         implTestDecodeCharBufferByteBufferUnmappedException(
    382                 getUnmappedByteBuffer(), true);
    383     }
    384 
    385     public void testDecodeCharBufferByteIncompleteBufferUnmappedException()
    386             throws CharacterCodingException, UnsupportedEncodingException {
    387         implTestDecodeCharBufferByteBufferUnmappedException(
    388                 getUnmappedByteBuffer(), false);
    389     }
    390 
    391     public void testDecodeCharBufferByteReadOnlyBufferUnmappedException()
    392             throws CharacterCodingException, UnsupportedEncodingException {
    393         implTestDecodeCharBufferByteBufferUnmappedException(
    394                 readOnly(getUnmappedByteBuffer()), true);
    395     }
    396 
    397     public void testDecodeCharBufferByteReadOnlyIncompleteBufferUnmappedException()
    398             throws CharacterCodingException, UnsupportedEncodingException {
    399         implTestDecodeCharBufferByteBufferUnmappedException(
    400                 readOnly(getUnmappedByteBuffer()), false);
    401     }
    402 
    403     void implTestDecodeCharBufferByteBufferUnmappedException(ByteBuffer in,
    404             boolean endOfInput) throws CharacterCodingException,
    405             UnsupportedEncodingException {
    406         if (null == in) {
    407             return;
    408         }
    409         CharBuffer out = CharBuffer.allocate(50);
    410 
    411         decoder.onMalformedInput(CodingErrorAction.REPORT);
    412         decoder.reset();
    413         decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    414         CoderResult result = decoder.decode(in, out, endOfInput);
    415         assertTrue(result.isUnmappable());
    416 
    417         decoder.reset();
    418         out.clear();
    419         in.rewind();
    420         decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
    421         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
    422         assertCharBufferValue(getString(), out);
    423 
    424         decoder.reset();
    425         out.clear();
    426         in.rewind();
    427         decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
    428         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
    429         assertCharBufferValue(decoder.replacement() + getString(), out);
    430     }
    431 
    432     public void testDecodeCharBufferByteBufferMalformedException()
    433             throws CharacterCodingException, UnsupportedEncodingException {
    434         implTestDecodeCharBufferByteBufferMalformedException(
    435                 getMalformedByteBuffer(), true);
    436     }
    437 
    438     public void testDecodeCharBufferByteIncompleteBufferMalformedException()
    439             throws CharacterCodingException, UnsupportedEncodingException {
    440 
    441         implTestDecodeCharBufferByteBufferMalformedException(
    442                 getMalformedByteBuffer(), false);
    443     }
    444 
    445     public void testDecodeCharBufferByteReadOnlyBufferMalformedException()
    446             throws CharacterCodingException, UnsupportedEncodingException {
    447         implTestDecodeCharBufferByteBufferMalformedException(
    448                 readOnly(getMalformedByteBuffer()), true);
    449     }
    450 
    451     public void testDecodeCharBufferByteReadOnlyIncompleteBufferMalformedException()
    452             throws CharacterCodingException, UnsupportedEncodingException {
    453         implTestDecodeCharBufferByteBufferMalformedException(
    454                 readOnly(getMalformedByteBuffer()), false);
    455     }
    456 
    457     void implTestDecodeCharBufferByteBufferMalformedException(ByteBuffer in,
    458             boolean endOfInput) throws CharacterCodingException,
    459             UnsupportedEncodingException {
    460         if (null == in) {
    461             return;
    462         }
    463         CharBuffer out = CharBuffer.allocate(getString().length() * 3);
    464         decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    465         decoder.reset();
    466         decoder.onMalformedInput(CodingErrorAction.REPORT);
    467         CoderResult result = decoder.decode(in, out, endOfInput);
    468         assertTrue(result.isMalformed());
    469 
    470         decoder.reset();
    471         out.clear();
    472         in.rewind();
    473         decoder.onMalformedInput(CodingErrorAction.IGNORE);
    474         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
    475         assertCharBufferValue(getString(), out);
    476 
    477         decoder.reset();
    478         out.clear();
    479         in.rewind();
    480         decoder.onMalformedInput(CodingErrorAction.REPLACE);
    481         assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
    482         assertCharBufferValue(decoder.replacement() + getString(), out);
    483     }
    484 
    485     public void testDecodeCharBufferByteBufferException()
    486             throws CharacterCodingException, UnsupportedEncodingException {
    487         implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
    488                 true);
    489     }
    490 
    491     public void testDecodeCharBufferByteIncompleteBufferException()
    492             throws CharacterCodingException, UnsupportedEncodingException {
    493         implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
    494                 false);
    495     }
    496 
    497     public void testDecodeCharBufferByteReadOnlyBufferException()
    498             throws CharacterCodingException, UnsupportedEncodingException {
    499         implTestDecodeCharBufferByteBufferException(
    500                 readOnly(getExceptionByteArray()), true);
    501     }
    502 
    503     public void testDecodeCharBufferByteReadOnlyIncompleteBufferException()
    504             throws CharacterCodingException, UnsupportedEncodingException {
    505         implTestDecodeCharBufferByteBufferException(
    506                 readOnly(getExceptionByteArray()), false);
    507     }
    508 
    509     void implTestDecodeCharBufferByteBufferException(ByteBuffer in,
    510             boolean endOfInput) throws CharacterCodingException,
    511             UnsupportedEncodingException {
    512         CharBuffer out = CharBuffer.allocate(50);
    513         decoder.reset();
    514         try {
    515             decoder.decode(in, out, endOfInput);
    516             fail("should throw runtime exception");
    517         } catch (RuntimeException e) {
    518         }
    519     }
    520 
    521     private ByteBuffer readOnly(ByteBuffer b) {
    522         if (null == b) {
    523             return null;
    524         }
    525         return b.asReadOnlyBuffer();
    526     }
    527 
    528     protected String getString() {
    529         return " buffer";
    530     }
    531 
    532     protected ByteBuffer getByteBuffer() {
    533         return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114 });
    534     }
    535 
    536     protected ByteBuffer getHeadlessByteBuffer() {
    537         return getByteBuffer();
    538     }
    539 
    540     ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
    541         // "runtime"
    542         return ByteBuffer
    543                 .wrap(new byte[] { 114, 117, 110, 116, 105, 109, 101 });
    544     }
    545 
    546     ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
    547         // "unmap buffer"
    548         byte[] ba = new byte[] { 117, 110, 109, 97, 112, 32, 98, 117, 102, 102,
    549                 101, 114 };
    550         return ByteBuffer.wrap(ba);
    551     }
    552 
    553     ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
    554         // "malform buffer"
    555         byte[] ba = new byte[] { 109, 97, 108, 102, 111, 114, 109, 32, 98, 117,
    556                 102, 102, 101, 114 };
    557         return ByteBuffer.wrap(ba);
    558     }
    559 
    560     private void assertCharBufferValue(String expected, CharBuffer out) {
    561         if (out.position() != 0) {
    562             out.flip();
    563         }
    564         assertEquals(expected, new String(out.array(), out.arrayOffset(), out
    565                 .arrayOffset() + out.limit()));
    566     }
    567 
    568     /*
    569      * test flush
    570      */
    571     public void testFlush() throws CharacterCodingException {
    572         CharBuffer out = CharBuffer.allocate(10);
    573         ByteBuffer in = ByteBuffer.wrap(new byte[] { 12, 12 });
    574         decoder.decode(in, out, true);
    575         assertSame(CoderResult.UNDERFLOW, decoder.flush(out));
    576 
    577         decoder.reset();
    578         decoder.decode((ByteBuffer) in.rewind(), (CharBuffer) out.rewind(),
    579                 true);
    580         assertSame(CoderResult.UNDERFLOW, decoder
    581                 .flush(CharBuffer.allocate(10)));
    582     }
    583 
    584     /*
    585      * ---------------------------------- methods to test illegal state
    586      * -----------------------------------
    587      */
    588     // Normal case: just after reset, and it also means reset can be done
    589     // anywhere
    590     public void testResetIllegalState() throws CharacterCodingException {
    591         decoder.reset();
    592         decoder.decode(getByteBuffer());
    593         decoder.reset();
    594         decoder.decode(getByteBuffer(), CharBuffer.allocate(3), false);
    595         decoder.reset();
    596         decoder.decode(getByteBuffer(), CharBuffer.allocate(3), true);
    597         decoder.reset();
    598     }
    599 
    600     public void testFlushIllegalState() throws CharacterCodingException {
    601         ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
    602         CharBuffer out = CharBuffer.allocate(5);
    603 
    604         // Illegal state: after reset.
    605         decoder.reset();
    606         try {
    607             decoder.flush(out);
    608             fail();
    609         } catch (IllegalStateException expected) {
    610         }
    611 
    612         // Normal case: after decode with endOfInput is true
    613         decoder.reset();
    614         decoder.decode(in, out, true);
    615         out.rewind();
    616         CoderResult result = decoder.flush(out);
    617         assertSame(result, CoderResult.UNDERFLOW);
    618 
    619         // Good state: flush twice
    620         decoder.flush(out);
    621 
    622         // Illegal state: flush after decode with endOfInput is false
    623         decoder.reset();
    624         decoder.decode(in, out, false);
    625         try {
    626             decoder.flush(out);
    627             fail();
    628         } catch (IllegalStateException expected) {
    629         }
    630     }
    631 
    632     // test illegal states for decode facade
    633     public void testDecodeFacadeIllegalState() throws CharacterCodingException {
    634         // decode facade can be execute in anywhere
    635         ByteBuffer in = getByteBuffer();
    636 
    637         // Normal case: just created
    638         decoder.decode(in);
    639         in.rewind();
    640 
    641         // Normal case: just after decode facade
    642         decoder.decode(in);
    643         in.rewind();
    644 
    645         // Normal case: just after decode with that endOfInput is true
    646         decoder.reset();
    647         decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
    648         decoder.decode(in);
    649         in.rewind();
    650 
    651         // Normal case:just after decode with that endOfInput is false
    652         decoder.reset();
    653         decoder.decode(getByteBuffer(), CharBuffer.allocate(30), false);
    654         decoder.decode(in);
    655         in.rewind();
    656 
    657         // Normal case: just after flush
    658         decoder.reset();
    659         decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
    660         decoder.flush(CharBuffer.allocate(10));
    661         decoder.decode(in);
    662         in.rewind();
    663     }
    664 
    665     // test illegal states for two decode method with endOfInput is true
    666     public void testDecodeTrueIllegalState() throws CharacterCodingException {
    667         ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
    668         CharBuffer out = CharBuffer.allocate(100);
    669         // Normal case: just created
    670         decoder.decode(in, out, true);
    671         in.rewind();
    672         out.rewind();
    673 
    674         // Normal case: just after decode with that endOfInput is true
    675         decoder.reset();
    676         decoder.decode(in, CharBuffer.allocate(30), true);
    677         in.rewind();
    678         decoder.decode(in, out, true);
    679         in.rewind();
    680         out.rewind();
    681 
    682         // Normal case:just after decode with that endOfInput is false
    683         decoder.reset();
    684         decoder.decode(in, CharBuffer.allocate(30), false);
    685         in.rewind();
    686         decoder.decode(in, out, true);
    687         in.rewind();
    688         out.rewind();
    689 
    690         // Illegal state: just after flush
    691         decoder.reset();
    692         decoder.decode(in, CharBuffer.allocate(30), true);
    693         decoder.flush(CharBuffer.allocate(10));
    694         in.rewind();
    695         try {
    696             decoder.decode(in, out, true);
    697             fail("should illegal state");
    698         } catch (IllegalStateException e) {
    699         }
    700         in.rewind();
    701         out.rewind();
    702 
    703     }
    704 
    705     // test illegal states for two decode method with endOfInput is false
    706     public void testDecodeFalseIllegalState() throws CharacterCodingException {
    707         ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
    708         CharBuffer out = CharBuffer.allocate(5);
    709         // Normal case: just created
    710         decoder.decode(in, out, false);
    711         in.rewind();
    712         out.rewind();
    713 
    714         // Illegal state: just after decode facade
    715         decoder.reset();
    716         decoder.decode(in);
    717         in.rewind();
    718         try {
    719             decoder.decode(in, out, false);
    720             fail("should illegal state");
    721         } catch (IllegalStateException e) {
    722         }
    723         in.rewind();
    724         out.rewind();
    725 
    726         // Illegal state: just after decode with that endOfInput is true
    727         decoder.reset();
    728         decoder.decode(in, CharBuffer.allocate(30), true);
    729         in.rewind();
    730         try {
    731             decoder.decode(in, out, false);
    732             fail("should illegal state");
    733         } catch (IllegalStateException e) {
    734         }
    735         in.rewind();
    736         out.rewind();
    737 
    738         // Normal case:just after decode with that endOfInput is false
    739         decoder.reset();
    740         decoder.decode(in, CharBuffer.allocate(30), false);
    741         in.rewind();
    742         decoder.decode(in, out, false);
    743         in.rewind();
    744         out.rewind();
    745 
    746         // Illegal state: just after flush
    747         decoder.reset();
    748         decoder.decode(in, CharBuffer.allocate(30), true);
    749         in.rewind();
    750         decoder.flush(CharBuffer.allocate(10));
    751         try {
    752             decoder.decode(in, out, false);
    753             fail("should illegal state");
    754         } catch (IllegalStateException e) {
    755         }
    756     }
    757 
    758     /*
    759      * --------------------------------- illegal state test end
    760      * ---------------------------------
    761      */
    762 
    763     public void testImplFlush() {
    764         decoder = new MockCharsetDecoder(cs, 1, 3);
    765         assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
    766                 .pubImplFlush(null));
    767     }
    768 
    769     public void testImplOnMalformedInput() {
    770         decoder = new MockCharsetDecoder(cs, 1, 3);
    771         assertEquals(CoderResult.UNDERFLOW, ((MockCharsetDecoder) decoder)
    772                 .pubImplFlush(null));
    773 
    774     }
    775 
    776     public void testImplOnUnmappableCharacter() {
    777         decoder = new MockCharsetDecoder(cs, 1, 3);
    778         ((MockCharsetDecoder) decoder).pubImplOnUnmappableCharacter(null);
    779     }
    780 
    781     public void testImplReplaceWith() {
    782         decoder = new MockCharsetDecoder(cs, 1, 3);
    783         ((MockCharsetDecoder) decoder).pubImplReplaceWith(null);
    784     }
    785 
    786     public void testImplReset() {
    787         decoder = new MockCharsetDecoder(cs, 1, 3);
    788         ((MockCharsetDecoder) decoder).pubImplReset();
    789     }
    790 
    791     /*
    792      * mock decoder
    793      */
    794     public static class MockCharsetDecoder extends CharsetDecoder {
    795         public MockCharsetDecoder(Charset cs, float ave, float max) {
    796             super(cs, ave, max);
    797         }
    798 
    799         protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
    800             int inPosition = in.position();
    801             byte[] input = new byte[in.remaining()];
    802             in.get(input);
    803             String result;
    804             try {
    805                 result = new String(input, "UTF-8");
    806             } catch (UnsupportedEncodingException e) {
    807                 throw new AssertionError(e);
    808             }
    809             if (result.startsWith("malform")) {
    810                 // reset the cursor to the error position
    811                 in.position(inPosition);
    812                 // set the error length
    813                 return CoderResult.malformedForLength("malform".length());
    814             } else if (result.startsWith("unmap")) {
    815                 // reset the cursor to the error position
    816                 in.position(inPosition);
    817                 // set the error length
    818                 return CoderResult.unmappableForLength("unmap".length());
    819             } else if (result.startsWith("runtime")) {
    820                 // reset the cursor to the error position
    821                 in.position(0);
    822                 // set the error length
    823                 throw new RuntimeException("runtime");
    824             }
    825             int inLeft = input.length;
    826             int outLeft = out.remaining();
    827             CoderResult r = CoderResult.UNDERFLOW;
    828             int length = inLeft;
    829             if (outLeft < inLeft) {
    830                 r = CoderResult.OVERFLOW;
    831                 length = outLeft;
    832                 in.position(inPosition + outLeft);
    833             }
    834             for (int i = 0; i < length; i++) {
    835                 out.put((char) input[i]);
    836             }
    837             return r;
    838         }
    839 
    840         protected CoderResult implFlush(CharBuffer out) {
    841             CoderResult result = super.implFlush(out);
    842             if (out.remaining() >= 5) {
    843                 // TODO
    844                 // out.put("flush");
    845                 result = CoderResult.UNDERFLOW;
    846             } else {
    847                 // out.put("flush", 0, out.remaining());
    848                 result = CoderResult.OVERFLOW;
    849             }
    850             return result;
    851         }
    852 
    853         public CoderResult pubImplFlush(CharBuffer out) {
    854             return super.implFlush(out);
    855         }
    856 
    857         public void pubImplOnMalformedInput(CodingErrorAction newAction) {
    858             super.implOnMalformedInput(newAction);
    859         }
    860 
    861         public void pubImplOnUnmappableCharacter(CodingErrorAction newAction) {
    862             super.implOnUnmappableCharacter(newAction);
    863         }
    864 
    865         public void pubImplReplaceWith(String newReplacement) {
    866             super.implReplaceWith(newReplacement);
    867         }
    868 
    869         public void pubImplReset() {
    870             super.implReset();
    871         }
    872 
    873     }
    874 
    875 }
    876