CharsetEncoder.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* Licensed to the Apache Software Foundation (ASF) under one or more 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.nio.charset; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.BufferOverflowException; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.BufferUnderflowException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.CharBuffer; 238454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughesimport java.util.Arrays; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A converter that can converts a 16-bit Unicode character sequence to a byte 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sequence in some charset. 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The input character sequence is wrapped by a 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link java.nio.CharBuffer CharBuffer} and the output character sequence is a 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link java.nio.ByteBuffer ByteBuffer}. An encoder instance should be used 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in the following sequence, which is referred to as a encoding operation: 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ol> 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>invoking the {@link #reset() reset} method to reset the encoder if the 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoder has been used;</li> 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>invoking the {@link #encode(CharBuffer, ByteBuffer, boolean) encode} 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method until the additional input is not needed, the <code>endOfInput</code> 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameter must be set to false, the input buffer must be filled and the 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer must be flushed between invocations;</li> 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>invoking the {@link #encode(CharBuffer, ByteBuffer, boolean) encode} 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method for the last time and the <code>endOfInput</code> parameter must be 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * set to {@code true}</li> 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>invoking the {@link #flush(ByteBuffer) flush} method to flush the 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output.</li> 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ol> 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method will 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * convert as many characters as possible, and the process won't stop until the 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input characters have run out, the output buffer has been filled or some 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * error has happened. A {@link CoderResult CoderResult} instance will be 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned to indicate the stop reason, and the invoker can identify the result 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and choose further action, which includes filling the input buffer, flushing 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer or recovering from an error and trying again. 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There are two common encoding errors. One is named malformed and it is 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned when the input content is an illegal 16-bit Unicode character 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sequence, the other is named unmappable character and occurs when there is a 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * problem mapping the input to a valid byte sequence in the specified charset. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Both errors can be handled in three ways, the default one is to report the 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * error to the invoker by a {@link CoderResult CoderResult} instance, and the 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * alternatives are to ignore it or to replace the erroneous input with the 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * replacement byte array. The replacement byte array is '{@code ?}' by 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * default and can be changed by invoking the 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #replaceWith(byte[]) replaceWith} method. The invoker of this encoder 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * can choose one way by specifying a 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link CodingErrorAction CodingErrorAction} instance for each error type via 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@link #onMalformedInput(CodingErrorAction) onMalformedInput} method and 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@link #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is abstract and encapsulates many common operations of the 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoding process for all charsets. Encoders for a specific charset should 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * extend this class and need only to implement the 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} method for basic 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoding. If a subclass maintains an internal state, it should override the 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implFlush(ByteBuffer) implFlush} method and the 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implReset() implReset} method in addition. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is not thread-safe. 81eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.charset.Charset 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.nio.charset.CharsetDecoder 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class CharsetEncoder { 86eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * internal status consts 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int INIT = 0; 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int ONGOING = 1; 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int END = 2; 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int FLUSH = 3; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the Charset which creates this encoder 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Charset cs; 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // average bytes per character created by this encoder 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private float averBytes; 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // maximum bytes per character can be created by this encoder 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private float maxBytes; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // replacement byte array 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] replace; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // internal status 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int status; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // action for malformed input 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private CodingErrorAction malformAction; 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // action for unmapped char input 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private CodingErrorAction unmapAction; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // decoder instance for this encoder's charset, used for replacement value 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // checking 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private CharsetDecoder decoder; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new <code>CharsetEncoder</code> using the given 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>Charset</code>, average number and maximum number of bytes 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * created by this encoder for one input character. 127f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cs 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the <code>Charset</code> to be used by this encoder. 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param averageBytesPerChar 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * average number of bytes created by this encoder for one input 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character, must be positive. 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param maxBytesPerChar 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * maximum number of bytes which can be created by this encoder 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for one input character, must be positive. 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if <code>maxBytesPerChar</code> or 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>averageBytesPerChar</code> is negative. 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected CharsetEncoder(Charset cs, float averageBytesPerChar, 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project float maxBytesPerChar) { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(cs, averageBytesPerChar, maxBytesPerChar, 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new byte[] { (byte) '?' }); 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new <code>CharsetEncoder</code> using the given 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>Charset</code>, replacement byte array, average number and 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * maximum number of bytes created by this encoder for one input character. 150f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cs 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the <code>Charset</code> to be used by this encoder. 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param averageBytesPerChar 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * average number of bytes created by this encoder for one single 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input character, must be positive. 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param maxBytesPerChar 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * maximum number of bytes which can be created by this encoder 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for one single input character, must be positive. 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param replacement 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the replacement byte array, cannot be null or empty, its 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * length cannot be larger than <code>maxBytesPerChar</code>, 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and must be a legal replacement, which can be justified by 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #isLegalReplacement(byte[]) isLegalReplacement}. 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any parameters are invalid. 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected CharsetEncoder(Charset cs, float averageBytesPerChar, 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project float maxBytesPerChar, byte[] replacement) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (averageBytesPerChar <= 0 || maxBytesPerChar <= 0) { 1708454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalArgumentException("averageBytesPerChar and maxBytesPerChar must both be positive"); 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (averageBytesPerChar > maxBytesPerChar) { 1738454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalArgumentException("averageBytesPerChar is greater than maxBytesPerChar"); 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.cs = cs; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project averBytes = averageBytesPerChar; 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project maxBytes = maxBytesPerChar; 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = INIT; 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project malformAction = CodingErrorAction.REPORT; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unmapAction = CodingErrorAction.REPORT; 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project replaceWith(replacement); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the average number of bytes created by this encoder for a single 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input character. 187f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the average number of bytes created by this encoder for a single 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input character. 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final float averageBytesPerChar() { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return averBytes; 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks if the given character can be encoded by this encoder. 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that this method can change the internal status of this encoder, so 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it should not be called when another encoding process is ongoing, 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise it will throw an <code>IllegalStateException</code>. 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method can be overridden for performance improvement. 203eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given encoder. 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if given character can be encoded by this encoder. 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if another encode process is ongoing so that the current 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * internal status is neither RESET or FLUSH. 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canEncode(char c) { 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return implCanEncode(CharBuffer.wrap(new char[] { c })); 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // implementation of canEncode 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean implCanEncode(CharBuffer cb) { 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status == FLUSH) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = INIT; 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status != INIT) { 2218454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalStateException("encoding already in progress"); 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CodingErrorAction malformBak = malformAction; 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CodingErrorAction unmapBak = unmapAction; 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project onMalformedInput(CodingErrorAction.REPORT); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project onUnmappableCharacter(CodingErrorAction.REPORT); 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean result = true; 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.encode(cb); 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (CharacterCodingException e) { 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = false; 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project onMalformedInput(malformBak); 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project onUnmappableCharacter(unmapBak); 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reset(); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks if a given <code>CharSequence</code> can be encoded by this 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoder. 242f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that this method can change the internal status of this encoder, so 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it should not be called when another encode process is ongoing, otherwise 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it will throw an <code>IllegalStateException</code>. 246f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method can be overridden for performance improvement. 248f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param sequence 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given <code>CharSequence</code>. 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the given <code>CharSequence</code> can be encoded by 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this encoder. 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if current internal status is neither RESET or FLUSH. 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canEncode(CharSequence sequence) { 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CharBuffer cb; 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (sequence instanceof CharBuffer) { 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cb = ((CharBuffer) sequence).duplicate(); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cb = CharBuffer.wrap(sequence); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return implCanEncode(cb); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the <code>Charset</code> which this encoder uses. 268f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the <code>Charset</code> which this encoder uses. 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Charset charset() { 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cs; 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is a facade method for the encoding operation. 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method encodes the remaining character sequence of the given 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character buffer into a new byte buffer. This method performs a complete 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoding operation, resets at first, then encodes, and flushes at last. 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method should not be invoked if another encode operation is ongoing. 283eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new <code>ByteBuffer</code> containing the bytes produced by 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this encoding operation. The buffer's limit will be the position 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the last byte in the buffer, and the position will be zero. 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if another encoding operation is ongoing. 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws MalformedInputException 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an illegal input character sequence for this charset is 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encountered, and the action for malformed error is 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT} 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnmappableCharacterException 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a legal but unmappable input character sequence for this 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * charset is encountered, and the action for unmappable 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character error is 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unmappable means the Unicode character sequence at the input 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer's current position cannot be mapped to a equivalent 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * byte sequence. 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws CharacterCodingException 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if other exception happened during the encode operation. 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final ByteBuffer encode(CharBuffer in) 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CharacterCodingException { 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (in.remaining() == 0) { 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ByteBuffer.allocate(0); 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project reset(); 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int length = (int) (in.remaining() * averBytes); 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer output = ByteBuffer.allocate(length); 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CoderResult result = null; 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = encode(in, output, false); 317eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (result==CoderResult.UNDERFLOW) { 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 319eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else if (result==CoderResult.OVERFLOW) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output = allocateMore(output); 321eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson continue; 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 323eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson checkCoderResult(result); 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = encode(in, output, true); 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkCoderResult(result); 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = flush(output); 330eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (result==CoderResult.UNDERFLOW) { 331eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson output.flip(); 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 333eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else if (result==CoderResult.OVERFLOW) { 334eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson output = allocateMore(output); 335eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson continue; 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 337eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson checkCoderResult(result); 338eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson output.flip(); 339eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (result.isMalformed()) { 340eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson throw new MalformedInputException(result.length()); 341eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else if (result.isUnmappable()) { 342eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson throw new UnmappableCharacterException(result.length()); 343eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 344eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson break; 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = FLUSH; 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return output; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * checks the result whether it needs to throw CharacterCodingException. 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkCoderResult(CoderResult result) 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws CharacterCodingException { 355eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (malformAction == CodingErrorAction.REPORT && result.isMalformed() ) { 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new MalformedInputException(result.length()); 357eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else if (unmapAction == CodingErrorAction.REPORT && result.isUnmappable()) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new UnmappableCharacterException(result.length()); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // allocate more spaces to the given ByteBuffer 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private ByteBuffer allocateMore(ByteBuffer output) { 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (output.capacity() == 0) { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ByteBuffer.allocate(1); 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer result = ByteBuffer.allocate(output.capacity() * 2); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.flip(); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.put(output); 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes characters starting at the current position of the given input 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer, and writes the equivalent byte sequence into the given output 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer from its current position. 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The buffers' position will be changed with the reading and writing 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operation, but their limits and marks will be kept intact. 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A <code>CoderResult</code> instance will be returned according to 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * following rules: 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>A {@link CoderResult#malformedForLength(int) malformed input} result 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * indicates that some malformed input error was encountered, and the 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * erroneous characters start at the input buffer's position and their 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number can be got by result's {@link CoderResult#length() length}. This 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * kind of result can be returned only if the malformed action is 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li> 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>{@link CoderResult#UNDERFLOW CoderResult.UNDERFLOW} indicates that 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as many characters as possible in the input buffer have been encoded. If 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * there is no further input and no characters left in the input buffer then 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this task is complete. If this is not the case then the client should 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * call this method again supplying some more input characters.</li> 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>{@link CoderResult#OVERFLOW CoderResult.OVERFLOW} indicates that the 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer has been filled, while there are still some characters 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * remaining in the input buffer. This method should be invoked again with a 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * non-full output buffer.</li> 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>A {@link CoderResult#unmappableForLength(int) unmappable character} 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * result indicates that some unmappable character error was encountered, 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and the erroneous characters start at the input buffer's position and 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * their number can be got by result's {@link CoderResult#length() length}. 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This kind of result can be returned only on 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li> 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The <code>endOfInput</code> parameter indicates if the invoker can 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider further input. This parameter is true if and only if the 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters in the current input buffer are all inputs for this encoding 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operation. Note that it is common and won't cause an error if the invoker 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sets false and then has no more input available, while it may cause an 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * error if the invoker always sets true in several consecutive invocations. 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This would make the remaining input to be treated as malformed input. 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input. 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method invokes the 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} method to 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implement the basic encode logic for a specific charset. 419eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param out 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param endOfInput 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * true if all the input characters have been provided. 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a <code>CoderResult</code> instance indicating the result. 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the encoding operation has already started or no more 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input is needed in this encoding process. 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws CoderMalfunctionError 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method threw an <code>BufferUnderflowException</code> or 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>BufferUnderflowException</code>. 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CoderResult encode(CharBuffer in, ByteBuffer out, 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean endOfInput) { 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((status == FLUSH) || (!endOfInput && status == END)) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException(); 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CoderResult result; 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = encodeLoop(in, out); 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BufferOverflowException e) { 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CoderMalfunctionError(e); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BufferUnderflowException e) { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new CoderMalfunctionError(e); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 450eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (result==CoderResult.UNDERFLOW) { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = endOfInput ? END : ONGOING; 452eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (endOfInput) { 453eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson int remaining = in.remaining(); 454eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson if (remaining > 0) { 455eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson result = CoderResult.malformedForLength(remaining); 456eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else { 457eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson return result; 458eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 462eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson } else if (result==CoderResult.OVERFLOW) { 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = endOfInput ? END : ONGOING; 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CodingErrorAction action = malformAction; 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result.isUnmappable()) { 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project action = unmapAction; 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the action is IGNORE or REPLACE, we should continue 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // encoding. 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (action == CodingErrorAction.REPLACE) { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (out.remaining() < replace.length) { 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.OVERFLOW; 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project out.put(replace); 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (action != CodingErrorAction.IGNORE) { 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.position(in.position() + result.length()); 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes characters into bytes. This method is called by 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encode(CharBuffer, ByteBuffer, boolean) encode}. 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method will implement the essential encoding operation, and it won't 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stop encoding until either all the input characters are read, the output 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer is filled, or some exception is encountered. Then it will 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return a <code>CoderResult</code> object indicating the result of the 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * current encoding operation. The rule to construct the 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CoderResult</code> is the same as for 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encode(CharBuffer, ByteBuffer, boolean) encode}. When an 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception is encountered in the encoding operation, most implementations 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this method will return a relevant result object to the 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method, and some 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * performance optimized implementation may handle the exception and 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implement the error action itself. 502eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * <p> 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The buffers are scanned from their current positions, and their positions 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will be modified accordingly, while their marks and limits will be 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * intact. At most {@link CharBuffer#remaining() in.remaining()} characters 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will be read, and {@link ByteBuffer#remaining() out.remaining()} bytes 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will be written. 508eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson * <p> 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that some implementations may pre-scan the input buffer and return 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CoderResult.UNDERFLOW</code> until it receives sufficient input. 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param out 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a <code>CoderResult</code> instance indicating the result. 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract CoderResult encodeLoop(CharBuffer in, ByteBuffer out); 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes this encoder. 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method will call {@link #implFlush(ByteBuffer) implFlush}. Some 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoders may need to write some bytes to the output buffer when they have 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read all input characters, subclasses can overridden 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implFlush(ByteBuffer) implFlush} to perform writing action. 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The maximum number of written bytes won't larger than 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link ByteBuffer#remaining() out.remaining()}. If some encoder wants to 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write more bytes than the output buffer's available remaining space, then 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CoderResult.OVERFLOW</code> will be returned, and this method 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * must be called again with a byte buffer that has free space. Otherwise 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this method will return <code>CoderResult.UNDERFLOW</code>, which 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * means one encoding process has been completed successfully. 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * During the flush, the output buffer's position will be changed 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * accordingly, while its mark and limit will be intact. 538f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param out 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given output buffer. 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <code>CoderResult.UNDERFLOW</code> or 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CoderResult.OVERFLOW</code>. 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this encoder hasn't read all input characters during one 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encoding process, which means neither after calling 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #encode(CharBuffer) encode(CharBuffer)} nor after 547f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * calling {@link #encode(CharBuffer, ByteBuffer, boolean) 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encode(CharBuffer, ByteBuffer, boolean)} with {@code true} 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the last boolean parameter. 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CoderResult flush(ByteBuffer out) { 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (status != END && status != INIT) { 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException(); 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CoderResult result = implFlush(out); 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == CoderResult.UNDERFLOW) { 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = FLUSH; 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes this encoder. The default implementation does nothing and always 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returns <code>CoderResult.UNDERFLOW</code>; this method can be 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * overridden if needed. 566f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param out 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <code>CoderResult.UNDERFLOW</code> or 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>CoderResult.OVERFLOW</code>. 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected CoderResult implFlush(ByteBuffer out) { 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CoderResult.UNDERFLOW; 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Notifies that this encoder's <code>CodingErrorAction</code> specified 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for malformed input error has been changed. The default implementation 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * does nothing; this method can be overridden if needed. 580f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newAction 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the new action. 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void implOnMalformedInput(CodingErrorAction newAction) { 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // default implementation is empty 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Notifies that this encoder's <code>CodingErrorAction</code> specified 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for unmappable character error has been changed. The default 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation does nothing; this method can be overridden if needed. 592f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newAction 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the new action. 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void implOnUnmappableCharacter(CodingErrorAction newAction) { 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // default implementation is empty 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Notifies that this encoder's replacement has been changed. The default 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation does nothing; this method can be overridden if needed. 603f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newReplacement 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the new replacement string. 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void implReplaceWith(byte[] newReplacement) { 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // default implementation is empty 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets this encoder's charset related state. The default implementation 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * does nothing; this method can be overridden if needed. 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void implReset() { 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // default implementation is empty 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks if the given argument is legal as this encoder's replacement byte 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * array. 622f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The given byte array is legal if and only if it can be decode into 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sixteen bits Unicode characters. 625f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method can be overridden for performance improvement. 627f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param repl 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given byte array to be checked. 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if the the given argument is legal as this encoder's 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * replacement byte array. 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isLegalReplacement(byte[] repl) { 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (decoder == null) { 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder = cs.newDecoder(); 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CodingErrorAction malform = decoder.malformedInputAction(); 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CodingErrorAction unmap = decoder.unmappableCharacterAction(); 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.onMalformedInput(CodingErrorAction.REPORT); 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.onUnmappableCharacter(CodingErrorAction.REPORT); 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteBuffer in = ByteBuffer.wrap(repl); 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CharBuffer out = CharBuffer.allocate((int) (repl.length * decoder 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .maxCharsPerByte())); 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CoderResult result = decoder.decode(in, out, true); 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.onMalformedInput(malform); 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project decoder.onUnmappableCharacter(unmap); 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !result.isError(); 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets this encoder's <code>CodingErrorAction</code> when a malformed 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input error occurred during the encoding process. 654f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder's <code>CodingErrorAction</code> when a malformed 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input error occurred during the encoding process. 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CodingErrorAction malformedInputAction() { 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return malformAction; 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the maximum number of bytes which can be created by this encoder for 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one input character, must be positive. 665f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the maximum number of bytes which can be created by this encoder 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for one input character, must be positive. 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final float maxBytesPerChar() { 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return maxBytes; 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets this encoder's action on malformed input error. 675f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method will call the 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implOnMalformedInput(CodingErrorAction) implOnMalformedInput} 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method with the given new action as argument. 679f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newAction 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the new action on malformed input error. 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder. 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given newAction is null. 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) { 6878454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes if (newAction == null) { 6888454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalArgumentException("newAction == null"); 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project malformAction = newAction; 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implOnMalformedInput(newAction); 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets this encoder's action on unmappable character error. 697f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method will call the 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implOnUnmappableCharacter(CodingErrorAction) implOnUnmappableCharacter} 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method with the given new action as argument. 701f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newAction 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the new action on unmappable character error. 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder. 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given newAction is null. 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 7088454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes public final CharsetEncoder onUnmappableCharacter(CodingErrorAction newAction) { 7098454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes if (newAction == null) { 7108454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalArgumentException("newAction == null"); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unmapAction = newAction; 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implOnUnmappableCharacter(newAction); 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets the replacement byte array, which is never null or empty. 719f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the replacement byte array, cannot be null or empty. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] replacement() { 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return replace; 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the new replacement value. 728f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method first checks the given replacement's validity, then changes 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the replacement value and finally calls the 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #implReplaceWith(byte[]) implReplaceWith} method with the given 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * new replacement as argument. 733f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param replacement 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the replacement byte array, cannot be null or empty, its 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * length cannot be larger than <code>maxBytesPerChar</code>, 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and it must be legal replacement, which can be justified by 7388454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes * calling <code>isLegalReplacement(byte[] replacement)</code>. 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder. 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given replacement cannot satisfy the requirement 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mentioned above. 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CharsetEncoder replaceWith(byte[] replacement) { 7458454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes if (replacement == null || replacement.length == 0 || maxBytes < replacement.length 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || !isLegalReplacement(replacement)) { 7478454d3c5b9778ae359d11cd98ed81c589e951d0aElliott Hughes throw new IllegalArgumentException("bad replacement: " + Arrays.toString(replacement)); 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project replace = replacement; 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implReplaceWith(replacement); 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets this encoder. This method will reset the internal status and then 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * calla <code>implReset()</code> to reset any status related to the 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specific charset. 758f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder. 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final CharsetEncoder reset() { 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project status = INIT; 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project implReset(); 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets this encoder's <code>CodingErrorAction</code> when unmappable 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character occurred during encoding process. 770f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this encoder's <code>CodingErrorAction</code> when unmappable 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character occurred during encoding process. 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CodingErrorAction unmappableCharacterAction() { 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unmapAction; 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 778