/**
*******************************************************************************
* Copyright (C) 2006, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
*******************************************************************************
*/

package com.ibm.icu.dev.test.charset;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
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 java.nio.charset.UnsupportedCharsetException;
import java.nio.charset.spi.CharsetProvider;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedMap;

import com.ibm.icu.charset.*;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.UTF16;

public class TestCharset extends TestFmwk {
    private String encoding = "UTF-16";
    CharsetDecoder decoder = null;
    CharsetEncoder encoder = null;
    Charset charset =null;
    static final String unistr = "abcd\ud800\udc00\u1234\u00a5\u3000\r\n";
    static final byte[] byteStr ={   
            (byte) 0x00,(byte) 'a',
            (byte) 0x00,(byte) 'b',
            (byte) 0x00,(byte) 'c',
            (byte) 0x00,(byte) 'd',
            (byte) 0xd8,(byte) 0x00,
            (byte) 0xdc,(byte) 0x00,
            (byte) 0x12,(byte) 0x34,
            (byte) 0x00,(byte) 0xa5,
            (byte) 0x30,(byte) 0x00,
            (byte) 0x00,(byte) 0x0d,
            (byte) 0x00,(byte) 0x0a };
    static final byte[] expectedByteStr ={
        (byte) 0xFE,(byte) 0xFF,    
        (byte) 0x00,(byte) 'a',
        (byte) 0x00,(byte) 'b',
        (byte) 0x00,(byte) 'c',
        (byte) 0x00,(byte) 'd',
        (byte) 0xd8,(byte) 0x00,
        (byte) 0xdc,(byte) 0x00,
        (byte) 0x12,(byte) 0x34,
        (byte) 0x00,(byte) 0xa5,
        (byte) 0x30,(byte) 0x00,
        (byte) 0x00,(byte) 0x0d,
        (byte) 0x00,(byte) 0x0a };
    public TestCharset() {
        CharsetProviderICU provider = new CharsetProviderICU();
        //Charset charset = CharsetICU.forName(encoding);
        charset = provider.charsetForName(encoding);
        decoder = (CharsetDecoder) charset.newDecoder();
        encoder = (CharsetEncoder) charset.newEncoder();
    }
    public static void main(String[] args) throws Exception {
        new TestCharset().run(args);
    }
    public void TestUTF16Converter(){
        CharsetProvider icu = new CharsetProviderICU();
        Charset icuChar = icu.charsetForName("UTF-16");
        CharsetEncoder encoder = icuChar.newEncoder();
        CharsetDecoder decoder = icuChar.newDecoder();
        for(int i=0x0000; i<0x10FFFF; i+=0xFF){
            CharBuffer us = CharBuffer.allocate(0xFF*2);
            ByteBuffer bs = ByteBuffer.allocate(0xFF*8);
            for(int j=0;j<0xFF; j++){
                int c = i+j;
              
                if((c>=0xd800&&c<=0xdFFF)||c>0x10FFFF){
                    continue;
                }

                if(c>0xFFFF){
                    char lead = UTF16.getLeadSurrogate(c);
                    char trail = UTF16.getTrailSurrogate(c);
                    if(!UTF16.isLeadSurrogate(lead)){
                        errln("lead is not lead!"+lead+" for cp: \\U"+Integer.toHexString(c));
                        continue;
                    }
                    if(!UTF16.isTrailSurrogate(trail)){
                        errln("trail is not trail!"+trail);
                        continue;
                    }
                    us.put(lead);
                    us.put(trail);
                    bs.put((byte)(lead>>8));
                    bs.put((byte)(lead&0xFF));
                    bs.put((byte)(trail>>8));
                    bs.put((byte)(trail&0xFF));
                }else{

                    if(c<0xFF){
                        bs.put((byte)(c>>8));
                        bs.put((byte)(c&0xFF));
                    }else{
                        bs.put((byte)(c>>8));
                        bs.put((byte)(c&0xFF));
                    }
                    us.put((char)c);
                }
            }
            bs.limit(bs.position());
            bs.position(0);
            us.limit(us.position());
            us.position(0);
            if(us.length()==0){
                continue;
            }
            smBufDecode(decoder, "UTF-16", bs, us);
            ByteBuffer newBS = ByteBuffer.allocate(bs.capacity());
            newBS.put((byte)0xFE);
            newBS.put((byte)0xFF);
            newBS.put(bs);
            
            smBufEncode(encoder, "UTF-16", us, newBS);
        }
        
    }
    public void TestASCIIConverter(){
        CharsetProvider icu = new CharsetProviderICU();
        Charset icuChar = icu.charsetForName("ASCII");
        CharsetEncoder encoder = icuChar.newEncoder();
        CharsetDecoder decoder = icuChar.newDecoder();

        CharBuffer us = CharBuffer.allocate(0x90);
        ByteBuffer bs = ByteBuffer.allocate(0x90);
        for(int j=0;j<=0x7f; j++){
           us.put((char)j);
           bs.put((byte)j);
        }
        bs.limit(bs.position());
        bs.position(0);
        us.limit(us.position());
        us.position(0);
        smBufDecode(decoder, "ASCII", bs, us);
        smBufEncode(encoder, "ASCII", us, bs);
        
    }
    public void Test88591Converter(){
        CharsetProvider icu = new CharsetProviderICU();
        Charset icuChar = icu.charsetForName("iso-8859-1");
        CharsetEncoder encoder = icuChar.newEncoder();
        CharsetDecoder decoder = icuChar.newDecoder();

        CharBuffer us = CharBuffer.allocate(0x100);
        ByteBuffer bs = ByteBuffer.allocate(0x100);
        for(int j=0;j<=0xFf; j++){
           us.put((char)j);
           bs.put((byte)j);
        }
        bs.limit(bs.position());
        bs.position(0);
        us.limit(us.position());
        us.position(0);
        smBufDecode(decoder, "iso-8859-1", bs, us);
        smBufEncode(encoder, "iso-8859-1", us, bs);
        
    }

