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 */ 16package tests.api.java.nio.charset; 17 18import java.io.UnsupportedEncodingException; 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.CoderResult; 25import java.nio.charset.CodingErrorAction; 26import java.nio.charset.MalformedInputException; 27import java.nio.charset.UnmappableCharacterException; 28 29import junit.framework.TestCase; 30 31/** 32 * API unit test for java.nio.CharsetDecoder 33 */ 34public 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