1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27// -- This file was mechanically generated: Do not edit! -- // 28 29package java.nio.charset; 30 31import java.nio.Buffer; 32import java.nio.ByteBuffer; 33import java.nio.CharBuffer; 34import java.nio.BufferOverflowException; 35import java.nio.BufferUnderflowException; 36import java.lang.ref.WeakReference; 37import java.nio.charset.CoderMalfunctionError; // javadoc 38import java.util.Arrays; 39 40 41/** 42 * An engine that can transform a sequence of sixteen-bit Unicode characters into a sequence of 43 * bytes in a specific charset. 44 * 45 * <a name="steps"></a> 46 * 47 * <p> The input character sequence is provided in a character buffer or a series 48 * of such buffers. The output byte sequence is written to a byte buffer 49 * or a series of such buffers. An encoder should always be used by making 50 * the following sequence of method invocations, hereinafter referred to as an 51 * <i>encoding operation</i>: 52 * 53 * <ol> 54 * 55 * <li><p> Reset the encoder via the {@link #reset reset} method, unless it 56 * has not been used before; </p></li> 57 * 58 * <li><p> Invoke the {@link #encode encode} method zero or more times, as 59 * long as additional input may be available, passing <tt>false</tt> for the 60 * <tt>endOfInput</tt> argument and filling the input buffer and flushing the 61 * output buffer between invocations; </p></li> 62 * 63 * <li><p> Invoke the {@link #encode encode} method one final time, passing 64 * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li> 65 * 66 * <li><p> Invoke the {@link #flush flush} method so that the encoder can 67 * flush any internal state to the output buffer. </p></li> 68 * 69 * </ol> 70 * 71 * Each invocation of the {@link #encode encode} method will encode as many 72 * characters as possible from the input buffer, writing the resulting bytes 73 * to the output buffer. The {@link #encode encode} method returns when more 74 * input is required, when there is not enough room in the output buffer, or 75 * when an encoding error has occurred. In each case a {@link CoderResult} 76 * object is returned to describe the reason for termination. An invoker can 77 * examine this object and fill the input buffer, flush the output buffer, or 78 * attempt to recover from an encoding error, as appropriate, and try again. 79 * 80 * <a name="ce"></a> 81 * 82 * <p> There are two general types of encoding errors. If the input character 83 * sequence is not a legal sixteen-bit Unicode sequence then the input is considered <i>malformed</i>. If 84 * the input character sequence is legal but cannot be mapped to a valid 85 * byte sequence in the given charset then an <i>unmappable character</i> has been encountered. 86 * 87 * <a name="cae"></a> 88 * 89 * <p> How an encoding error is handled depends upon the action requested for 90 * that type of error, which is described by an instance of the {@link 91 * CodingErrorAction} class. The possible error actions are to {@linkplain 92 * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain 93 * CodingErrorAction#REPORT report} the error to the invoker via 94 * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE 95 * replace} the erroneous input with the current value of the 96 * replacement byte array. The replacement 97 * 98 99 * is initially set to the encoder's default replacement, which often 100 * (but not always) has the initial value <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>; 101 102 103 104 105 * 106 * its value may be changed via the {@link #replaceWith(byte[]) 107 * replaceWith} method. 108 * 109 * <p> The default action for malformed-input and unmappable-character errors 110 * is to {@linkplain CodingErrorAction#REPORT report} them. The 111 * malformed-input error action may be changed via the {@link 112 * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the 113 * unmappable-character action may be changed via the {@link 114 * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method. 115 * 116 * <p> This class is designed to handle many of the details of the encoding 117 * process, including the implementation of error actions. An encoder for a 118 * specific charset, which is a concrete subclass of this class, need only 119 * implement the abstract {@link #encodeLoop encodeLoop} method, which 120 * encapsulates the basic encoding loop. A subclass that maintains internal 121 * state should, additionally, override the {@link #implFlush implFlush} and 122 * {@link #implReset implReset} methods. 123 * 124 * <p> Instances of this class are not safe for use by multiple concurrent 125 * threads. </p> 126 * 127 * 128 * @author Mark Reinhold 129 * @author JSR-51 Expert Group 130 * @since 1.4 131 * 132 * @see ByteBuffer 133 * @see CharBuffer 134 * @see Charset 135 * @see CharsetDecoder 136 */ 137 138public abstract class CharsetEncoder { 139 140 private final Charset charset; 141 private final float averageBytesPerChar; 142 private final float maxBytesPerChar; 143 144 private byte[] replacement; 145 private CodingErrorAction malformedInputAction 146 = CodingErrorAction.REPORT; 147 private CodingErrorAction unmappableCharacterAction 148 = CodingErrorAction.REPORT; 149 150 // Internal states 151 // 152 private static final int ST_RESET = 0; 153 private static final int ST_CODING = 1; 154 private static final int ST_END = 2; 155 private static final int ST_FLUSHED = 3; 156 157 private int state = ST_RESET; 158 159 private static String stateNames[] 160 = { "RESET", "CODING", "CODING_END", "FLUSHED" }; 161 162 163 /** 164 * Initializes a new encoder. The new encoder will have the given 165 * bytes-per-char and replacement values. 166 * 167 * @param cs 168 * The charset that created this encoder 169 * 170 * @param averageBytesPerChar 171 * A positive float value indicating the expected number of 172 * bytes that will be produced for each input character 173 * 174 * @param maxBytesPerChar 175 * A positive float value indicating the maximum number of 176 * bytes that will be produced for each input character 177 * 178 * @param replacement 179 * The initial replacement; must not be <tt>null</tt>, must have 180 * non-zero length, must not be longer than maxBytesPerChar, 181 * and must be {@linkplain #isLegalReplacement legal} 182 * 183 * @throws IllegalArgumentException 184 * If the preconditions on the parameters do not hold 185 */ 186 protected 187 CharsetEncoder(Charset cs, 188 float averageBytesPerChar, 189 float maxBytesPerChar, 190 byte[] replacement) 191 { 192 // BEGIN Android-added: A hidden constructor for the CharsetEncoderICU subclass. 193 this(cs, averageBytesPerChar, maxBytesPerChar, replacement, false); 194 } 195 196 /** 197 * This constructor is for subclasses to specify whether {@code replacement} can be used as it 198 * is ("trusted"). If it is trusted, {@link #replaceWith(byte[])} and 199 * {@link #implReplaceWith(byte[])} will not be called. 200 */ 201 CharsetEncoder(Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement, 202 boolean trusted) 203 { 204 // END Android-added: A hidden constructor for the CharsetEncoderICU subclass. 205 this.charset = cs; 206 if (averageBytesPerChar <= 0.0f) 207 throw new IllegalArgumentException("Non-positive " 208 + "averageBytesPerChar"); 209 if (maxBytesPerChar <= 0.0f) 210 throw new IllegalArgumentException("Non-positive " 211 + "maxBytesPerChar"); 212 if (!Charset.atBugLevel("1.4")) { 213 if (averageBytesPerChar > maxBytesPerChar) 214 throw new IllegalArgumentException("averageBytesPerChar" 215 + " exceeds " 216 + "maxBytesPerChar"); 217 } 218 this.replacement = replacement; 219 this.averageBytesPerChar = averageBytesPerChar; 220 this.maxBytesPerChar = maxBytesPerChar; 221 // BEGIN Android-changed: Avoid calling replaceWith() for trusted subclasses. 222 // replaceWith(replacement); 223 if (!trusted) { 224 replaceWith(replacement); 225 } 226 // END Android-changed: Avoid calling replaceWith() for trusted subclasses. 227 } 228 229 /** 230 * Initializes a new encoder. The new encoder will have the given 231 * bytes-per-char values and its replacement will be the 232 * byte array <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>. 233 * 234 * @param cs 235 * The charset that created this encoder 236 * 237 * @param averageBytesPerChar 238 * A positive float value indicating the expected number of 239 * bytes that will be produced for each input character 240 * 241 * @param maxBytesPerChar 242 * A positive float value indicating the maximum number of 243 * bytes that will be produced for each input character 244 * 245 * @throws IllegalArgumentException 246 * If the preconditions on the parameters do not hold 247 */ 248 protected CharsetEncoder(Charset cs, 249 float averageBytesPerChar, 250 float maxBytesPerChar) 251 { 252 this(cs, 253 averageBytesPerChar, maxBytesPerChar, 254 new byte[] { (byte)'?' }); 255 } 256 257 /** 258 * Returns the charset that created this encoder. 259 * 260 * @return This encoder's charset 261 */ 262 public final Charset charset() { 263 return charset; 264 } 265 266 /** 267 * Returns this encoder's replacement value. 268 * 269 * @return This encoder's current replacement, 270 * which is never <tt>null</tt> and is never empty 271 */ 272 public final byte[] replacement() { 273 274 275 276 277 return Arrays.copyOf(replacement, replacement.length); 278 279 } 280 281 /** 282 * Changes this encoder's replacement value. 283 * 284 * <p> This method invokes the {@link #implReplaceWith implReplaceWith} 285 * method, passing the new replacement, after checking that the new 286 * replacement is acceptable. </p> 287 * 288 * @param newReplacement The replacement value 289 * 290 291 292 293 294 295 * The new replacement; must not be <tt>null</tt>, must have 296 * non-zero length, must not be longer than the value returned by 297 * the {@link #maxBytesPerChar() maxBytesPerChar} method, and 298 * must be {@link #isLegalReplacement legal} 299 300 * 301 * @return This encoder 302 * 303 * @throws IllegalArgumentException 304 * If the preconditions on the parameter do not hold 305 */ 306 public final CharsetEncoder replaceWith(byte[] newReplacement) { 307 if (newReplacement == null) 308 throw new IllegalArgumentException("Null replacement"); 309 int len = newReplacement.length; 310 if (len == 0) 311 throw new IllegalArgumentException("Empty replacement"); 312 if (len > maxBytesPerChar) 313 throw new IllegalArgumentException("Replacement too long"); 314 315 316 317 318 if (!isLegalReplacement(newReplacement)) 319 throw new IllegalArgumentException("Illegal replacement"); 320 this.replacement = Arrays.copyOf(newReplacement, newReplacement.length); 321 322 implReplaceWith(this.replacement); 323 return this; 324 } 325 326 /** 327 * Reports a change to this encoder's replacement value. 328 * 329 * <p> The default implementation of this method does nothing. This method 330 * should be overridden by encoders that require notification of changes to 331 * the replacement. </p> 332 * 333 * @param newReplacement The replacement value 334 */ 335 protected void implReplaceWith(byte[] newReplacement) { 336 } 337 338 339 340 private WeakReference<CharsetDecoder> cachedDecoder = null; 341 342 /** 343 * Tells whether or not the given byte array is a legal replacement value 344 * for this encoder. 345 * 346 * <p> A replacement is legal if, and only if, it is a legal sequence of 347 * bytes in this encoder's charset; that is, it must be possible to decode 348 * the replacement into one or more sixteen-bit Unicode characters. 349 * 350 * <p> The default implementation of this method is not very efficient; it 351 * should generally be overridden to improve performance. </p> 352 * 353 * @param repl The byte array to be tested 354 * 355 * @return <tt>true</tt> if, and only if, the given byte array 356 * is a legal replacement value for this encoder 357 */ 358 public boolean isLegalReplacement(byte[] repl) { 359 WeakReference<CharsetDecoder> wr = cachedDecoder; 360 CharsetDecoder dec = null; 361 if ((wr == null) || ((dec = wr.get()) == null)) { 362 dec = charset().newDecoder(); 363 dec.onMalformedInput(CodingErrorAction.REPORT); 364 dec.onUnmappableCharacter(CodingErrorAction.REPORT); 365 cachedDecoder = new WeakReference<CharsetDecoder>(dec); 366 } else { 367 dec.reset(); 368 } 369 ByteBuffer bb = ByteBuffer.wrap(repl); 370 CharBuffer cb = CharBuffer.allocate((int)(bb.remaining() 371 * dec.maxCharsPerByte())); 372 CoderResult cr = dec.decode(bb, cb, true); 373 return !cr.isError(); 374 } 375 376 377 378 /** 379 * Returns this encoder's current action for malformed-input errors. 380 * 381 * @return The current malformed-input action, which is never <tt>null</tt> 382 */ 383 public CodingErrorAction malformedInputAction() { 384 return malformedInputAction; 385 } 386 387 /** 388 * Changes this encoder's action for malformed-input errors. 389 * 390 * <p> This method invokes the {@link #implOnMalformedInput 391 * implOnMalformedInput} method, passing the new action. </p> 392 * 393 * @param newAction The new action; must not be <tt>null</tt> 394 * 395 * @return This encoder 396 * 397 * @throws IllegalArgumentException 398 * If the precondition on the parameter does not hold 399 */ 400 public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) { 401 if (newAction == null) 402 throw new IllegalArgumentException("Null action"); 403 malformedInputAction = newAction; 404 implOnMalformedInput(newAction); 405 return this; 406 } 407 408 /** 409 * Reports a change to this encoder's malformed-input action. 410 * 411 * <p> The default implementation of this method does nothing. This method 412 * should be overridden by encoders that require notification of changes to 413 * the malformed-input action. </p> 414 * 415 * @param newAction The new action 416 */ 417 protected void implOnMalformedInput(CodingErrorAction newAction) { } 418 419 /** 420 * Returns this encoder's current action for unmappable-character errors. 421 * 422 * @return The current unmappable-character action, which is never 423 * <tt>null</tt> 424 */ 425 public CodingErrorAction unmappableCharacterAction() { 426 return unmappableCharacterAction; 427 } 428 429 /** 430 * Changes this encoder's action for unmappable-character errors. 431 * 432 * <p> This method invokes the {@link #implOnUnmappableCharacter 433 * implOnUnmappableCharacter} method, passing the new action. </p> 434 * 435 * @param newAction The new action; must not be <tt>null</tt> 436 * 437 * @return This encoder 438 * 439 * @throws IllegalArgumentException 440 * If the precondition on the parameter does not hold 441 */ 442 public final CharsetEncoder onUnmappableCharacter(CodingErrorAction 443 newAction) 444 { 445 if (newAction == null) 446 throw new IllegalArgumentException("Null action"); 447 unmappableCharacterAction = newAction; 448 implOnUnmappableCharacter(newAction); 449 return this; 450 } 451 452 /** 453 * Reports a change to this encoder's unmappable-character action. 454 * 455 * <p> The default implementation of this method does nothing. This method 456 * should be overridden by encoders that require notification of changes to 457 * the unmappable-character action. </p> 458 * 459 * @param newAction The new action 460 */ 461 protected void implOnUnmappableCharacter(CodingErrorAction newAction) { } 462 463 /** 464 * Returns the average number of bytes that will be produced for each 465 * character of input. This heuristic value may be used to estimate the size 466 * of the output buffer required for a given input sequence. 467 * 468 * @return The average number of bytes produced 469 * per character of input 470 */ 471 public final float averageBytesPerChar() { 472 return averageBytesPerChar; 473 } 474 475 /** 476 * Returns the maximum number of bytes that will be produced for each 477 * character of input. This value may be used to compute the worst-case size 478 * of the output buffer required for a given input sequence. 479 * 480 * @return The maximum number of bytes that will be produced per 481 * character of input 482 */ 483 public final float maxBytesPerChar() { 484 return maxBytesPerChar; 485 } 486 487 /** 488 * Encodes as many characters as possible from the given input buffer, 489 * writing the results to the given output buffer. 490 * 491 * <p> The buffers are read from, and written to, starting at their current 492 * positions. At most {@link Buffer#remaining in.remaining()} characters 493 * will be read and at most {@link Buffer#remaining out.remaining()} 494 * bytes will be written. The buffers' positions will be advanced to 495 * reflect the characters read and the bytes written, but their marks and 496 * limits will not be modified. 497 * 498 * <p> In addition to reading characters from the input buffer and writing 499 * bytes to the output buffer, this method returns a {@link CoderResult} 500 * object to describe its reason for termination: 501 * 502 * <ul> 503 * 504 * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the 505 * input buffer as possible has been encoded. If there is no further 506 * input then the invoker can proceed to the next step of the 507 * <a href="#steps">encoding operation</a>. Otherwise this method 508 * should be invoked again with further input. </p></li> 509 * 510 * <li><p> {@link CoderResult#OVERFLOW} indicates that there is 511 * insufficient space in the output buffer to encode any more characters. 512 * This method should be invoked again with an output buffer that has 513 * more {@linkplain Buffer#remaining remaining} bytes. This is 514 * typically done by draining any encoded bytes from the output 515 * buffer. </p></li> 516 * 517 * <li><p> A {@linkplain CoderResult#malformedForLength 518 * malformed-input} result indicates that a malformed-input 519 * error has been detected. The malformed characters begin at the input 520 * buffer's (possibly incremented) position; the number of malformed 521 * characters may be determined by invoking the result object's {@link 522 * CoderResult#length() length} method. This case applies only if the 523 * {@linkplain #onMalformedInput malformed action} of this encoder 524 * is {@link CodingErrorAction#REPORT}; otherwise the malformed input 525 * will be ignored or replaced, as requested. </p></li> 526 * 527 * <li><p> An {@linkplain CoderResult#unmappableForLength 528 * unmappable-character} result indicates that an 529 * unmappable-character error has been detected. The characters that 530 * encode the unmappable character begin at the input buffer's (possibly 531 * incremented) position; the number of such characters may be determined 532 * by invoking the result object's {@link CoderResult#length() length} 533 * method. This case applies only if the {@linkplain #onUnmappableCharacter 534 * unmappable action} of this encoder is {@link 535 * CodingErrorAction#REPORT}; otherwise the unmappable character will be 536 * ignored or replaced, as requested. </p></li> 537 * 538 * </ul> 539 * 540 * In any case, if this method is to be reinvoked in the same encoding 541 * operation then care should be taken to preserve any characters remaining 542 * in the input buffer so that they are available to the next invocation. 543 * 544 * <p> The <tt>endOfInput</tt> parameter advises this method as to whether 545 * the invoker can provide further input beyond that contained in the given 546 * input buffer. If there is a possibility of providing additional input 547 * then the invoker should pass <tt>false</tt> for this parameter; if there 548 * is no possibility of providing further input then the invoker should 549 * pass <tt>true</tt>. It is not erroneous, and in fact it is quite 550 * common, to pass <tt>false</tt> in one invocation and later discover that 551 * no further input was actually available. It is critical, however, that 552 * the final invocation of this method in a sequence of invocations always 553 * pass <tt>true</tt> so that any remaining unencoded input will be treated 554 * as being malformed. 555 * 556 * <p> This method works by invoking the {@link #encodeLoop encodeLoop} 557 * method, interpreting its results, handling error conditions, and 558 * reinvoking it as necessary. </p> 559 * 560 * 561 * @param in 562 * The input character buffer 563 * 564 * @param out 565 * The output byte buffer 566 * 567 * @param endOfInput 568 * <tt>true</tt> if, and only if, the invoker can provide no 569 * additional input characters beyond those in the given buffer 570 * 571 * @return A coder-result object describing the reason for termination 572 * 573 * @throws IllegalStateException 574 * If an encoding operation is already in progress and the previous 575 * step was an invocation neither of the {@link #reset reset} 576 * method, nor of this method with a value of <tt>false</tt> for 577 * the <tt>endOfInput</tt> parameter, nor of this method with a 578 * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter 579 * but a return value indicating an incomplete encoding operation 580 * 581 * @throws CoderMalfunctionError 582 * If an invocation of the encodeLoop method threw 583 * an unexpected exception 584 */ 585 public final CoderResult encode(CharBuffer in, ByteBuffer out, 586 boolean endOfInput) 587 { 588 int newState = endOfInput ? ST_END : ST_CODING; 589 if ((state != ST_RESET) && (state != ST_CODING) 590 && !(endOfInput && (state == ST_END))) 591 throwIllegalStateException(state, newState); 592 state = newState; 593 594 for (;;) { 595 596 CoderResult cr; 597 try { 598 cr = encodeLoop(in, out); 599 } catch (BufferUnderflowException x) { 600 throw new CoderMalfunctionError(x); 601 } catch (BufferOverflowException x) { 602 throw new CoderMalfunctionError(x); 603 } 604 605 if (cr.isOverflow()) 606 return cr; 607 608 if (cr.isUnderflow()) { 609 if (endOfInput && in.hasRemaining()) { 610 cr = CoderResult.malformedForLength(in.remaining()); 611 // Fall through to malformed-input case 612 } else { 613 return cr; 614 } 615 } 616 617 CodingErrorAction action = null; 618 if (cr.isMalformed()) 619 action = malformedInputAction; 620 else if (cr.isUnmappable()) 621 action = unmappableCharacterAction; 622 else 623 assert false : cr.toString(); 624 625 if (action == CodingErrorAction.REPORT) 626 return cr; 627 628 if (action == CodingErrorAction.REPLACE) { 629 if (out.remaining() < replacement.length) 630 return CoderResult.OVERFLOW; 631 out.put(replacement); 632 } 633 634 if ((action == CodingErrorAction.IGNORE) 635 || (action == CodingErrorAction.REPLACE)) { 636 // Skip erroneous input either way 637 in.position(in.position() + cr.length()); 638 continue; 639 } 640 641 assert false; 642 } 643 644 } 645 646 /** 647 * Flushes this encoder. 648 * 649 * <p> Some encoders maintain internal state and may need to write some 650 * final bytes to the output buffer once the overall input sequence has 651 * been read. 652 * 653 * <p> Any additional output is written to the output buffer beginning at 654 * its current position. At most {@link Buffer#remaining out.remaining()} 655 * bytes will be written. The buffer's position will be advanced 656 * appropriately, but its mark and limit will not be modified. 657 * 658 * <p> If this method completes successfully then it returns {@link 659 * CoderResult#UNDERFLOW}. If there is insufficient room in the output 660 * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens 661 * then this method must be invoked again, with an output buffer that has 662 * more room, in order to complete the current <a href="#steps">encoding 663 * operation</a>. 664 * 665 * <p> If this encoder has already been flushed then invoking this method 666 * has no effect. 667 * 668 * <p> This method invokes the {@link #implFlush implFlush} method to 669 * perform the actual flushing operation. </p> 670 * 671 * @param out 672 * The output byte buffer 673 * 674 * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or 675 * {@link CoderResult#OVERFLOW} 676 * 677 * @throws IllegalStateException 678 * If the previous step of the current encoding operation was an 679 * invocation neither of the {@link #flush flush} method nor of 680 * the three-argument {@link 681 * #encode(CharBuffer,ByteBuffer,boolean) encode} method 682 * with a value of <tt>true</tt> for the <tt>endOfInput</tt> 683 * parameter 684 */ 685 public final CoderResult flush(ByteBuffer out) { 686 if (state == ST_END) { 687 CoderResult cr = implFlush(out); 688 if (cr.isUnderflow()) 689 state = ST_FLUSHED; 690 return cr; 691 } 692 693 if (state != ST_FLUSHED) 694 throwIllegalStateException(state, ST_FLUSHED); 695 696 return CoderResult.UNDERFLOW; // Already flushed 697 } 698 699 /** 700 * Flushes this encoder. 701 * 702 * <p> The default implementation of this method does nothing, and always 703 * returns {@link CoderResult#UNDERFLOW}. This method should be overridden 704 * by encoders that may need to write final bytes to the output buffer 705 * once the entire input sequence has been read. </p> 706 * 707 * @param out 708 * The output byte buffer 709 * 710 * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or 711 * {@link CoderResult#OVERFLOW} 712 */ 713 protected CoderResult implFlush(ByteBuffer out) { 714 return CoderResult.UNDERFLOW; 715 } 716 717 /** 718 * Resets this encoder, clearing any internal state. 719 * 720 * <p> This method resets charset-independent state and also invokes the 721 * {@link #implReset() implReset} method in order to perform any 722 * charset-specific reset actions. </p> 723 * 724 * @return This encoder 725 * 726 */ 727 public final CharsetEncoder reset() { 728 implReset(); 729 state = ST_RESET; 730 return this; 731 } 732 733 /** 734 * Resets this encoder, clearing any charset-specific internal state. 735 * 736 * <p> The default implementation of this method does nothing. This method 737 * should be overridden by encoders that maintain internal state. </p> 738 */ 739 protected void implReset() { } 740 741 /** 742 * Encodes one or more characters into one or more bytes. 743 * 744 * <p> This method encapsulates the basic encoding loop, encoding as many 745 * characters as possible until it either runs out of input, runs out of room 746 * in the output buffer, or encounters an encoding error. This method is 747 * invoked by the {@link #encode encode} method, which handles result 748 * interpretation and error recovery. 749 * 750 * <p> The buffers are read from, and written to, starting at their current 751 * positions. At most {@link Buffer#remaining in.remaining()} characters 752 * will be read, and at most {@link Buffer#remaining out.remaining()} 753 * bytes will be written. The buffers' positions will be advanced to 754 * reflect the characters read and the bytes written, but their marks and 755 * limits will not be modified. 756 * 757 * <p> This method returns a {@link CoderResult} object to describe its 758 * reason for termination, in the same manner as the {@link #encode encode} 759 * method. Most implementations of this method will handle encoding errors 760 * by returning an appropriate result object for interpretation by the 761 * {@link #encode encode} method. An optimized implementation may instead 762 * examine the relevant error action and implement that action itself. 763 * 764 * <p> An implementation of this method may perform arbitrary lookahead by 765 * returning {@link CoderResult#UNDERFLOW} until it receives sufficient 766 * input. </p> 767 * 768 * @param in 769 * The input character buffer 770 * 771 * @param out 772 * The output byte buffer 773 * 774 * @return A coder-result object describing the reason for termination 775 */ 776 protected abstract CoderResult encodeLoop(CharBuffer in, 777 ByteBuffer out); 778 779 /** 780 * Convenience method that encodes the remaining content of a single input 781 * character buffer into a newly-allocated byte buffer. 782 * 783 * <p> This method implements an entire <a href="#steps">encoding 784 * operation</a>; that is, it resets this encoder, then it encodes the 785 * characters in the given character buffer, and finally it flushes this 786 * encoder. This method should therefore not be invoked if an encoding 787 * operation is already in progress. </p> 788 * 789 * @param in 790 * The input character buffer 791 * 792 * @return A newly-allocated byte buffer containing the result of the 793 * encoding operation. The buffer's position will be zero and its 794 * limit will follow the last byte written. 795 * 796 * @throws IllegalStateException 797 * If an encoding operation is already in progress 798 * 799 * @throws MalformedInputException 800 * If the character sequence starting at the input buffer's current 801 * position is not a legal sixteen-bit Unicode sequence and the current malformed-input action 802 * is {@link CodingErrorAction#REPORT} 803 * 804 * @throws UnmappableCharacterException 805 * If the character sequence starting at the input buffer's current 806 * position cannot be mapped to an equivalent byte sequence and 807 * the current unmappable-character action is {@link 808 * CodingErrorAction#REPORT} 809 */ 810 public final ByteBuffer encode(CharBuffer in) 811 throws CharacterCodingException 812 { 813 int n = (int)(in.remaining() * averageBytesPerChar()); 814 ByteBuffer out = ByteBuffer.allocate(n); 815 816 if ((n == 0) && (in.remaining() == 0)) 817 return out; 818 reset(); 819 for (;;) { 820 CoderResult cr = in.hasRemaining() ? 821 encode(in, out, true) : CoderResult.UNDERFLOW; 822 if (cr.isUnderflow()) 823 cr = flush(out); 824 825 if (cr.isUnderflow()) 826 break; 827 if (cr.isOverflow()) { 828 n = 2*n + 1; // Ensure progress; n might be 0! 829 ByteBuffer o = ByteBuffer.allocate(n); 830 out.flip(); 831 o.put(out); 832 out = o; 833 continue; 834 } 835 cr.throwException(); 836 } 837 out.flip(); 838 return out; 839 } 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 private boolean canEncode(CharBuffer cb) { 920 if (state == ST_FLUSHED) 921 reset(); 922 else if (state != ST_RESET) 923 throwIllegalStateException(state, ST_CODING); 924 925 // BEGIN Android-added: Fast path handling for empty buffers. 926 // Empty buffers can always be "encoded". 927 if (!cb.hasRemaining()) { 928 return true; 929 } 930 // END Android-added: Fast path handling for empty buffers. 931 932 CodingErrorAction ma = malformedInputAction(); 933 CodingErrorAction ua = unmappableCharacterAction(); 934 try { 935 onMalformedInput(CodingErrorAction.REPORT); 936 onUnmappableCharacter(CodingErrorAction.REPORT); 937 encode(cb); 938 } catch (CharacterCodingException x) { 939 return false; 940 } finally { 941 onMalformedInput(ma); 942 onUnmappableCharacter(ua); 943 reset(); 944 } 945 return true; 946 } 947 948 /** 949 * Tells whether or not this encoder can encode the given character. 950 * 951 * <p> This method returns <tt>false</tt> if the given character is a 952 * surrogate character; such characters can be interpreted only when they 953 * are members of a pair consisting of a high surrogate followed by a low 954 * surrogate. The {@link #canEncode(java.lang.CharSequence) 955 * canEncode(CharSequence)} method may be used to test whether or not a 956 * character sequence can be encoded. 957 * 958 * <p> This method may modify this encoder's state; it should therefore not 959 * be invoked if an <a href="#steps">encoding operation</a> is already in 960 * progress. 961 * 962 * <p> The default implementation of this method is not very efficient; it 963 * should generally be overridden to improve performance. </p> 964 * 965 * @param c 966 * The given character 967 * 968 * @return <tt>true</tt> if, and only if, this encoder can encode 969 * the given character 970 * 971 * @throws IllegalStateException 972 * If an encoding operation is already in progress 973 */ 974 public boolean canEncode(char c) { 975 CharBuffer cb = CharBuffer.allocate(1); 976 cb.put(c); 977 cb.flip(); 978 return canEncode(cb); 979 } 980 981 /** 982 * Tells whether or not this encoder can encode the given character 983 * sequence. 984 * 985 * <p> If this method returns <tt>false</tt> for a particular character 986 * sequence then more information about why the sequence cannot be encoded 987 * may be obtained by performing a full <a href="#steps">encoding 988 * operation</a>. 989 * 990 * <p> This method may modify this encoder's state; it should therefore not 991 * be invoked if an encoding operation is already in progress. 992 * 993 * <p> The default implementation of this method is not very efficient; it 994 * should generally be overridden to improve performance. </p> 995 * 996 * @param cs 997 * The given character sequence 998 * 999 * @return <tt>true</tt> if, and only if, this encoder can encode 1000 * the given character without throwing any exceptions and without 1001 * performing any replacements 1002 * 1003 * @throws IllegalStateException 1004 * If an encoding operation is already in progress 1005 */ 1006 public boolean canEncode(CharSequence cs) { 1007 CharBuffer cb; 1008 if (cs instanceof CharBuffer) 1009 cb = ((CharBuffer)cs).duplicate(); 1010 else 1011 // Android-removed: An unnecessary call to toString(). 1012 // cb = CharBuffer.wrap(cs.toString()); 1013 cb = CharBuffer.wrap(cs); 1014 return canEncode(cb); 1015 } 1016 1017 1018 1019 1020 private void throwIllegalStateException(int from, int to) { 1021 throw new IllegalStateException("Current state = " + stateNames[from] 1022 + ", new state = " + stateNames[to]); 1023 } 1024 1025} 1026