    public void TestAPISemantics(/*String encoding*/) 
                throws Exception {
        int rc;
        ByteBuffer byes = ByteBuffer.wrap(byteStr);
        CharBuffer uniVal = CharBuffer.wrap(unistr);
        ByteBuffer expected = ByteBuffer.wrap(expectedByteStr);
        
        rc = 0;
        decoder.reset();
        /* Convert the whole buffer to Unicode */
        try {
            CharBuffer chars = CharBuffer.allocate(unistr.length());
            CoderResult result = decoder.decode(byes, chars, false);

            if (result.isError()) {
                errln("ToChars encountered Error");
                rc = 1;
            }
            if (result.isOverflow()) {
                errln("ToChars encountered overflow exception");
                rc = 1;
            }
            if (!equals(chars, unistr)) {
                errln("ToChars does not match");
                printchars(chars);
                errln("Expected : ");
                printchars(unistr);
                rc = 2;
            }

        } catch (Exception e) {
            errln("ToChars - exception in buffer");
            rc = 5;
        }

        /* Convert single bytes to Unicode */
        try {
            CharBuffer chars = CharBuffer.allocate(unistr.length());
            ByteBuffer b = ByteBuffer.wrap(byteStr);
            decoder.reset();
            CoderResult result=null;
            for (int i = 1; i <= byteStr.length; i++) {
                b.limit(i);
                result = decoder.decode(b, chars, false);
                if(result.isOverflow()){
                    errln("ToChars single threw an overflow exception");
                }
                if (result.isError()) {
                    errln("ToChars single the result is an error "+result.toString());
                } 
            }
            if (unistr.length() != (chars.limit())) {
                errln("ToChars single len does not match");
                rc = 3;
            }
            if (!equals(chars, unistr)) {
                errln("ToChars single does not match");
                printchars(chars);
                rc = 4;
            }
        } catch (Exception e) {
            errln("ToChars - exception in single");
            //e.printStackTrace();
            rc = 6;
        }

        /* Convert the buffer one at a time to Unicode */
        try {
            CharBuffer chars = CharBuffer.allocate(unistr.length());
            decoder.reset();
            byes.rewind();
            for (int i = 1; i <= byteStr.length; i++) {
                byes.limit(i);
                CoderResult result = decoder.decode(byes, chars, false);
                if (result.isError()) {
                    errln("Error while decoding: "+result.toString());
                }
                if(result.isOverflow()){
                    errln("ToChars Simple threw an overflow exception");
                }
            }
            if (chars.limit() != unistr.length()) {
                errln("ToChars Simple buffer len does not match");
                rc = 7;
            }
            if (!equals(chars, unistr)) {
                errln("ToChars Simple buffer does not match");
                printchars(chars);
                err(" Expected : ");
                printchars(unistr);
                rc = 8;
            }
        } catch (Exception e) {
            errln("ToChars - exception in single buffer");
            //e.printStackTrace(System.err);
            rc = 9;
        }
        if (rc != 0) {
            errln("Test Simple ToChars for encoding : FAILED");
        }

        rc = 0;
        /* Convert the whole buffer from unicode */
        try {
            ByteBuffer bytes = ByteBuffer.allocate(expectedByteStr.length);
            encoder.reset();
            CoderResult result = encoder.encode(uniVal, bytes, false);
            if (result.isError()) {
                errln("FromChars reported error: " + result.toString());
                rc = 1;
            }
            if(result.isOverflow()){
                errln("FromChars threw an overflow exception");
            }
            bytes.position(0);
            if (!bytes.equals(expected)) {
                errln("FromChars does not match");
                printbytes(bytes);
                rc = 2;
            }
        } catch (Exception e) {
            errln("FromChars - exception in buffer");
            //e.printStackTrace(System.err);
            rc = 5;
        }

        /* Convert the buffer one char at a time to unicode */
        try {
            ByteBuffer bytes = ByteBuffer.allocate(expectedByteStr.length);
            CharBuffer c = CharBuffer.wrap(unistr);
            encoder.reset();
            CoderResult result= null;
            for (int i = 1; i <= unistr.length(); i++) {
                c.limit(i);
                result = encoder.encode(c, bytes, false);
                if(result.isOverflow()){
                    errln("FromChars single threw an overflow exception");
                }
                if(result.isError()){
                    errln("FromChars single threw an error: "+ result.toString());
                }
            }
            if (expectedByteStr.length != bytes.limit()) {
                errln("FromChars single len does not match");
                rc = 3;
            }

            bytes.position(0);
            if (!bytes.equals(expected)) {
                errln("FromChars single does not match");
                printbytes(bytes);
                rc = 4;
            }

        } catch (Exception e) {
            errln("FromChars - exception in single");
            //e.printStackTrace(System.err);
            rc = 6;
        }

        /* Convert one char at a time to unicode */
        try {
            ByteBuffer bytes = ByteBuffer.allocate(expectedByteStr.length);
            encoder.reset();
            char[] temp = unistr.toCharArray();
            CoderResult result=null;
            for (int i = 0; i <= temp.length; i++) {
                uniVal.limit(i);
                result = encoder.encode(uniVal, bytes, false);
                if(result.isOverflow()){
                    errln("FromChars simple threw an overflow exception");
                }
                if(result.isError()){
                    errln("FromChars simple threw an error: "+ result.toString());
                }
            }
            if (bytes.limit() != expectedByteStr.length) {
                errln("FromChars Simple len does not match");
                rc = 7;
            }
            if (!bytes.equals(byes)) {
                errln("FromChars Simple does not match");
                printbytes(bytes);
                rc = 8;
            }
        } catch (Exception e) {
            errln("FromChars - exception in single buffer");
            //e.printStackTrace(System.err);
            rc = 9;
        }
        if (rc != 0) {
            errln("Test Simple FromChars " + encoding + " --FAILED");
        }
    }

