/*
 * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.nio.cs.ext;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import sun.nio.cs.HistoricallyNamedCharset;
import sun.nio.cs.Surrogate;
import sun.nio.cs.US_ASCII;

/*
 * Implementation notes:
 *
 * (1)"Standard based" (ASCII, JIS_X_0201 and JIS_X_0208) ISO2022-JP charset
 * is provided by the base implementation of this class.
 *
 * Three Microsoft ISO2022-JP variants, MS50220, MS50221 and MSISO2022JP
 * are provided via subclasses.
 *
 * (2)MS50220 and MS50221 are assumed to work the same way as Microsoft
 * CP50220 and CP50221's 7-bit implementation works by using CP5022X
 * specific JIS0208 and JIS0212 mapping tables (generated via Microsoft's
 * MultiByteToWideChar/WideCharToMultiByte APIs). The only difference
 * between these 2 classes is that MS50220 does not support singlebyte
 * halfwidth kana (Uff61-Uff9f) shiftin mechanism when "encoding", instead
 * these halfwidth kana characters are converted to their fullwidth JIS0208
 * counterparts.
 *
 * The difference between the standard JIS_X_0208 and JIS_X_0212 mappings
 * and the CP50220/50221 specific are
 *
 * 0208 mapping:
 *              1)0x213d <-> U2015 (compared to U2014)
 *              2)One way mappings for 5 characters below
 *                u2225 (ms) -> 0x2142 <-> u2016 (jis)
 *                uff0d (ms) -> 0x215d <-> u2212 (jis)
 *                uffe0 (ms) -> 0x2171 <-> u00a2 (jis)
 *                uffe1 (ms) -> 0x2172 <-> u00a3 (jis)
 *                uffe2 (ms) -> 0x224c <-> u00ac (jis)
 *                //should consider 0xff5e -> 0x2141 <-> U301c?
 *              3)NEC Row13 0x2d21-0x2d79
 *              4)85-94 ku <-> UE000,UE3AB (includes NEC selected
 *                IBM kanji in 89-92ku)
 *              5)UFF61-UFF9f -> Fullwidth 0208 KANA
 *
 * 0212 mapping:
 *              1)0x2237 <-> UFF5E (Fullwidth Tilde)
 *              2)0x2271 <-> U2116 (Numero Sign)
 *              3)85-94 ku <-> UE3AC - UE757
 *
 * (3)MSISO2022JP uses a JIS0208 mapping generated from MS932DB.b2c
 * and MS932DB.c2b by converting the SJIS codepoints back to their
 * JIS0208 counterparts. With the exception of
 *
 * (a)Codepoints with a resulting JIS0208 codepoints beyond 0x7e00 are
 *    dropped (this includs the IBM Extended Kanji/Non-kanji from 0x9321
 *    to 0x972c)
 * (b)The Unicode codepoints that the IBM Extended Kanji/Non-kanji are
 *    mapped to (in MS932) are mapped back to NEC selected IBM Kanji/
 *    Non-kanji area at 0x7921-0x7c7e.
 *
 * Compared to JIS_X_0208 mapping, this MS932 based mapping has

 * (a)different mappings for 7 JIS codepoints
 *        0x213d <-> U2015
 *        0x2141 <-> UFF5E
 *        0x2142 <-> U2225
 *        0x215d <-> Uff0d
 *        0x2171 <-> Uffe0
 *        0x2172 <-> Uffe1
 *        0x224c <-> Uffe2
 * (b)added one-way c2b mappings for
 *        U00b8 -> 0x2124
 *        U00b7 -> 0x2126
 *        U00af -> 0x2131
 *        U00ab -> 0x2263
 *        U00bb -> 0x2264
 *        U3094 -> 0x2574
 *        U00b5 -> 0x264c
 * (c)NEC Row 13
 * (d)NEC selected IBM extended Kanji/Non-kanji
 *    These codepoints are mapped to the same Unicode codepoints as
 *    the MS932 does, while MS50220/50221 maps them to the Unicode
 *    private area.
 *
 * # There is also an interesting difference when compared to MS5022X
 *   0208 mapping for JIS codepoint "0x2D60", MS932 maps it to U301d
 *   but MS5022X maps it to U301e, obvious MS5022X is wrong, but...
 */

