// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2007-2011, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.charset;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

import com.ibm.icu.text.UnicodeSet;

/**
 * @author Michael Ow
 *
 */
class CharsetUTF7 extends CharsetICU {
    private final static String IMAP_NAME="IMAP-mailbox-name";
    private boolean useIMAP;
    protected byte[] fromUSubstitution=new byte[]{0x3F};
   
    public CharsetUTF7(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
        super(icuCanonicalName, javaCanonicalName, aliases);
        maxBytesPerChar=4; /* max 3 bytes per code unit from UTF-7 (base64) */
        minBytesPerChar=1;
        maxCharsPerByte=1;
        
        useIMAP=false;
        
        if (icuCanonicalName.equals(IMAP_NAME)) {
            useIMAP=true;
        }
    }
    
    //private static boolean inSetD(char c) {
    //    return (
    //            (char)(c - 97) < 26 || (char)(c - 65) < 26 || /* letters */
    //            (char)(c - 48) < 10 ||                        /* digits */
    //            (char)(c - 39) < 3 ||                          /* ' () */
    //            (char)(c - 44) < 4 ||                          /* ,-./ */
    //            (c==58) || (c==63)            /* :? */
    //            );
    //}
    
    //private static boolean inSetO(char c) {
    //    return (
    //            (char)(c - 33) < 6 ||                           /* !"#$%& */
    //            (char)(c - 59) < 4 ||                           /* ;<=> */
    //            (char)(c - 93) < 4 ||                           /* ]^_` */
    //            (char)(c - 123) < 3 ||                         /* {|} */
    //            (c==58) || (c==63)             /* *@[ */
    //            );
    //}
    
    private static boolean isCRLFTAB(char c) {
        return (
                (c==13) || (c==10) || (c==9)
                );
    }
    
    //private static boolean isCRLFSPTAB(char c) {
    //   return (
    //            (c==32) || (c==13) || (c==10) || (c==9)
    //            );
    //}
    
    private static final byte PLUS=43;
    private static final byte MINUS=45;
    private static final byte BACKSLASH=92;
    //private static final byte TILDE=126;
    private static final byte AMPERSAND=0x26;
    private static final byte COMMA=0x2c;
    private static final byte SLASH=0x2f;
    
    // legal byte values: all US-ASCII graphic characters 0x20..0x7e
    private static boolean isLegal(char c, boolean useIMAP) {
        if (useIMAP) {
            return (
                    (0x20 <= c) && (c <= 0x7e)
                    );
        } else {
            return (
                    ((char)(c - 32) < 94 && (c != BACKSLASH)) || isCRLFTAB(c)
                    );
        }
    }
    
    // directly encode all of printable ASCII 0x20..0x7e except '&' 0x26
    private static boolean inSetDIMAP(char c) {
        return (
                (isLegal(c, true) && c != AMPERSAND)
                );
    }
    
    private static byte TO_BASE64_IMAP(int n) {
        return (n < 63 ? TO_BASE_64[n] : COMMA);
    }
    
    private static byte FROM_BASE64_IMAP(char c) {
        return (c==COMMA ? 63 : c==SLASH ? -1 : FROM_BASE_64[c]);
    }
    
    /* encode directly sets D and O and CR LF SP TAB */
    private static final byte ENCODE_DIRECTLY_MAXIMUM[] =
    {
     /*0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f*/
        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
        
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
    };
    
    /* encode directly set D and CR LF SP TAB but not set O */
    private static final byte ENCODE_DIRECTLY_RESTRICTED[] =
    {
     /*0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f*/
        0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        
        1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
        
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 
        
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
    };
    
    private static final byte TO_BASE_64[] =
    {
       /* A-Z */
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
       /* a-z */
       97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
       110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
       /* 0-9 */
       48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
       /* +/ */
       43, 47
    };
    
    private static final byte FROM_BASE_64[] =
    {
       /* C0 controls, -1 for legal ones (CR LF TAB), -3 for illegal ones */
       -3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,
       -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
       /* general punctuation with + and / and a special value (-2) for - */
       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -2, -1, 63,
       /* digits */
       52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
       /* A-Z */
       -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
       15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -3, -1, -1, -1,       
       /* a-z*/
       -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
       41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -3, -3
    };
    
    class CharsetDecoderUTF7 extends CharsetDecoderICU {
        public CharsetDecoderUTF7(CharsetICU cs) {
            super(cs);
            implReset();
        }
    
        protected void implReset() {
            super.implReset();
            toUnicodeStatus=(toUnicodeStatus & 0xf0000000) | 0x1000000;
        }
        
        protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) { 
            CoderResult cr=CoderResult.UNDERFLOW;
            byte base64Value;
            byte base64Counter;
            byte inDirectMode;
            char bits;
            int byteIndex;
            int sourceIndex, nextSourceIndex;
            
            int length;
            
            char b;
            char c;
            
            int sourceArrayIndex=source.position();
            
            //get the state of the machine state
            {
            int status=toUnicodeStatus;
            inDirectMode=(byte)((status >> 24) & 1);
            base64Counter=(byte)(status >> 16);
            bits=(char)status;
            }
            byteIndex=toULength;
            /* sourceIndex=-1 if the current character began in the previous buffer */
            sourceIndex=byteIndex==0 ? 0 : -1;
            nextSourceIndex=0;            
            
            directMode:  while (true) {
                if (inDirectMode==1) {
                    /* 
                     * In Direct Mode, most US-ASCII characters are encoded directly, i.e.,
                     * with their US-ASCII byte values.
                     * Backslash and Tilde and most control characters are not alled in UTF-7.
                     * A plus sign starts Unicode (or "escape") Mode.
                     * An ampersand starts Unicode Mode for IMAP.
                     * 
                     * In Direct Mode, only the sourceIndex is used.
                     */
                    byteIndex=0;
                    length=source.remaining();
                    //targetCapacity=target.remaining();
                    //Commented out because length of source may be larger than target when it comes to bytes 
                    /*if (useIMAP && length > targetCapacity) {
                        length=targetCapacity;
                    }*/
                    while (length > 0) {
                        b=(char)(source.get());
                        sourceArrayIndex++;
                        if (!isLegal(b, useIMAP)) {
                            toUBytesArray[0]=(byte)b;
                            byteIndex=1;
                            cr=CoderResult.malformedForLength(sourceArrayIndex);
                            break;
                        } else if ((!useIMAP && b!=PLUS) || (useIMAP && b!=AMPERSAND)) {
                            // write directly encoded character
                            if (target.hasRemaining()) { // Check to make sure that there is room in target.
                                target.put(b);
                                if (offsets!= null) {
                                    offsets.put(sourceIndex++);
                                }
                            } else {  // Get out and set the CoderResult.
                                charErrorBufferArray[charErrorBufferLength++] = b;
                                cr = CoderResult.OVERFLOW;
                                break;
                            }
                        } else { /* PLUS or (AMPERSAND in IMAP)*/
                            /* switch to Unicode mode */
                            nextSourceIndex=++sourceIndex;
                            inDirectMode=0;
                            byteIndex=0;
                            bits=0;
                            base64Counter=-1;
                            continue directMode;
                        }
                        --length;
                    }//end of while
                    if (source.hasRemaining() && target.position() >= target.limit()) {
                        /* target is full */
                        cr=CoderResult.OVERFLOW;
                    }
                    break directMode;
                } else { /* Unicode Mode*/
                    /* 
                     * In Unicode Mode, UTF-16BE is base64-encoded.
                     * The base64 sequence ends with any character that is not in the base64 alphabet.
                     * A terminating minus sign is consumed.
                     * 
                     * In Unicode Mode, the sourceIndex has the index to the start of the current
                     * base64 bytes, while nextSourceIndex is precisely parallel to source,
                     * keeping the index to the following byte.
                     */
                    while(source.hasRemaining()) {
                        if (target.hasRemaining()) {
                            b=(char)source.get();
                            sourceArrayIndex++;
                            toUBytesArray[byteIndex++]=(byte)b;
                            base64Value = -3; /* initialize as illegal */
                            if ((!useIMAP && (b>=126 || (base64Value=FROM_BASE_64[b])==-3 || base64Value==-1)) || (useIMAP && b>0x7e)) {
                                /* either
                                 * base64Value==-1 for any legal character except base64 and minus sign, or
                                 * base64Value==-3 for illegal characters:
                                 * 1. In either case, leave Unicode mode.
                                 * 2.1. If we ended with an incomplete UChar or none after the +, then
                                 *      generate an error for the preceding erroneous sequence and deal with
                                 *      the current (possibly illegal) character next time through.
                                 * 2.2. Else the current char comes after a complete UChar, which was already
                                 *      pushed to the output buf, so:
                                 * 2.2.1. If the current char is legal, just save it for processing next time.
                                 *        It may be for example, a plus which we need to deal with in direct mode.
                                 * 2.2.2. Else if the current char is illegal, we might as well deal with it here.
                                 */
                                inDirectMode=1;
                                
                                if(base64Counter==-1) {
                                    /* illegal: + immediately followed by something other than base64 or minus sign */
                                    /* include the plus sign in the reported sequence, but not the subsequent char */
                                    source.position(source.position() -1);
                                    toUBytesArray[0]=PLUS;
                                    byteIndex=1;
                                    cr=CoderResult.malformedForLength(sourceArrayIndex);
                                    break directMode;
                                } else if(bits!=0) {
                                    /* bits are illegally left over, a UChar is incomplete */
                                    /* don't include current char (legal or illegal) in error seq */
                                    source.position(source.position() -1);
                                    --byteIndex;
                                    cr=CoderResult.malformedForLength(sourceArrayIndex);
                                    break directMode;
                                } else {
                                    /* previous UChar was complete */
                                    if(base64Value==-3) {
                                        /* current character is illegal, deal with it here */
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        break directMode;
                                    } else {
                                        /* un-read the current character in case it is a plus sign */
                                        source.position(source.position() -1);
                                        sourceIndex=nextSourceIndex-1;
                                        continue directMode;
                                    }
                                }
                            } else if ((!useIMAP && (base64Value=FROM_BASE_64[b])>=0) || (useIMAP && (base64Value=FROM_BASE64_IMAP(b))>=0)) {
                                /* collect base64 bytes */
                                switch (base64Counter) {
                                case -1: /* -1 is immediately after the + */
                                case 0:
                                    bits=(char)base64Value;
                                    base64Counter=1;
                                    break;
                                case 1:
                                case 3:
                                case 4:
                                case 6:
                                    bits=(char)((bits<<6) | base64Value);
                                    ++base64Counter;
                                    break;
                                case 2:
                                    c=(char)((bits<<4) | (base64Value>>2));
                                    if (useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex - 1;
                                    }
                                    toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
                                    byteIndex=1;
                                    bits=(char)(base64Value&3);
                                    base64Counter=3;
                                    break;
                                case 5:
                                    c=(char)((bits<<2) | (base64Value>>4));
                                    if(useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex - 1;
                                    }
                                    toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
                                    byteIndex=1;
                                    bits=(char)(base64Value&15);
                                    base64Counter=6;
                                    break;
                                case 7:
                                    c=(char)((bits<<6) | base64Value);
                                    if (useIMAP && isLegal(c, useIMAP)) {
                                        // illegal
                                        inDirectMode=1;
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        // goto endloop;
                                        break directMode;
                                    }
                                    target.put(c);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex);
                                        sourceIndex=nextSourceIndex;
                                    }
                                    byteIndex=0;
                                    bits=0;
                                    base64Counter=0;
                                    break;
                                //default:                  
                                    /* will never occur */
                                    //break;                                                           
                                }//end of switch
                            } else if (!useIMAP || (useIMAP && base64Value==-2)) {
                                /* minus sign terminates the base64 sequence */
                                inDirectMode=1;
                                if (base64Counter==-1) {
                                    /* +- i.e. a minus immediately following a plus */
                                    target.put(useIMAP ? (char)AMPERSAND : (char)PLUS);
                                    if (offsets != null) {
                                        offsets.put(sourceIndex - 1);
                                    }
                                } else {
                                    /* absorb the minus and leave the Unicode Mode */
                                    if (bits!=0 || (useIMAP && base64Counter!=0 && base64Counter!=3 && base64Counter!=6)) {
                                        /*bits are illegally left over, a unicode character is incomplete */
                                        cr=CoderResult.malformedForLength(sourceArrayIndex);
                                        break;
                                    }
                                }
                                sourceIndex=nextSourceIndex;
                                continue directMode;
                            } else if (useIMAP) { 
                                if (base64Counter==-1) {
                                    // illegal: & immediately followed by something other than base64 or minus sign
                                    // include the ampersand in the reported sequence
                                    --sourceIndex;
                                    toUBytesArray[0]=AMPERSAND;
                                    toUBytesArray[1]=(byte)b;
                                    byteIndex=2;
                                }
                                /* base64Value==-3 for illegal characters */
                                /* illegal */
                                inDirectMode=1;
                                cr=CoderResult.malformedForLength(sourceArrayIndex);
                                break;
                            }
                        } else {
                            /* target is full */
                            cr=CoderResult.OVERFLOW;
                            break;
                        }
                    } //end of while
                    break directMode;
                }
            }//end of direct mode label
            if (useIMAP) {
                if (!cr.isError() && inDirectMode==0 && flush && byteIndex==0 && !source.hasRemaining()) {
                    if (base64Counter==-1) {
                        /* & at the very end of the input */
                        /* make the ampersand the reported sequence */
                        toUBytesArray[0]=AMPERSAND;
                        byteIndex=1;
                    }
                    /* else if (base64Counter!=-1) byteIndex remains 0 because ther is no particular byte sequence */
                    inDirectMode=1;
                    cr=CoderResult.malformedForLength(sourceIndex);
                }
                
            } else {
                if (!cr.isError() && flush && !source.hasRemaining() && bits  ==0) {
                    /*
                     * if we are in Unicode Mode, then the byteIndex might not be 0,
                     * but that is ok if bits -- 0
                     * -> we set byteIndex=0 at the end of the stream to avoid a truncated error 
                     * (not true for IMAP-mailbox-name where we must end in direct mode)
                     */
                    if (!cr.isOverflow()) {
                        byteIndex=0;
                    }
                }
            }
            /* set the converter state */
            toUnicodeStatus=(inDirectMode<<24 | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | (int)bits);
            toULength=byteIndex;
   
            return cr;
        }
    }
    
    class CharsetEncoderUTF7 extends CharsetEncoderICU {
        public CharsetEncoderUTF7(CharsetICU cs) {
            super(cs, fromUSubstitution);
            implReset();
        }
        
        protected void implReset() {
            super.implReset();
            fromUnicodeStatus=(fromUnicodeStatus & 0xf0000000) | 0x1000000;
        }
        
        protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
            CoderResult cr=CoderResult.UNDERFLOW;
            byte inDirectMode;
            byte encodeDirectly[];
            int status;
            
            int length, targetCapacity, sourceIndex;
            
            byte base64Counter;
            char bits;
            char c;
            char b;
            /* get the state machine state */
            {
                status=fromUnicodeStatus;
                encodeDirectly=(((long)status) < 0x10000000) ? ENCODE_DIRECTLY_MAXIMUM : ENCODE_DIRECTLY_RESTRICTED;
                inDirectMode=(byte)((status >> 24) & 1);
                base64Counter=(byte)(status >> 16);
                bits=(char)((byte)status);
            }
            /* UTF-7 always encodes UTF-16 code units, therefore we need only a simple sourceIndex */
            sourceIndex=0;
            
            directMode: while(true) {
            if(inDirectMode==1) {
                length=source.remaining();
                targetCapacity=target.remaining();
                if(length > targetCapacity) {
                    length=targetCapacity;
                }
                while (length > 0) {
                    c=source.get();
                    /* UTF7: currently always encode CR LF SP TAB directly */
                    /* IMAP: encode 0x20..0x7e except '&' directly */
                    if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && inSetDIMAP(c))) {
                        /* encode directly */
                        target.put((byte)c);
                        if (offsets != null) {
                            offsets.put(sourceIndex++);
                        }
                    } else if ((!useIMAP && c==PLUS) || (useIMAP && c==AMPERSAND)) {
                        /* IMAP: output &- for & */
                        /* UTF-7: output +- for + */
                        target.put(useIMAP ? AMPERSAND : PLUS);
                        if (target.hasRemaining()) {
                            target.put(MINUS);
                            if (offsets != null) {
                                offsets.put(sourceIndex);
                                offsets.put(sourceIndex++);
                            }
                            /* realign length and targetCapacity */
                            continue directMode;
                        } else {
                            if (offsets != null) {
                                offsets.put(sourceIndex++);
                            }
                            errorBuffer[0]=MINUS;
                            errorBufferLength=1;
                            cr=CoderResult.OVERFLOW;
                            break;
                        }
                    } else {
                        /* un-read this character and switch to unicode mode */
                        source.position(source.position() - 1);
                        target.put(useIMAP ? AMPERSAND : PLUS);
                        if (offsets != null) {
                            offsets.put(sourceIndex);
                        }
                        inDirectMode=0;
                        base64Counter=0;
                        continue directMode;
                    }
                    --length;
                } //end of while
                if (source.hasRemaining() && !target.hasRemaining()) {
                    /* target is full */
                    cr=CoderResult.OVERFLOW;
                }
                break directMode;
            } else { 
                /* Unicode Mode */
                while (source.hasRemaining()) {
                    if (target.hasRemaining()) {
                        c=source.get();
                        if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && isLegal(c, useIMAP))) {
                            /* encode directly */
                            inDirectMode=1;
                            
                            /* trick: back out this character to make this easier */
                            source.position(source.position() - 1);
                            
                            /* terminate the base64 sequence */
                            if (base64Counter!=0) {
                                /* write remaining bits for the previous character */
                                target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
                                if (offsets!=null) {
                                    offsets.put(sourceIndex-1);
                                }
                            }
                            if (FROM_BASE_64[c]!=-1 || useIMAP) {
                                /* need to terminate with a minus */
                                if (target.hasRemaining()) {
                                    target.put(MINUS);
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex-1);
                                    }
                                } else {
                                    errorBuffer[0]=MINUS;
                                    errorBufferLength=1;
                                    cr=CoderResult.OVERFLOW;
                                    break;
                                }
                            }
                            continue directMode;
                        } else {
                            /*
                             * base64 this character:
                             * Output 2 or 3 base64 bytres for the remaining bits of the previous character
                             * and the bits of this character, each implicitly in UTF-16BE.
                             * 
                             * Here, bits is an 8-bit variable because only 6 bits need to be kept from one
                             * character to the next.  The actual 2 or 4 bits are shifted to the left edge
                             * of the 6-bits filed 5..0 to make the termination of the base64 sequence easier.
                             */
                            switch (base64Counter) {
                            case 0:
                                b=(char)(c>>10);
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>4)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex);
                                        offsets.put(sourceIndex++);
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>4)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=1;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=(char)((c&15)<<2);
                                base64Counter=1;
                                break;
                            case 1:
                                b=(char)(bits|(c>>14));
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>8)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (target.hasRemaining()) {
                                        b=(char)((c>>2)&0x3f);
                                        target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                    } else {
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                        b=(char)((c>>2)&0x3f);
                                        errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                        errorBufferLength=1;
                                        cr=CoderResult.OVERFLOW;
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>8)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    b=(char)((c>>2)&0x3f);
                                    errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=2;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=(char)((c&3)<<4);
                                base64Counter=2;
                                break;
                            case 2:
                                b=(char)(bits|(c>>12));
                                target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                if (target.hasRemaining()) {
                                    b=(char)((c>>6)&0x3f);
                                    target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                    if (target.hasRemaining()) {
                                        b=(char)(c&0x3f);
                                        target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                    } else {
                                        if (offsets!=null) {
                                            offsets.put(sourceIndex);
                                            offsets.put(sourceIndex++);
                                        }
                                        b=(char)(c&0x3f);
                                        errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                        errorBufferLength=1;
                                        cr=CoderResult.OVERFLOW;
                                    }
                                } else {
                                    if (offsets!=null) {
                                        offsets.put(sourceIndex++);
                                    }
                                    b=(char)((c>>6)&0x3f);
                                    errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    b=(char)(c&0x3f);
                                    errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
                                    errorBufferLength=2;
                                    cr=CoderResult.OVERFLOW;
                                }
                                bits=0;
                                base64Counter=0;
                                break;
                           //default:
                               /* will never occur */
                               //break;
                           } //end of switch 
                        }                      
                    } else {
                        /* target is full */
                        cr=CoderResult.OVERFLOW;
                        break;
                    }
                } //end of while
                break directMode;
            }
            } //end of directMode label
            
            if (flush && !source.hasRemaining()) {
                /* flush remaining bits to the target */
                if (inDirectMode==0) {
                    if (base64Counter!=0) {
                        if (target.hasRemaining()) {
                            target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
                            if (offsets!=null) {
                                offsets.put(sourceIndex - 1);
                            }
                        } else {
                            errorBuffer[errorBufferLength++]=useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits];
                            cr=CoderResult.OVERFLOW;
                        }
                    }
                    
                    /* need to terminate with a minus */
                    if (target.hasRemaining()) {
                        target.put(MINUS);
                        if (offsets!=null) {
                            offsets.put(sourceIndex - 1);
                        }
                    } else {
                        errorBuffer[errorBufferLength++]=MINUS;
                        cr=CoderResult.OVERFLOW;
                    }
                }
                /*reset the state for the next conversion */
                fromUnicodeStatus=((status&0xf0000000) | 0x1000000); /* keep version, inDirectMode=TRUE */
            } else {
                /* set the converter state back */
                fromUnicodeStatus=((status&0xf0000000) | (inDirectMode<<24) | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | ((int)bits));
            }
            
            return cr;
        }
    }
    
    public CharsetDecoder newDecoder() {
        return new CharsetDecoderUTF7(this);
    }
    
    public CharsetEncoder newEncoder() {
        return new CharsetEncoderUTF7(this);
    }
    
    void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
        getCompleteUnicodeSet(setFillIn);
    }
}