    void printchars(CharBuffer buf) {
        int i;
        char[] chars = new char[buf.limit()];
        //save the current position
        int pos = buf.position();
        buf.position(0);
        buf.get(chars);
        //reset to old position
        buf.position(pos);
        for (i = 0; i < chars.length; i++) {
            err(hex(chars[i]) + " ");
        }
        errln("");
    }
    void printchars(String str) {
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            err(hex(chars[i]) + " ");
        }
        errln("");
    }
    void printbytes(ByteBuffer buf) {
        int i;
        byte[] bytes = new byte[buf.limit()];
        //save the current position
        int pos = buf.position();
        buf.position(0);
        buf.get(bytes);
        //reset to old position
        buf.position(pos);
        for (i = 0; i < bytes.length; i++) {
            System.out.print(hex(bytes[i]) + " ");
        }
        errln("");
    }

    public boolean equals(CharBuffer buf, String str) {
        return equals(buf, str.toCharArray());
    }
    public boolean equals(CharBuffer buf, CharBuffer str) {
        return equals(buf.array(), str.array());
    }
    public boolean equals(CharBuffer buf, char[] compareTo) {
        char[] chars = new char[buf.limit()];
        //save the current position
        int pos = buf.position();
        buf.position(0);
        buf.get(chars);
        //reset to old position
        buf.position(pos);
        return equals(chars, compareTo);
    }

    public boolean equals(char[] chars, char[] compareTo) {
        if (chars.length != compareTo.length) {
            errln(
                "Length does not match chars: "
                    + chars.length
                    + " compareTo: "
                    + compareTo.length);
            return false;
        } else {
            boolean result = true;
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] != compareTo[i]) {
                    errln(
                        "Got: "
                            + hex(chars[i])
                            + " Expected: "
                            + hex(compareTo[i])
                            + " At: "
                            + i);
                    result = false;
                }
            }
            return result;
        }
    }

    public boolean equals(ByteBuffer buf, byte[] compareTo) {
        byte[] chars = new byte[buf.limit()];
        //save the current position
        int pos = buf.position();
        buf.position(0);
        buf.get(chars);
        //reset to old position
        buf.position(pos);
        return equals(chars, compareTo);
    }
    public boolean equals(ByteBuffer buf, ByteBuffer compareTo) {
        return equals(buf.array(), compareTo.array());
    }
    public boolean equals(byte[] chars, byte[] compareTo) {
        if (chars.length != compareTo.length) {
            errln(
                "Length does not match chars: "
                    + chars.length
                    + " compareTo: "
                    + compareTo.length);
            return false;
        } else {
            boolean result = true;
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] != compareTo[i]) {
                    errln(
                        "Got: "
                            + hex(chars[i])
                            + " Expected: "
                            + hex(compareTo[i])
                            + " At: "
                            + i);
                    result = false;
                }
            }
            return result;
        }
    }