public class ISO2022_JP
    extends Charset
    implements HistoricallyNamedCharset
{
    private static final int ASCII = 0;                 // ESC ( B
    private static final int JISX0201_1976 = 1;         // ESC ( J
    private static final int JISX0208_1978 = 2;         // ESC $ @
    private static final int JISX0208_1983 = 3;         // ESC $ B
    private static final int JISX0212_1990 = 4;         // ESC $ ( D
    private static final int JISX0201_1976_KANA = 5;    // ESC ( I
    private static final int SHIFTOUT = 6;

    private static final int ESC = 0x1b;
    private static final int SO = 0x0e;
    private static final int SI = 0x0f;

    public ISO2022_JP() {
        super("ISO-2022-JP",
              ExtendedCharsets.aliasesFor("ISO-2022-JP"));
    }

    protected ISO2022_JP(String canonicalName,
                         String[] aliases) {
        super(canonicalName, aliases);
    }

    public String historicalName() {
        return "ISO2022JP";
    }

    public boolean contains(Charset cs) {
        return ((cs instanceof JIS_X_0201)
                || (cs instanceof US_ASCII)
                || (cs instanceof JIS_X_0208)
                || (cs instanceof ISO2022_JP));
    }

    public CharsetDecoder newDecoder() {
        return new Decoder(this,
                           getDecIndex1(),
                           getDecIndex2(),
                           get0212Decoder());
    }

    public CharsetEncoder newEncoder() {
        return new Encoder(this,
                           getEncIndex1(),
                           getEncIndex2(),
                           get0212Encoder(),
                           doSBKANA());
    }

    protected short[] getDecIndex1() {
        return JIS_X_0208_Decoder.getIndex1();
    }

    protected String[] getDecIndex2() {
        return JIS_X_0208_Decoder.getIndex2();
    }

    protected DoubleByteDecoder get0212Decoder() {
        return null;
    }

    protected short[] getEncIndex1() {
        return JIS_X_0208_Encoder.getIndex1();
    }

    protected String[] getEncIndex2() {
        return JIS_X_0208_Encoder.getIndex2();
    }

    protected DoubleByteEncoder get0212Encoder() {
        return null;
    }

    protected boolean doSBKANA() {
        return true;
    }

    private static class Decoder extends DoubleByteDecoder
        implements DelegatableDecoder {

        private int currentState;
        private int previousState;
        private DoubleByteDecoder decoder0212;

        protected Decoder(Charset cs,
                          short[] index1,
                          String[] index2,
                          DoubleByteDecoder decoder0212) {
            super(cs,
                  index1,
                  index2,
                  0x21,
                  0x7e);
            this.decoder0212 = decoder0212;
            currentState = ASCII;
            previousState = ASCII;
        }

        protected char convSingleByte(int b) {
            return REPLACE_CHAR;
        }

        public void implReset() {
            currentState = ASCII;
            previousState = ASCII;
        }

        private CoderResult decodeArrayLoop(ByteBuffer src,
                                            CharBuffer dst)
        {
            int inputSize = 0;
            int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
            char c = REPLACE_CHAR;
            byte[] sa = src.array();
            int sp = src.arrayOffset() + src.position();
            int sl = src.arrayOffset() + src.limit();
            assert (sp <= sl);
            sp = (sp <= sl ? sp : sl);

            char[] da = dst.array();
            int dp = dst.arrayOffset() + dst.position();
            int dl = dst.arrayOffset() + dst.limit();
            assert (dp <= dl);
            dp = (dp <= dl ? dp : dl);

            try {
                while (sp < sl) {
                    b1 = sa[sp] & 0xff;
                    inputSize = 1;
                    if ((b1 & 0x80) != 0) {
                        return CoderResult.malformedForLength(inputSize);
                    }
                    if (b1 == ESC || b1 == SO || b1 == SI) {
                        if (b1 == ESC) {
                            if (sp + inputSize + 2 > sl)
                                return CoderResult.UNDERFLOW;
                            b2 = sa[sp + inputSize++] & 0xff;
                            if (b2 == '(') {
                                b3 = sa[sp + inputSize++] & 0xff;
                                if (b3 == 'B'){
                                    currentState = ASCII;
                                } else if (b3 == 'J'){
                                    currentState = JISX0201_1976;
                                } else if (b3 == 'I'){
                                    currentState = JISX0201_1976_KANA;
                                } else {
                                    return CoderResult.malformedForLength(inputSize);
                                }
                            } else if (b2 == '$'){
                                b3 = sa[sp + inputSize++] & 0xff;
                                if (b3 == '@'){
                                    currentState = JISX0208_1978;
                                } else if (b3 == 'B'){
                                    currentState = JISX0208_1983;
                                } else if (b3 == '(' && decoder0212 != null) {
                                    if (sp + inputSize + 1 > sl)
                                        return CoderResult.UNDERFLOW;
                                    b4 = sa[sp + inputSize++] & 0xff;
                                    if (b4 == 'D') {
                                        currentState = JISX0212_1990;
                                    } else {
                                        return CoderResult.malformedForLength(inputSize);
                                    }
                                } else {
                                    return CoderResult.malformedForLength(inputSize);
                                }
                            } else {
                                return CoderResult.malformedForLength(inputSize);
                            }
                        } else if (b1 == SO) {
                            previousState = currentState;
                            currentState = SHIFTOUT;
                        } else if (b1 == SI) {
                            currentState = previousState;
                        }
                        sp += inputSize;
                        continue;
                    }
                    if (dp + 1 > dl)
                        return CoderResult.OVERFLOW;

                    switch (currentState){
                        case ASCII:
                            da[dp++] = (char)(b1 & 0xff);
                            break;
                        case JISX0201_1976:
                          switch (b1) {
                              case 0x5c:  // Yen/tilde substitution
                                da[dp++] = '\u00a5';
                                break;
                              case 0x7e:
                                da[dp++] = '\u203e';
                                break;
                              default:
                                da[dp++] = (char)b1;
                                break;
                            }
                            break;
                        case JISX0208_1978:
                        case JISX0208_1983:
                            if (sp + inputSize + 1 > sl)
                                return CoderResult.UNDERFLOW;
                            b2 = sa[sp + inputSize++] & 0xff;
                            c = decodeDouble(b1,b2);
                            if (c == REPLACE_CHAR)
                                return CoderResult.unmappableForLength(inputSize);
                            da[dp++] = c;
                            break;
                        case JISX0212_1990:
                            if (sp + inputSize + 1 > sl)
                                return CoderResult.UNDERFLOW;
                            b2 = sa[sp + inputSize++] & 0xff;
                            c = decoder0212.decodeDouble(b1,b2);
                            if (c == REPLACE_CHAR)
                                return CoderResult.unmappableForLength(inputSize);
                            da[dp++] = c;
                            break;
                        case JISX0201_1976_KANA:
                        case SHIFTOUT:
                            if (b1 > 0x60) {
                                return CoderResult.malformedForLength(inputSize);
                            }
                            da[dp++] = (char)(b1 + 0xff40);
                            break;
                    }
                    sp += inputSize;
                }
                return CoderResult.UNDERFLOW;
            } finally {
                src.position(sp - src.arrayOffset());
                dst.position(dp - dst.arrayOffset());
            }
        }

        private CoderResult decodeBufferLoop(ByteBuffer src,
                                             CharBuffer dst)
        {
            int mark = src.position();
            int b1 = 0, b2 = 0, b3 = 0, b4=0;
            char c = REPLACE_CHAR;
            int inputSize = 0;
            try {
                while (src.hasRemaining()) {
                    b1 = src.get() & 0xff;
                    inputSize = 1;
                    if ((b1 & 0x80) != 0)
                        return CoderResult.malformedForLength(inputSize);
                    if (b1 == ESC || b1 == SO || b1 == SI) {
                        if (b1 == ESC) {  // ESC
                            if (src.remaining() < 2)
                                return CoderResult.UNDERFLOW;
                            b2 = src.get() & 0xff;
                            inputSize++;
                            if (b2 == '(') {
                                b3 = src.get() & 0xff;
                                inputSize++;
                                if (b3 == 'B'){
                                    currentState = ASCII;
                                } else if (b3 == 'J'){
                                    currentState = JISX0201_1976;
                                } else if (b3 == 'I'){
                                    currentState = JISX0201_1976_KANA;
                                } else {
                                   return CoderResult.malformedForLength(inputSize);
                                }
                            } else if (b2 == '$'){
                                b3 = src.get() & 0xff;
                                inputSize++;
                                if (b3 == '@'){
                                    currentState = JISX0208_1978;
                                } else if (b3 == 'B'){
                                    currentState = JISX0208_1983;
                                } else if (b3 == '(' && decoder0212 != null) {
                                    if (!src.hasRemaining())
                                        return CoderResult.UNDERFLOW;
                                    b4 = src.get() & 0xff;
                                    inputSize++;
                                    if (b4 == 'D') {
                                        currentState = JISX0212_1990;
                                    } else {
                                        return CoderResult.malformedForLength(inputSize);
                                    }
                                } else {
                                    return CoderResult.malformedForLength(inputSize);
                                }
                            } else {
                                return CoderResult.malformedForLength(inputSize);
                            }
                        } else if (b1 == SO) {
                            previousState = currentState;
                            currentState = SHIFTOUT;
                        } else if (b1 == SI) { // shift back in
                            currentState = previousState;
                        }
                        mark += inputSize;
                        continue;
                    }
                    if (!dst.hasRemaining())
                        return CoderResult.OVERFLOW;

                    switch (currentState){
                        case ASCII:
                            dst.put((char)(b1 & 0xff));
                            break;
                        case JISX0201_1976:
                            switch (b1) {
                              case 0x5c:  // Yen/tilde substitution
                                dst.put('\u00a5');
                                break;
                              case 0x7e:
                                dst.put('\u203e');
                                break;
                              default:
                                dst.put((char)b1);
                                break;
                            }
                            break;
                        case JISX0208_1978:
                        case JISX0208_1983:
                            if (!src.hasRemaining())
                                return CoderResult.UNDERFLOW;
                            b2 = src.get() & 0xff;
                            inputSize++;
                            c = decodeDouble(b1,b2);
                            if (c == REPLACE_CHAR)
                                return CoderResult.unmappableForLength(inputSize);
                            dst.put(c);
                            break;
                        case JISX0212_1990:
                            if (!src.hasRemaining())
                                return CoderResult.UNDERFLOW;
                            b2 = src.get() & 0xff;
                            inputSize++;
                            c = decoder0212.decodeDouble(b1,b2);
                            if (c == REPLACE_CHAR)
                                return CoderResult.unmappableForLength(inputSize);
                            dst.put(c);
                            break;
                        case JISX0201_1976_KANA:
                        case SHIFTOUT:
                            if (b1 > 0x60) {
                                return CoderResult.malformedForLength(inputSize);
                            }
                            dst.put((char)(b1 + 0xff40));
                            break;
                    }
                    mark += inputSize;
                }
                return CoderResult.UNDERFLOW;
            } finally {
                src.position(mark);
            }
        }

        // Make some protected methods public for use by JISAutoDetect
        public CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
            if (src.hasArray() && dst.hasArray())
                return decodeArrayLoop(src, dst);
            else
                return decodeBufferLoop(src, dst);
        }

        public CoderResult implFlush(CharBuffer out) {
            return super.implFlush(out);
        }
    }

    private static class Encoder extends DoubleByteEncoder {
        private static byte[] repl = { (byte)0x21, (byte)0x29 };
        private int currentMode = ASCII;
        private int replaceMode = JISX0208_1983;
        private DoubleByteEncoder encoder0212 = null;
        private boolean doSBKANA;

        private Encoder(Charset cs,
                        short[] index1,
                        String[] index2,
                        DoubleByteEncoder encoder0212,
                        boolean doSBKANA) {
            super(cs,
                  index1,
                  index2,
                  repl,
                  4.0f,
                  (encoder0212 != null)? 9.0f : 8.0f);
            this.encoder0212 = encoder0212;
            this.doSBKANA = doSBKANA;
        }

        protected int encodeSingle(char inputChar) {
            return -1;
        }

        protected void implReset() {
            currentMode = ASCII;
        }

        protected void implReplaceWith(byte[] newReplacement) {
            /* It's almost impossible to decide which charset they belong
               to. The best thing we can do here is to "guess" based on
               the length of newReplacement.
             */
            if (newReplacement.length == 1) {
                replaceMode = ASCII;
            } else if (newReplacement.length == 2) {
                replaceMode = JISX0208_1983;
            }
        }

        protected CoderResult implFlush(ByteBuffer out) {
            if (currentMode != ASCII) {
                if (out.remaining() < 3)
                    return CoderResult.OVERFLOW;
                out.put((byte)0x1b);
                out.put((byte)0x28);
                out.put((byte)0x42);
                currentMode = ASCII;
            }
            return CoderResult.UNDERFLOW;
        }

        public boolean canEncode(char c) {
            return ((c <= '\u007F') ||
                    (c >= 0xFF61 && c <= 0xFF9F) ||
                    (c == '\u00A5') ||
                    (c == '\u203E') ||
                    super.canEncode(c) ||
                    (encoder0212!=null && encoder0212.canEncode(c)));
        }

        private final Surrogate.Parser sgp = new Surrogate.Parser();

        private CoderResult encodeArrayLoop(CharBuffer src,
                                            ByteBuffer dst)
        {
            char[] sa = src.array();
            int sp = src.arrayOffset() + src.position();
            int sl = src.arrayOffset() + src.limit();
            assert (sp <= sl);
            sp = (sp <= sl ? sp : sl);
            byte[] da = dst.array();
            int dp = dst.arrayOffset() + dst.position();
            int dl = dst.arrayOffset() + dst.limit();
            assert (dp <= dl);
            dp = (dp <= dl ? dp : dl);

            try {
                while (sp < sl) {
                    char c = sa[sp];
                    if (c <= '\u007F') {
                        if (currentMode != ASCII) {
                            if (dl - dp < 3)
                                return CoderResult.OVERFLOW;
                            da[dp++] = (byte)0x1b;
                            da[dp++] = (byte)0x28;
                            da[dp++] = (byte)0x42;
                            currentMode = ASCII;
                        }
                        if (dl - dp < 1)
                            return CoderResult.OVERFLOW;
                        da[dp++] = (byte)c;
                    } else if (c >= 0xff61 && c <= 0xff9f && doSBKANA) {
                        //a single byte kana
                        if (currentMode != JISX0201_1976_KANA) {
                            if (dl - dp < 3)
                                return CoderResult.OVERFLOW;
                            da[dp++] = (byte)0x1b;
                            da[dp++] = (byte)0x28;
                            da[dp++] = (byte)0x49;
                            currentMode = JISX0201_1976_KANA;
                        }
                        if (dl - dp < 1)
                            return CoderResult.OVERFLOW;
                        da[dp++] = (byte)(c - 0xff40);
                    } else if (c == '\u00A5' || c == '\u203E') {
                        //backslash or tilde
                        if (currentMode != JISX0201_1976) {
                            if (dl - dp < 3)
                                return CoderResult.OVERFLOW;
                            da[dp++] = (byte)0x1b;
                            da[dp++] = (byte)0x28;
                            da[dp++] = (byte)0x4a;
                            currentMode = JISX0201_1976;
                        }
                        if (dl - dp < 1)
                            return CoderResult.OVERFLOW;
                        da[dp++] = (c == '\u00A5')?(byte)0x5C:(byte)0x7e;
                    } else {
                        int index = encodeDouble(c);
                        if (index != 0) {
                            if (currentMode != JISX0208_1983) {
                                if (dl - dp < 3)
                                    return CoderResult.OVERFLOW;
                                da[dp++] = (byte)0x1b;
                                da[dp++] = (byte)0x24;
                                da[dp++] = (byte)0x42;
                                currentMode = JISX0208_1983;
                            }
                            if (dl - dp < 2)
                                return CoderResult.OVERFLOW;
                            da[dp++] = (byte)(index >> 8);
                            da[dp++] = (byte)(index & 0xff);
                        } else if (encoder0212 != null &&
                                   (index = encoder0212.encodeDouble(c)) != 0) {
                            if (currentMode != JISX0212_1990) {
                                if (dl - dp < 4)
                                    return CoderResult.OVERFLOW;
                                da[dp++] = (byte)0x1b;
                                da[dp++] = (byte)0x24;
                                da[dp++] = (byte)0x28;
                                da[dp++] = (byte)0x44;
                                currentMode = JISX0212_1990;
                            }
                            if (dl - dp < 2)
                                return CoderResult.OVERFLOW;
                            da[dp++] = (byte)(index >> 8);
                            da[dp++] = (byte)(index & 0xff);
                        } else {
                            if (Character.isSurrogate(c) && sgp.parse(c, sa, sp, sl) < 0)
                                return sgp.error();
                            if (unmappableCharacterAction()
                                == CodingErrorAction.REPLACE
                                && currentMode != replaceMode) {
                                if (dl - dp < 3)
                                    return CoderResult.OVERFLOW;
                                if (replaceMode == ASCII) {
                                    da[dp++] = (byte)0x1b;
                                    da[dp++] = (byte)0x28;
                                    da[dp++] = (byte)0x42;
                                } else {
                                    da[dp++] = (byte)0x1b;
                                    da[dp++] = (byte)0x24;
                                    da[dp++] = (byte)0x42;
                                }
                                currentMode = replaceMode;
                            }
                            if (Character.isSurrogate(c))
                                return sgp.unmappableResult();
                            return CoderResult.unmappableForLength(1);
                        }
                    }
                    sp++;
                }
                return CoderResult.UNDERFLOW;
            } finally {
                src.position(sp - src.arrayOffset());
                dst.position(dp - dst.arrayOffset());
            }
        }

        private CoderResult encodeBufferLoop(CharBuffer src,
                                             ByteBuffer dst)
        {
            int mark = src.position();
            try {
                while (src.hasRemaining()) {
                    char c = src.get();

                    if (c <= '\u007F') {
                        if (currentMode != ASCII) {
                            if (dst.remaining() < 3)
                                return CoderResult.OVERFLOW;
                            dst.put((byte)0x1b);
                            dst.put((byte)0x28);
                            dst.put((byte)0x42);
                            currentMode = ASCII;
                        }
                        if (dst.remaining() < 1)
                            return CoderResult.OVERFLOW;
                        dst.put((byte)c);
                    } else if (c >= 0xff61 && c <= 0xff9f && doSBKANA) {
                        //Is it a single byte kana?
                        if (currentMode != JISX0201_1976_KANA) {
                            if (dst.remaining() < 3)
                                return CoderResult.OVERFLOW;
                            dst.put((byte)0x1b);
                            dst.put((byte)0x28);
                            dst.put((byte)0x49);
                            currentMode = JISX0201_1976_KANA;
                        }
                        if (dst.remaining() < 1)
                            return CoderResult.OVERFLOW;
                        dst.put((byte)(c - 0xff40));
                    } else if (c == '\u00a5' || c == '\u203E') {
                        if (currentMode != JISX0201_1976) {
                            if (dst.remaining() < 3)
                                return CoderResult.OVERFLOW;
                            dst.put((byte)0x1b);
                            dst.put((byte)0x28);
                            dst.put((byte)0x4a);
                            currentMode = JISX0201_1976;
                        }
                        if (dst.remaining() < 1)
                            return CoderResult.OVERFLOW;
                        dst.put((c == '\u00A5')?(byte)0x5C:(byte)0x7e);
                    } else {
                        int index = encodeDouble(c);
                        if (index != 0) {
                            if (currentMode != JISX0208_1983) {
                                if (dst.remaining() < 3)
                                    return CoderResult.OVERFLOW;
                                dst.put((byte)0x1b);
                                dst.put((byte)0x24);
                                dst.put((byte)0x42);
                                currentMode = JISX0208_1983;
                            }
                            if (dst.remaining() < 2)
                                return CoderResult.OVERFLOW;
                            dst.put((byte)(index >> 8));
                            dst.put((byte)(index & 0xff));
                        } else if (encoder0212 != null &&
                                   (index = encoder0212.encodeDouble(c)) != 0) {
                            if (currentMode != JISX0212_1990) {
                                if (dst.remaining() < 4)
                                    return CoderResult.OVERFLOW;
                                dst.put((byte)0x1b);
                                dst.put((byte)0x24);
                                dst.put((byte)0x28);
                                dst.put((byte)0x44);
                                currentMode = JISX0212_1990;
                            }
                            if (dst.remaining() < 2)
                                return CoderResult.OVERFLOW;
                            dst.put((byte)(index >> 8));
                            dst.put((byte)(index & 0xff));
                        } else {
                            if (Character.isSurrogate(c) && sgp.parse(c, src) < 0)
                                return sgp.error();
                            if (unmappableCharacterAction() == CodingErrorAction.REPLACE
                                && currentMode != replaceMode) {
                                if (dst.remaining() < 3)
                                    return CoderResult.OVERFLOW;
                                if (replaceMode == ASCII) {
                                    dst.put((byte)0x1b);
                                    dst.put((byte)0x28);
                                    dst.put((byte)0x42);
                                } else {
                                    dst.put((byte)0x1b);
                                    dst.put((byte)0x24);
                                    dst.put((byte)0x42);
                                }
                                currentMode = replaceMode;
                            }
                            if (Character.isSurrogate(c))
                                return sgp.unmappableResult();
                            return CoderResult.unmappableForLength(1);
                        }
                    }
                    mark++;
                }
                return CoderResult.UNDERFLOW;
              } finally {
                src.position(mark);
            }
        }

        protected CoderResult encodeLoop(CharBuffer src,
                                         ByteBuffer dst)
        {
            if (src.hasArray() && dst.hasArray())
                return encodeArrayLoop(src, dst);
            else
                return encodeBufferLoop(src, dst);
        }
    }
}
