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