//  TODO
  /*
    public void TestCallback(String encoding) throws Exception {
        
        byte[] gbSource =
            {
                (byte) 0x81,
                (byte) 0x36,
                (byte) 0xDE,
                (byte) 0x36,
                (byte) 0x81,
                (byte) 0x36,
                (byte) 0xDE,
                (byte) 0x37,
                (byte) 0x81,
                (byte) 0x36,
                (byte) 0xDE,
                (byte) 0x38,
                (byte) 0xe3,
                (byte) 0x32,
                (byte) 0x9a,
                (byte) 0x36 };

        char[] subChars = { 'P', 'I' };

        decoder.reset();

        decoder.replaceWith(new String(subChars));
        ByteBuffer mySource = ByteBuffer.wrap(gbSource);
        CharBuffer myTarget = CharBuffer.allocate(5);

        decoder.decode(mySource, myTarget, true);
        char[] expectedResult =
            { '\u22A6', '\u22A7', '\u22A8', '\u0050', '\u0049', };

        if (!equals(myTarget, new String(expectedResult))) {
            errln("Test callback GB18030 to Unicode : FAILED");
        }
        
    }
*/
    public void TestCanConvert(/*String encoding*/)throws Exception {
        char[] mySource = { 
            '\ud800', '\udc00',/*surrogate pair */
            '\u22A6','\u22A7','\u22A8','\u22A9','\u22AA',
            '\u22AB','\u22AC','\u22AD','\u22AE','\u22AF',
            '\u22B0','\u22B1','\u22B2','\u22B3','\u22B4',
            '\ud800','\udc00',/*surrogate pair */
            '\u22B5','\u22B6','\u22B7','\u22B8','\u22B9',
            '\u22BA','\u22BB','\u22BC','\u22BD','\u22BE' 
            };
            
        encoder.reset();
        if (!encoder.canEncode(new String(mySource))) {
            errln("Test canConvert() " + encoding + " failed. "+encoder);
        }

    }
    public void TestAvailableCharsets() {
        SortedMap map = Charset.availableCharsets();
        Set keySet = map.keySet();
        Iterator iter = keySet.iterator();
        while(iter.hasNext()){
            logln("Charset name: "+iter.next().toString());
        }
        Object[] charsets = CharsetProviderICU.getAvailableNames();
        int mapSize = map.size();
        if(mapSize < charsets.length){
            errln("Charset.availableCharsets() returned a number less than the number returned by icu. ICU: " + charsets.length
                    + " JDK: " + mapSize);
        }
        logln("Total Number of chasets = " + map.size());
	}
    
    public void TestWindows936(){
        CharsetProviderICU icu = new CharsetProviderICU();
        Charset cs = icu.charsetForName("windows-936-2000");
        String canonicalName = cs.name();
        if(!canonicalName.equals("GBK")){
            errln("Did not get the expected canonical name. Got: "+canonicalName); //get the canonical name
        }
    }
    
    public void TestICUAvailableCharsets() {
        CharsetProviderICU icu = new CharsetProviderICU();
        Object[] charsets = CharsetProviderICU.getAvailableNames();
        for(int i=0;i<charsets.length;i++){
            Charset cs = icu.charsetForName((String)charsets[i]);
            try{
                CharsetEncoder encoder = cs.newEncoder();
                if(encoder!=null){
                    logln("Creation of encoder succeeded. "+cs.toString());
                }
            }catch(Exception ex){
                errln("Could not instantiate encoder for "+charsets[i]+". Error: "+ex.toString());
            }
            try{
                CharsetDecoder decoder = cs.newDecoder();
                if(decoder!=null){
                    logln("Creation of decoder succeeded. "+cs.toString());
                }
            }catch(Exception ex){
                errln("Could not instantiate decoder for "+charsets[i]+". Error: "+ex.toString());
            }
        }
    }
    /* jitterbug 4312 */
    public void TestUnsupportedCharset(){
        CharsetProvider icu = new CharsetProviderICU();
        Charset icuChar = icu.charsetForName("impossible");
        if(icuChar != null){
            errln("ICU does not conform to the spec");
        }
    }


    public void TestEncoderCreation(){
        try{
            Charset cs = Charset.forName("GB_2312-80");
            CharsetEncoder enc = cs.newEncoder();
            if(enc!=null && (enc instanceof CharsetEncoderICU) ){
                logln("Successfully created the encoder: "+ enc);
            }else{
                errln("Error creating charset encoder.");
            }
        }catch(Exception e){
            errln("Error creating charset encoder."+ e.toString());
           // e.printStackTrace();
        }
        try{
            Charset cs = Charset.forName("x-ibm-971_P100-1995");
            CharsetEncoder enc = cs.newEncoder();
            if(enc!=null && (enc instanceof CharsetEncoderICU) ){
                logln("Successfully created the encoder: "+ enc);
            }else{
                errln("Error creating charset encoder.");
            }
        }catch(Exception e){
            errln("Error creating charset encoder."+ e.toString());
        }
    }
    public void TestSubBytes(){
        try{
            //create utf-8 decoder
            CharsetDecoder decoder = new CharsetProviderICU().charsetForName("utf-8").newDecoder();
    
            //create a valid byte array, which can be decoded to " buffer"
            byte[] unibytes = new byte[] { 0x0020, 0x0062, 0x0075, 0x0066, 0x0066, 0x0065, 0x0072 };
    
            ByteBuffer buffer = ByteBuffer.allocate(20);
    
            //add a evil byte to make the byte buffer be malformed input
            buffer.put((byte)0xd8);
    
            //put the valid byte array
            buffer.put(unibytes);
    
            //reset postion
            buffer.flip();  
            
            decoder.onMalformedInput(CodingErrorAction.REPLACE);
            CharBuffer out = decoder.decode(buffer);
            String expected = "\ufffd buffer";
            if(!expected.equals(new String(out.array()))){
                errln("Did not get the expected result for substitution chars. Got: "+
                       new String(out.array()) + "("+ hex(out.array())+")");
            }
            logln("Output: "+  new String(out.array()) + "("+ hex(out.array())+")");
        }catch (CharacterCodingException ex){
            errln("Unexpected exception: "+ex.toString());
        }
    }
    /*
    public void TestImplFlushFailure(){
   
       try{
           CharBuffer in = CharBuffer.wrap("\u3005\u3006\u3007\u30FC\u2015\u2010\uFF0F");
           CharsetEncoder encoder = new CharsetProviderICU().charsetForName("iso-2022-jp").newEncoder();
           ByteBuffer out = ByteBuffer.allocate(30);
           encoder.encode(in, out, true);
           encoder.flush(out);
           if(out.position()!= 20){
               errln("Did not get the expected position from flush");
           }
           
       }catch (Exception ex){
           errln("Could not create encoder for  iso-2022-jp exception: "+ex.toString());
       } 
    }
   */
    public void TestISO88591() {
       
        Charset cs = new CharsetProviderICU().charsetForName("iso-8859-1");
        if(cs!=null){
            CharsetEncoder encoder = cs.newEncoder();
            if(encoder!=null){
                encoder.canEncode("\uc2a3");
            }else{
                errln("Could not create encoder for iso-8859-1");
            }
        }else{
            errln("Could not create Charset for iso-8859-1");
        }
        
    }
    public  void TestUTF8Encode() {
        CharsetEncoder encoderICU = new CharsetProviderICU().charsetForName("utf-8").newEncoder();
        ByteBuffer out = ByteBuffer.allocate(30);
        CoderResult result = encoderICU.encode(CharBuffer.wrap("\ud800"), out, true);
       
        if (result.isMalformed()) {
            logln("\\ud800 is malformed for ICU4JNI utf-8 encoder");
        } else if (result.isUnderflow()) {
            errln("\\ud800 is OK for ICU4JNI utf-8 encoder");
        }

        CharsetEncoder encoderJDK = Charset.forName("utf-8").newEncoder();
        result = encoderJDK.encode(CharBuffer.wrap("\ud800"), ByteBuffer
                .allocate(10), true);
        if (result.isUnderflow()) {
            errln("\\ud800 is OK for JDK utf-8 encoder");
        } else if (result.isMalformed()) {
            logln("\\ud800 is malformed for JDK utf-8 encoder");
        }
    }

    private void printCB(CharBuffer buf){
        buf.rewind();
        while(buf.hasRemaining()){
            System.out.println(hex(buf.get()));
        }
        buf.rewind();
    }
    /*
    public void TestUTF8() throws CharacterCodingException{
           try{
               CharsetEncoder encoderICU = new CharsetProviderICU().charsetForName("utf-8").newEncoder();
               encoderICU.encode(CharBuffer.wrap("\ud800"));
               errln("\\ud800 is OK for ICU4JNI utf-8 encoder");
           }catch (MalformedInputException e) {
               logln("\\ud800 is malformed for JDK utf-8 encoder");
              //e.printStackTrace();
           }
           
           CharsetEncoder encoderJDK = Charset.forName("utf-8").newEncoder();
           try {
               encoderJDK.encode(CharBuffer.wrap("\ud800"));
               errln("\\ud800 is OK for JDK utf-8 encoder");
           } catch (MalformedInputException e) {
               logln("\\ud800 is malformed for JDK utf-8 encoder");
               //e.printStackTrace();
           }         
    }
    */
    public void TestUTF16Bom(){

        Charset cs = (new CharsetProviderICU()).charsetForName("UTF-16");
        char[] in = new char[] { 0x1122, 0x2211, 0x3344, 0x4433,
                                0x5566, 0x6655, 0x7788, 0x8877, 0x9900 };
        CharBuffer inBuf = CharBuffer.allocate(in.length);
        inBuf.put(in);
        CharsetEncoder encoder = cs.newEncoder();
        ByteBuffer outBuf = ByteBuffer.allocate(in.length*2);
        inBuf.rewind();
        encoder.encode(inBuf, outBuf, true);
        outBuf.rewind();
        if(outBuf.remaining()> in.length*2){
            errln("The UTF16 encoder appended bom. Length returned: " + outBuf.remaining());
        }
        while(outBuf.hasRemaining()){
            logln("0x"+hex(outBuf.get()));
        }
        CharsetDecoder decoder = cs.newDecoder();
        outBuf.rewind();
        CharBuffer rt = CharBuffer.allocate(in.length);
        decoder.decode(outBuf, rt, true);
    }
     
    private void smBufDecode(CharsetDecoder decoder, String encoding, ByteBuffer source, CharBuffer target) {

        ByteBuffer mySource = source.duplicate();
        CharBuffer myTarget = CharBuffer.allocate(target.capacity());
        {
            decoder.reset();
            myTarget.limit(target.limit());
            mySource.limit(source.limit());
            mySource.position(source.position());
            int inputLen = mySource.remaining();

            CoderResult result = CoderResult.UNDERFLOW;
            for(int i=1; i<=inputLen; i++) {
                mySource.limit(i);
                if(i==inputLen){
                    result = decoder.decode(mySource, myTarget, true);
                }else{
                    result = decoder.decode(mySource, myTarget, false);
                }
                if (result.isError()) {
                    errln("Test small input buffers while decoding failed. "+result.toString());
                    break;
                }
                if (result.isOverflow()) {
                    errln("Test small input buffers while decoding threw overflow exception");
                    break;
                }

            }
            myTarget.limit(myTarget.position());
            myTarget.position(0);
            target.position(0);
            if (result.isUnderflow()&&!equals(myTarget,target)) {
                errln(
                    "Test small input buffers while decoding "
                        + encoding
                        + " TO Unicode--failed");
            }
        }
        {
            decoder.reset();
            myTarget.limit(target.limit());
            mySource.limit(source.limit());
            mySource.position(source.position());
            while (true) {
                int pos = myTarget.position();
                myTarget.limit(++pos);
                CoderResult result = decoder.decode(mySource, myTarget, false);
                if (result.isError()) {
                    errln("Test small output buffers while decoding "+ result.toString());
                }
                if (mySource.position()== mySource.limit()) {
                    result = decoder.decode(mySource, myTarget, true);
                    if (result.isError()) {
                        errln("Test small output buffers while decoding "+result.toString());
                    }
                    result = decoder.flush(myTarget);
                    if (result.isError()) {
                        errln("Test small output buffers while decoding "+ result.toString());
                    }
                    break;
                }
            }

            if (!equals(myTarget,target)) {
                errln(
                    "Test small output buffers "
                        + encoding
                        + " TO Unicode failed");
            }
        }
    }

    private void smBufEncode(CharsetEncoder encoder, String encoding, CharBuffer source, ByteBuffer target) {
        logln("Running smBufEncode for "+ encoding + " with class " + encoder);
        CharBuffer mySource = source.duplicate();
        ByteBuffer myTarget = ByteBuffer.allocate(target.capacity());
        {
            logln("Running tests on small input buffers for "+ encoding);
            encoder.reset();
            myTarget.limit(target.limit());
            mySource.limit(source.limit());
            mySource.position(source.position());
            int inputLen = mySource.limit();
            CoderResult result=null;
            for(int i=1; i<=inputLen; i++) {
                mySource.limit(i);
                result = encoder.encode(mySource, myTarget, false);
                if (result.isError()) {
                    errln("Test small input buffers while encoding failed. "+result.toString());
                }
                if (result.isOverflow()) {
                    errln("Test small input buffers while encoding threw overflow exception");
                }

            }
            
            if (!equals(myTarget,target)) {

                errln("Test small input buffers "+ encoding+ " From Unicode failed");

            }
            logln("Tests on small input buffers for "+ encoding +" passed");
        }
        {
            logln("Running tests on small output buffers for "+ encoding);
            encoder.reset();
            myTarget.limit(target.limit());
            mySource.limit(source.limit());
            mySource.position(source.position());
            mySource.position(0);
            myTarget.position(0);
            logln("myTarget.limit: " + myTarget.limit() + " myTarget.capcity: " + myTarget.capacity());
            
            while (true) {
                int pos = myTarget.position();

                CoderResult result = encoder.encode(mySource, myTarget, false);
                logln("myTarget.Position: "+ pos + " myTarget.limit: " + myTarget.limit());
                logln("mySource.position: " + mySource.position() + " mySource.limit: " + mySource.limit());
                
                if (result.isError()) {
                    errln("Test small output buffers while encoding "+result.toString());
                }
                if (mySource.position() == mySource.limit()) {
                    result = encoder.encode(mySource, myTarget, true);
                    if (result.isError()) {
                        errln("Test small output buffers while encoding "+result.toString());
                    }
                    
                    myTarget.limit(myTarget.capacity());
                    result = encoder.flush(myTarget);
                    if (result.isError()) {
                        errln("Test small output buffers while encoding "+result.toString());
                    }
                    break;
                }
            }
            if (!equals(target,myTarget)) {
                errln("Test small output buffers "+ encoding+ " From Unicode failed.");
            }
            logln("Tests on small output buffers for "+ encoding +" passed");

        }
    }
    public void convertAllTest(ByteBuffer bSource, CharBuffer uSource) throws Exception {
        {
            try {
                decoder.reset();
                ByteBuffer mySource = bSource.duplicate();
                CharBuffer myTarget = decoder.decode(mySource);
                if (!equals(myTarget, uSource)) {
                    errln(
                        "--Test convertAll() "
                            + encoding
                            + " to Unicode  --FAILED");
                }
            } catch (Exception e) {
                //e.printStackTrace();
                errln(e.getMessage());
            }
        }
        {
            try {
                encoder.reset();
                CharBuffer mySource = CharBuffer.wrap(uSource);
                ByteBuffer myTarget = encoder.encode(mySource);
                if (!equals(myTarget, bSource)) {
                    errln(
                        "--Test convertAll() "
                            + encoding
                            + " to Unicode  --FAILED");
                }
            } catch (Exception e) {
                //e.printStackTrace();
                errln("encoder.encode() failed "+ e.getMessage()+" "+e.toString());
            }
        }

    }
    //TODO
    /*
    public void testString(ByteBuffer bSource, CharBuffer uSource) {
        try {
            {
                String source = new String(uSource);
                byte[] target = source.getBytes(encoding);
                if (!equals(target, bSource)) {
                    errln("encode using string API failed");
                }
            }
            {

                String target = new String(getByteArray(gbSource), encoding);
                if (!equals(uSource, target.toCharArray())) {
                    errln("decode using string API failed");
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            errln(e.getMessage());
        }
    }

    private void fromUnicodeTest() throws Exception {
        
        logln("Loaded Charset: " + charset.getClass().toString());
        logln("Loaded CharsetEncoder: " + encoder.getClass().toString());
        logln("Loaded CharsetDecoder: " + decoder.getClass().toString());
        
        ByteBuffer myTarget = ByteBuffer.allocate(gbSource.length);
        logln("Created ByteBuffer of length: " + uSource.length);
        CharBuffer mySource = CharBuffer.wrap(uSource);
        logln("Wrapped ByteBuffer with CharBuffer  ");
        encoder.reset();
        logln("Test Unicode to " + encoding );
        encoder.encode(mySource, myTarget, true);
        if (!equals(myTarget, gbSource)) {
            errln("--Test Unicode to " + encoding + ": FAILED");
        } 
        logln("Test Unicode to " + encoding +" passed");
    }

    public void TestToUnicode( ) throws Exception {
        
        logln("Loaded Charset: " + charset.getClass().toString());
        logln("Loaded CharsetEncoder: " + encoder.getClass().toString());
        logln("Loaded CharsetDecoder: " + decoder.getClass().toString());
        
        CharBuffer myTarget = CharBuffer.allocate(uSource.length);
        ByteBuffer mySource = ByteBuffer.wrap(getByteArray(gbSource));
        decoder.reset();
        CoderResult result = decoder.decode(mySource, myTarget, true);
        if (result.isError()) {
            errln("Test ToUnicode -- FAILED");
        }
        if (!equals(myTarget, uSource)) {
            errln("--Test " + encoding + " to Unicode :FAILED");
        }
    }

    public static byte[] getByteArray(char[] source) {
        byte[] target = new byte[source.length];
        int i = source.length;
        for (; --i >= 0;) {
            target[i] = (byte) source[i];
        }
        return target;
    }
    /*
    private void smBufCharset(Charset charset) {
        try {
            ByteBuffer bTarget = charset.encode(CharBuffer.wrap(uSource));
            CharBuffer uTarget =
                charset.decode(ByteBuffer.wrap(getByteArray(gbSource)));

            if (!equals(uTarget, uSource)) {
                errln("Test " + charset.toString() + " to Unicode :FAILED");
            }
            if (!equals(bTarget, gbSource)) {
                errln("Test " + charset.toString() + " from Unicode :FAILED");
            }
        } catch (Exception ex) {
            errln("Encountered exception in smBufCharset");
        }
    }
    
    public void TestMultithreaded() throws Exception {
        final Charset cs = Charset.forName(encoding);
        if (cs == charset) {
            errln("The objects are equal");
        }
        smBufCharset(cs);
        try {
            final Thread t1 = new Thread() {
                public void run() {
                    // commented out since the mehtods on
                    // Charset API are supposed to be thread
                    // safe ... to test it we dont sync
            
                    // synchronized(charset){
                   while (!interrupted()) {
                        try {
                            smBufCharset(cs);
                        } catch (UnsupportedCharsetException ueEx) {
                            errln(ueEx.toString());
                        }
                    }

                    // }
                }
            };
            final Thread t2 = new Thread() {
                public void run() {
                        // synchronized(charset){
                    while (!interrupted()) {
                        try {
                            smBufCharset(cs);
                        } catch (UnsupportedCharsetException ueEx) {
                            errln(ueEx.toString());
                        }
                    }

                    //}
                }
            };
            t1.start();
            t2.start();
            int i = 0;
            for (;;) {
                if (i > 1000000000) {
                    try {
                        t1.interrupt();
                    } catch (Exception e) {
                    }
                    try {
                        t2.interrupt();
                    } catch (Exception e) {
                    }
                    break;
                }
                i++;
            }
        } catch (Exception e) {
            throw e;
        }
    }

    public void TestSynchronizedMultithreaded() throws Exception {
        // Methods on CharsetDecoder and CharsetEncoder classes
        // are inherently unsafe if accessed by multiple concurrent
        // thread so we synchronize them
        final Charset charset = Charset.forName(encoding);
        final CharsetDecoder decoder = charset.newDecoder();
        final CharsetEncoder encoder = charset.newEncoder();
        try {
            final Thread t1 = new Thread() {
                public void run() {
                    while (!interrupted()) {
                        try {
                            synchronized (encoder) {
                                smBufEncode(encoder, encoding);
                            }
                            synchronized (decoder) {
                                smBufDecode(decoder, encoding);
                            }
                        } catch (UnsupportedCharsetException ueEx) {
                            errln(ueEx.toString());
                        }
                    }

                }
            };
            final Thread t2 = new Thread() {
                public void run() {
                    while (!interrupted()) {
                        try {
                            synchronized (encoder) {
                                smBufEncode(encoder, encoding);
                            }
                            synchronized (decoder) {
                                smBufDecode(decoder, encoding);
                            }
                        } catch (UnsupportedCharsetException ueEx) {
                            errln(ueEx.toString());
                        }
                    }
                }
            };
            t1.start();
            t2.start();
            int i = 0;
            for (;;) {
                if (i > 1000000000) {
                    try {
                        t1.interrupt();
                    } catch (Exception e) {
                    }
                    try {
                        t2.interrupt();
                    } catch (Exception e) {
                    }
                    break;
                }
                i++;
            }
        } catch (Exception e) {
            throw e;
        }
    }
    */
    
    public void TestMBCS(){      
        {
            // Encoder: from Unicode conversion
            CharsetEncoder encoderICU = new CharsetProviderICU().charsetForName("ibm-971").newEncoder();
            ByteBuffer out = ByteBuffer.allocate(6);
            encoderICU.onUnmappableCharacter(CodingErrorAction.REPLACE);
            CoderResult result = encoderICU.encode(CharBuffer.wrap("\u0131\u0061\u00a1"), out, true);
            if(!result.isError()){
                byte[] expected = {(byte)0xA9, (byte)0xA5, (byte)0xAF, (byte)0xFE, (byte)0xA2, (byte)0xAE};
                if(!equals(expected, out.array())){
                    errln("Did not get the expected result for substitution bytes. Got: "+
                           hex(out.array()));
                }
                logln("Output: "+  hex(out.array()));
            }else{
                errln("Encode operation failed for encoder: "+encoderICU.toString());
            }
        }
        {
            // Decoder: to Unicode conversion
            CharsetDecoder decoderICU = new CharsetProviderICU().charsetForName("ibm-971").newDecoder();
            CharBuffer out = CharBuffer.allocate(3);
            decoderICU.onMalformedInput(CodingErrorAction.REPLACE);
            CoderResult result = decoderICU.decode(ByteBuffer.wrap(new byte[] { (byte)0xA2, (byte)0xAE, (byte)0x12, (byte)0x34, (byte)0xEF, (byte)0xDC }), out, true);
            if(!result.isError()){
                char[] expected = {'\u00a1', '\ufffd', '\u6676'};
                if(!equals(expected, out.array())){
                    errln("Did not get the expected result for substitution chars. Got: "+
                           hex(out.array()));
                }
                logln("Output: "+  hex(out.array()));
            }else{
                errln("Decode operation failed for encoder: "+decoderICU.toString());
            }
        }
    }
    
    public void TestJB4897(){
        CharsetProviderICU provider = new CharsetProviderICU();
        Charset charset = provider.charsetForName("x-abracadabra");  
        if(charset!=null && charset.canEncode()== true){
            errln("provider.charsetForName() does not validate the charset names" );
        }
    }

    public void TestJB5027() {
        CharsetProviderICU provider= new CharsetProviderICU();

        Charset fake = provider.charsetForName("doesNotExist");
        if(fake != null){
            errln("\"doesNotExist\" returned " + fake);
        }
        Charset xfake = provider.charsetForName("x-doesNotExist");
        if(xfake!=null){
            errln("\"x-doesNotExist\" returned " + xfake);
        }
    }
    //test to make sure that number of aliases and canonical names are in the charsets that are in
    public void TestAllNames() {
        
        CharsetProviderICU provider= new CharsetProviderICU();
        Object[] available = CharsetProviderICU.getAvailableNames();
        for(int i=0; i<available.length;i++){
            try{
                String canon  = CharsetProviderICU.getICUCanonicalName((String)available[i]);

                // ',' is not allowed by Java's charset name checker
                if(canon.indexOf(',')>=0){
                    continue;
                }
                Charset cs = provider.charsetForName((String)available[i]);
              
                Object[] javaAliases =  cs.aliases().toArray();
                //seach for ICU canonical name in javaAliases
                boolean inAliasList = false;
                for(int j=0; j<javaAliases.length; j++){
                    String java = (String) javaAliases[j];
                    if(java.equals(canon)){
                        logln("javaAlias: " + java + " canon: " + canon);
                        inAliasList = true;
                    }
                }
                if(inAliasList == false){
                    errln("Could not find ICU canonical name: "+canon+ " for java canonical name: "+ available[i]+ " "+ i);
                }
            }catch(UnsupportedCharsetException ex){
                errln("could no load charset "+ available[i]+" "+ex.getMessage());
                continue;
            }
        }
    }
    public void TestDecoderImplFlush() {
        CharsetProviderICU provider = new CharsetProviderICU();
        Charset ics = provider.charsetForName("UTF-16");
        Charset jcs = Charset.forName("UTF-16"); // Java's UTF-16 charset
        execDecoder(jcs);
        execDecoder(ics);
    }
    public void TestEncoderImplFlush() {
        CharsetProviderICU provider = new CharsetProviderICU();
        Charset ics = provider.charsetForName("UTF-16");
        Charset jcs = Charset.forName("UTF-16"); // Java's UTF-16 charset
        execEncoder(jcs);
        execEncoder(ics);
    }
    private void execDecoder(Charset cs){
        CharsetDecoder decoder = cs.newDecoder();
        decoder.onMalformedInput(CodingErrorAction.REPORT);
        decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
        CharBuffer out = CharBuffer.allocate(10);
        CoderResult result = decoder.decode(ByteBuffer.wrap(new byte[] { -1,
                -2, 32, 0, 98 }), out, false);
        result = decoder.decode(ByteBuffer.wrap(new byte[] { 98 }), out, true);

        logln(cs.getClass().toString()+ ":" +result.toString());
        try {
            result = decoder.flush(out);
            logln(cs.getClass().toString()+ ":" +result.toString());
        } catch (Exception e) {
            errln(e.getMessage()+" "+cs.getClass().toString());
        }
    }
    private void execEncoder(Charset cs){
        CharsetEncoder encoder = cs.newEncoder();
        encoder.onMalformedInput(CodingErrorAction.REPORT);
        encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
        ByteBuffer out = ByteBuffer.allocate(10);
        CoderResult result = encoder.encode(CharBuffer.wrap(new char[] { '\uFFFF',
                '\u2345', 32, 98 }), out, false);
        logln(cs.getClass().toString()+ ":" +result.toString());
        result = encoder.encode(CharBuffer.wrap(new char[] { 98 }), out, true);

        logln(cs.getClass().toString()+ ":" +result.toString());
        try {
            result = encoder.flush(out);
            logln(cs.getClass().toString()+ ":" +result.toString());
        } catch (Exception e) {
            errln(e.getMessage()+" "+cs.getClass().toString());
        }
    }
    public void TestDecodeMalformed() {
        CharsetProviderICU provider = new CharsetProviderICU();
        Charset ics = provider.charsetForName("UTF-16BE");
        //Use SUN's charset
        Charset jcs = Charset.forName("UTF-16");
        CoderResult ir = execMalformed(ics);
        CoderResult jr = execMalformed(jcs);
        if(ir!=jr){
            errln("ICU's decoder did not return the same result as Sun. ICU: "+ir.toString()+" Sun: "+jr.toString());
        }
    }
    private CoderResult execMalformed(Charset cs){
        CharsetDecoder decoder = cs.newDecoder();
        decoder.onMalformedInput(CodingErrorAction.IGNORE);
        decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
        ByteBuffer in = ByteBuffer.wrap(new byte[] { 0x00, 0x41, 0x00, 0x42, 0x01 });
        CharBuffer out = CharBuffer.allocate(3);
        return decoder.decode(in, out, true);
    }
    
    public void TestJavaUTF16Decoder(){
        CharsetProviderICU provider = new CharsetProviderICU();
        Charset ics = provider.charsetForName("UTF-16BE");
        //Use SUN's charset
        Charset jcs = Charset.forName("UTF-16");
        Exception ie = execConvertAll(ics);
        Exception je = execConvertAll(jcs);
        if(ie!=je){
            errln("ICU's decoder did not return the same result as Sun. ICU: "+ie.toString()+" Sun: "+je.toString());
        }
    }
    private Exception execConvertAll(Charset cs){
        ByteBuffer in = ByteBuffer.allocate(400);
        int i=0;
        while(in.position()!=in.capacity()){
            in.put((byte)0xD8);
            in.put((byte)i);
            in.put((byte)0xDC);
            in.put((byte)i);
            i++;
        }
        in.limit(in.position());
        in.position(0);
        CharsetDecoder decoder = cs.newDecoder();
        decoder.onMalformedInput(CodingErrorAction.IGNORE);
        decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
        try{
            CharBuffer out = decoder.decode(in);
            if(out!=null){
                logln(cs.toString()+" encoing succeeded as expected!");
            }
        }catch ( Exception ex){
            errln("Did not get expected exception for encoding: "+cs.toString());
            return ex;
        }
        return null;
    }
}
