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