public int decode(PeterO.Support.InputStream stream, IEncodingError error)
 {
     int[] value=new int[1];
     int c=decode(stream,value,0,1, error);
     if(c<=0)return -1;
     return value[0];
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     int cp=0;
     int count=0;
     while(length>0){
       int b=stream.ReadByte();
       if(b<0 && (leadByte>=0 || leadSurrogate>=0)){
     leadByte=-1;
     leadSurrogate=-1;
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     break;
       } else if(b<0){
     break;
       }
       if(leadByte==-1){
     leadByte=b;
     continue;
       }
       cp=(utf16be) ? (leadByte<<8)|b : (b<<8)|leadByte;
       leadByte=-1;
       if(leadSurrogate>=0){
     int lead=leadSurrogate;
     leadSurrogate=-1;
     if(cp>=0xDC00 && cp<=0xDFFF){
       int cp2=0x10000+(lead-0xD800)*0x400+(cp-0xDC00);
       buffer[offset++]=(cp2);
       count++;
       length--;
     } else {
       stream.reset();
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
     }
       } else if(cp>=0xD800 && cp<=0xDBFF){
     leadSurrogate=cp;
     stream.mark(4);
     continue;
       } else if(cp>=0xDC00 && cp<=0xDFFF){
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
       } else {
     buffer[offset++]=(cp);
     count++;
     length--;
       }
     }
     return (count<=0) ? -1 : count;
 }
 public int decode(PeterO.Support.InputStream stream, IEncodingError error)
 {
     if(stream==null)throw new ArgumentException();
     int c=stream.ReadByte();
     if(c<0)return -1;
     if(c<0x80)
       return c;
     else
       return 0xF780+c-0x80;
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     int cp=0;
     int count=0;
     while(length>0){
       int b=stream.ReadByte();
       if(b<0 && (b1>=0 || b2>=0 || b3>=0)){
     b1=b2=b3=-1;
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     break;
       } else if(b<0){
     break;
       }
       if(b3>=0){
     if((utf32be && b1!=0) || (!utf32be && b!=0)){
       b1=b2=b3=-1;
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
     } else {
       cp=(utf32be) ? (b1<<24)|(b2<<16)|(b3<<8)|b : (b<<24)|(b3<<16)|(b2<<8)|b1;
       b1=b2=b3=-1;
       if((cp>=0xD800 && cp<=0xDFFF) || cp<0 || cp>=0x110000){
     // Surrogate and out-of-range code points are illegal
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
       } else {
     buffer[offset++]=(cp);
     count++;
     length--;
       }
     }
     continue;
       } else if(b2>=0){
     b3=b;
     continue;
       } else if(b1>=0){
     b2=b;
     continue;
       } else {
     b1=b;
     continue;
       }
     }
     return (count<=0) ? -1 : count;
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     if(length==0)return 0;
     if(!endofstream){
       endofstream=true;
       int o=error.emitDecoderError(buffer, offset, length);
       return o;
     }
     return -1;
 }
 public int decode(PeterO.Support.InputStream stream, IEncodingError error)
 {
     if(!endofstream){
       endofstream=true;
       if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE))
     return 0xFFFD;
       else {
     int[] data=new int[1];
     int o=error.emitDecoderError(data,0,1);
     return (o==0) ? -1 : data[0];
       }
     }
     return -1;
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     if(length==0)return 0;
     int count=0;
     while(length>0){
       int c=decoder.decode(stream, error);
       if(!havebom && !havecr && c>=0x20 && c<=0x7E){
     buffer[offset]=c;
     offset++;
     count++;
     length--;
     continue;
       }
       if(c<0) {
     break;
       }
       if(c==0x0D){
     // CR character
     havecr=true;
     c=0x0A;
       } else if(c==0x0A && havecr){
     havecr=false;
     continue;
       } else {
     havecr=false;
       }
       if(c==0xFEFF && !havebom){
     // leading BOM
     havebom=true;
     continue;
       } else if(c!=0xFEFF){
     havebom=false;
       }
       if(c<0x09 || (c>=0x0E && c<=0x1F) || (c>=0x7F && c<=0x9F) ||
       (c&0xFFFE)==0xFFFE || c>0x10FFFF || c==0x0B || (c>=0xFDD0 && c<=0xFDEF)){
     // control character or noncharacter
     iserror=true;
       }
       buffer[offset]=c;
       offset++;
       count++;
       length--;
     }
     return count==0 ? -1 : count;
 }
 public int decode(PeterO.Support.InputStream stream, IEncodingError error)
 {
     if(stream==null)throw new ArgumentException();
     while(true){
       int c=stream.ReadByte();
       if(c<0)return -1;
       if(c<0x80)
     return c;
       else {
     int cp=indexes[(c)&0x7F];
     if(cp!=0)return cp;
     if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE))
       return 0xFFFD;
     else {
       int[] data=new int[1];
       int o=error.emitDecoderError(data,0,1);
       if(o>0)return data[0];
     }
       }
     }
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if((stream)==null)throw new ArgumentNullException("stream");
     if((error)==null)throw new ArgumentNullException("error");
     if((buffer)==null)throw new ArgumentNullException("buffer");
     if((offset)<0)throw new ArgumentOutOfRangeException("offset"+" not greater or equal to "+"0"+" ("+Convert.ToString(offset,CultureInfo.InvariantCulture)+")");
     if((length)<0)throw new ArgumentOutOfRangeException("length"+" not greater or equal to "+"0"+" ("+Convert.ToString(length,CultureInfo.InvariantCulture)+")");
     if((offset+length)>buffer.Length)throw new ArgumentOutOfRangeException("offset+length"+" not less or equal to "+Convert.ToString(buffer.Length,CultureInfo.InvariantCulture)+" ("+Convert.ToString(offset+length,CultureInfo.InvariantCulture)+")");
     if(length==0)return 0;
     int total=0;
     for(int i=0;i<length;i++){
       int c=stream.ReadByte();
       if(c<0){
     break;
       } else if(c<0x80){
     buffer[offset++]=c;
     total++;
       } else {
     buffer[offset++]=(0xF780+(c&0xFF)-0x80);
     total++;
       }
     }
     return (total==0) ? -1 : total;
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if((cp<=0x7F || cp==0xa5 || cp==0x203e) && state!=0){
     // ASCII state
     state=0;
     stream.WriteByte(unchecked((byte)(0x1b)));
     stream.WriteByte(unchecked((byte)(0x28)));
     stream.WriteByte(unchecked((byte)(0x42)));
       }
       if(cp<=0x7F){
     stream.WriteByte(unchecked((byte)(cp)));
     continue;
       } else if(cp==0xa5){
     stream.WriteByte(unchecked((byte)(0x5c)));
     continue;
       } else if(cp==0x203e){
     stream.WriteByte(unchecked((byte)(0x7e)));
     continue;
       }
       if(cp>=0xFF61 && cp<=0xFF9F && state!=7){
     // Katakana state
     state=7;
     stream.WriteByte(unchecked((byte)(0x1b)));
     stream.WriteByte(unchecked((byte)(0x28)));
     stream.WriteByte(unchecked((byte)(0x49)));
       }
       if(cp>=0xFF61 && cp<=0xFF9F){
     stream.WriteByte(unchecked((byte)(cp-0xFF61+0x21)));
     continue;
       }
       int pointer=JIS0208.codePointToIndex(cp);
       if(pointer<0){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(state!=5){ // lead state
     state=5;
     stream.WriteByte(unchecked((byte)(0x1b)));
     stream.WriteByte(unchecked((byte)(0x24)));
     stream.WriteByte(unchecked((byte)(0x42)));
       }
       int lead=pointer/94+0x21;
       int trail=pointer%94+0x21;
       stream.WriteByte(unchecked((byte)(lead)));
       stream.WriteByte(unchecked((byte)(trail)));
     }
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     int count=0;
     while(length>0){
       int b=stream.ReadByte();
       if(b<0 && (eucjp1|eucjp2)==0)
     return (count==0) ? -1 : count;
       else if(b<0){
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     break;
       }
       if(eucjp2!=0){
     int lead=0;
     eucjp2=0;
     int cp=0;
     if((lead>=0xA1 && lead<=0xFE) && (b>=0xA1 && b<=0xFE)){
       int index=(lead-0xA1)*94+b-0xA1;
       cp=JIS0212.indexToCodePoint(index);
     }
     if(b<0xA1 || b==0xFF){
       stream.reset();
     }
     if(cp<=0){
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     } else {
       buffer[offset++]=(cp);
       count++;
       length--;
       continue;
     }
       }
       if(eucjp1==0x8E && b>=0xA1 && b<=0xDF){
     eucjp1=0;
     buffer[offset++]=(0xFF61+b-0xA1);
     count++;
     length--;
     //Console.WriteLine("return 0xFF61 cp: %04X",0xFF61+b-0xA1);
     continue;
       }
       if(eucjp1==0x8F && b>=0xA1 && b<=0xFE){
     eucjp1=0;
     eucjp2=b;
     stream.mark(4);
     continue;
       }
       if(eucjp1!=0){
     int lead=eucjp1;
     eucjp1=0;
     int cp=0;
     if((lead>=0xA1 && lead<=0xFE) && (b>=0xA1 && b<=0xFE)){
       int index=(lead-0xA1)*94+b-0xA1;
       cp=JIS0208.indexToCodePoint(index);
       //Console.WriteLine("return 0208 cp: %04X lead=%02X b=%02X index=%04X",cp,lead,b,index);
     }
     if(b<0xA1 || b==0xFF){
       stream.reset();
     }
     if(cp==0){
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     } else {
       buffer[offset++]=(cp);
       count++;
       length--;
       continue;
     }
       }
       if(b<0x80){
     buffer[offset++]=(b);
     count++;
     length--;
     continue;
       } else if(b==0x8E || b==0x8F || (b>=0xA1 && b<=0xFE)){
     eucjp1=b;
     stream.mark(4);
     continue;
       } else {
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     continue;
       }
     }
     return (count==0) ? -1 : count;
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000 || (cp>=0xd800 && cp<=0xdfff)){
     error.emitEncoderError(stream, cp);
     continue;
       }
       int byte1=(cp>>24)&0xFF;
       int byte2=(cp>>16)&0xFF;
       int byte3=(cp>>8)&0xFF;
       int byte4=(cp)&0xFF;
       stream.WriteByte(unchecked((byte)(utf32be ? byte1 : byte4)));
       stream.WriteByte(unchecked((byte)(utf32be ? byte2 : byte3)));
       stream.WriteByte(unchecked((byte)(utf32be ? byte3 : byte2)));
       stream.WriteByte(unchecked((byte)(utf32be ? byte4 : byte1)));
     }
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     int count=0;
     while(length>0){
       if(nextChar>=0){
     buffer[offset++]=nextChar;
     count++;
     length--;
     nextChar=-1;
     continue;
       }
       int b=stream.ReadByte();
       if(b<0 && lead==0){
     break;
       } else if(b<0){
     lead=0;
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     continue;
       }
       if(lead!=0){
     int thislead=lead;
     int pointer=-1;
     lead=0;
     int thisoffset=(b<0x7F) ? 0x40 : 0x62;
     if((b>=0x40 && b<=0x7E) || (b>=0xA1 && b<=0xFE)){
       pointer=(thislead-0x81)*157+(b-thisoffset);
       if(pointer==1133 || pointer==1135){
     buffer[offset++]=(0xca);
     count++;
     length--;
     if(length<=0){
       nextChar=((pointer==1133) ? 0x304 : 0x30C);
       break;
     } else {
       buffer[offset++]=((pointer==1133) ? 0x304 : 0x30C);
       count++;
       length--;
       continue;
     }
       } else if(pointer==1164 || pointer==1166){
     buffer[offset++]=(0xea);
     count++;
     length--;
     if(length<=0){
       nextChar=((pointer==1164) ? 0x304 : 0x30C);
       break;
     } else {
       buffer[offset++]=((pointer==1164) ? 0x304 : 0x30C);
       count++;
       length--;
       continue;
     }
       }
     }
     int cp=Big5.indexToCodePoint(pointer);
     if(pointer<0){
       stream.reset();
     }
     if(cp<=0){
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     } else {
       buffer[offset++]=(cp);
       count++;
       length--;
       continue;
     }
       }
       if(b<0x7F){
     buffer[offset++]=(b);
     count++;
     length--;
     continue;
       } else if(b>=0x81 && b<=0xFE){
     stream.mark(2);
     lead=b;
     continue;
       } else {
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     continue;
       }
     }
     return count>0 ? count : -1;
 }
   /**
      *
      * Utility method to write a _string to an output byte stream.
      *
      * @param str string. If null,
      * Any unpaired surrogates in the _string are kept intact in the
      * input to the encoder.
      * @param output a stream for writing converted bytes to.
      * If null,
      * @param encoder Encoder for converting Unicode characters
      * to bytes.
      * If null,
      * @param error Error handler called when a Unicode character
      * cannot be converted to bytes.  You
      * can use TextEncoding.ENCODING_ERROR_THROW or
      * TextEncoding.ENCODING_ERROR_REPLACE for this.
      * If null,
      * @ if the error handler  exception
      * or another I/O error occurs
      */
   public static void encodeString(
 string str, Stream output,
 ITextEncoder encoder, IEncodingError error)
   {
       if(str==null || encoder==null || output==null || error==null)
         throw new ArgumentException();
       int[] data=new int[1];
       int length=str.Length;
       for(int i=0;i<length;i++){
         int c=str[i];
         if(c>=0xD800 && c<=0xDBFF && i+1<length &&
         str[i+1]>=0xDC00 && str[i+1]<=0xDFFF){
       // Get the Unicode code point for the surrogate pair
       c=0x10000+(c-0xD800)*0x400+(str[i+1]-0xDC00);
       i++;
         }
         data[0]=c;
         encoder.encode(output,data,0,1,error);
       }
   }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if((stream)==null)throw new ArgumentNullException("stream");
     if((error)==null)throw new ArgumentNullException("error");
     if((buffer)==null)throw new ArgumentNullException("buffer");
     if((offset)<0)throw new ArgumentOutOfRangeException("offset"+" not greater or equal to "+"0"+" ("+Convert.ToString(offset,CultureInfo.InvariantCulture)+")");
     if((length)<0)throw new ArgumentOutOfRangeException("length"+" not greater or equal to "+"0"+" ("+Convert.ToString(length,CultureInfo.InvariantCulture)+")");
     if((offset+length)>buffer.Length)throw new ArgumentOutOfRangeException("offset+length"+" not less or equal to "+Convert.ToString(buffer.Length,CultureInfo.InvariantCulture)+" ("+Convert.ToString(offset+length,CultureInfo.InvariantCulture)+")");
     if(length==0)return 0;
     int total=0;
     for(int i=0;i<length;i++){
       int c=stream.ReadByte();
       if(c<0){
     break;
       } else if(c<0x80){
     buffer[offset++]=c;
     total++;
       } else {
     int cp=indexes[(c)&0x7F];
     if(cp==0){
       if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE)) {
     cp=0xFFFD;
       } else {
     int[] data=new int[1];
     int o=error.emitDecoderError(data,0,1);
     if(o>0)return data[0];
       }
     }
     buffer[offset++]=cp;
     total++;
       }
     }
     return (total==0) ? -1 : total;
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if((stream)==null)throw new ArgumentNullException("stream");
     if((error)==null)throw new ArgumentNullException("error");
     if((array)==null)throw new ArgumentNullException("array");
     if((offset)<0)throw new ArgumentOutOfRangeException("offset"+" not greater or equal to "+"0"+" ("+Convert.ToString(offset,CultureInfo.InvariantCulture)+")");
     if((length)<0)throw new ArgumentOutOfRangeException("length"+" not greater or equal to "+"0"+" ("+Convert.ToString(length,CultureInfo.InvariantCulture)+")");
     if((offset+length)>array.Length)throw new ArgumentOutOfRangeException("offset+length"+" not less or equal to "+Convert.ToString(array.Length,CultureInfo.InvariantCulture)+" ("+Convert.ToString(offset+length,CultureInfo.InvariantCulture)+")");
     for(int i=0;i<length;i++){
       int c=array[offset++];
       if(c<0 || c>=0x110000){
     error.emitEncoderError(stream, c);
       } else if(c<0x80){
     stream.WriteByte(unchecked((byte)((byte)c)));
       } else {
     if(c<minValue){
       error.emitEncoderError(stream, c);
       continue;
     }
     int pointer=-1;
     for(int k=0;k<0x80;k++){
       if(indexes[k]==c){
     pointer=k+0x80;
       }
     }
     if(pointer>=0){
       stream.WriteByte(unchecked((byte)((byte)pointer)));
     } else {
       error.emitEncoderError(stream, c);
     }
       }
     }
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(cp<0x80){
     stream.WriteByte(unchecked((byte)(cp)));
     continue;
       }
       if(cp==0xa5){
     stream.WriteByte(unchecked((byte)(0x5c)));
     continue;
       }
       if(cp==0x203e){
     stream.WriteByte(unchecked((byte)(0x7e)));
     continue;
       }
       if(cp>=0xff61 && cp<=0xff9f){
     stream.WriteByte(unchecked((byte)(cp-0xff61+0xa1)));
     continue;
       }
       int pointer=JIS0208.codePointToIndex(cp);
       if(pointer<0){
     error.emitEncoderError(stream, cp);
     continue;
       }
       int lead=pointer/188;
       lead+=(lead<0x1f) ? 0x81 : 0xc1;
       int trail=pointer%188;
       trail+=(trail<0x3f) ? 0x40 : 0x41;
       stream.WriteByte(unchecked((byte)(lead)));
       stream.WriteByte(unchecked((byte)(trail)));
     }
 }
        public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
        {
            if(stream==null || buffer==null || offset<0 || length<0 ||
            offset+length>buffer.Length)
              throw new ArgumentException();
            if(length==0)return 0;
            int count=0;
            while(length>0){
              int b=stream.ReadByte();
              if(state==0){ // ASCII state
            if(b==0x0e){
              state=5; // lead state
            } else if(b==0x0f){
              continue;
            } else if(b==0x1b){
              stream.mark(4);
              state=2; // escape start state
              continue;
            } else if(b<0){
              break;
            } else if(b<=0x7F){
              buffer[offset++]=(b);
              length--;
              count++;
            } else {
              int o=error.emitDecoderError(buffer, offset, length);
              offset+=o;
              count+=o;
              length-=o;

            }
              } else if(state==2){ // escape start state
            if(b==0x24){
              state=3; // escape middle state
              continue;
            } else {
              stream.reset(); // 'decrease by one'
              state=0;// ASCII state
              int o=error.emitDecoderError(buffer, offset, length);
              offset+=o;
              count+=o;
              length-=o;

            }
              } else if(state==3){ // escape middle state
            if(b==0x29){
              state=4;
              continue;
            } else {
              stream.reset();
              state=0;// ASCII state
              int o=error.emitDecoderError(buffer, offset, length);
              offset+=o;
              count+=o;
              length-=o;

            }
              } else if(state==4){ //  state
            if(b==0x43){
              state=0;
              continue;
            } else {
              stream.reset();
              state=0;// ASCII state
              int o=error.emitDecoderError(buffer, offset, length);
              offset+=o;
              count+=o;
              length-=o;

            }
              } else if(state==5){ // lead state
            if(b==0x0A){
              state=0;// ASCII state
              buffer[offset++]=0x0a;
              length--;
              count++;
            } else if(b==0x0e){
              continue;
            } else if(b==0x0f){
              state=0;
              continue;
            } else if(b<0){
              break;
            } else {
              lead=b;
              state=6;
              continue;
            }
              } else if(state==6){ // trail state
            state=5; // lead state
            if(b<0){
              int o=error.emitDecoderError(buffer, offset, length);
              offset+=o;
              count+=o;
              length-=o;

            } else {
              int cp=-1;
              if((lead>=0x21 && lead<=0x46) &&
              (b>=0x21 && b<=0x7e)){
            cp=Korean.indexToCodePoint((26+26+126)*(lead-1)+26+26+b-1);
              } else if((lead>=0x47 && lead<=0x7E) &&
              (b>=0x21 && b<=0x7e)){
            cp=Korean.indexToCodePoint((26+26+126)*(0xc7-0x81)+(lead-0x47)*94+(b-0x21));
              }
              if(cp<=0){
            int o=error.emitDecoderError(buffer, offset, length);
            offset+=o;
            count+=o;
            length-=o;

              } else {
            buffer[offset++]=(cp);
            length--;
            count++;
              }
            }
              }
            }
            return (count==0) ? -1 : count;
        }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(!initialization){
     initialization=true;
     stream.WriteByte(unchecked((byte)(0x1b)));
     stream.WriteByte(unchecked((byte)(0x24)));
     stream.WriteByte(unchecked((byte)(0x29)));
     stream.WriteByte(unchecked((byte)(0x43)));
       }
       if(state!=0 && cp<=0x7F){
     state=0;
     stream.WriteByte(unchecked((byte)(0x0F)));
       }
       if(cp<=0x7F){
     stream.WriteByte(unchecked((byte)(cp)));
     continue;
       }
       int pointer=Korean.codePointToIndex(cp);
       if(pointer<0){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(state!=5){
     state=5;
     stream.WriteByte(unchecked((byte)(0x0e)));
       }
       if(pointer<(26+26+126)*(0xc7-0x81)){
     int lead=pointer/(26+26+126)+1;
     int trail=pointer%(26+26+126)-26-26+1;
     if(lead<0x21 || trail<0x21){
       error.emitEncoderError(stream, cp);
       continue;
     }
     stream.WriteByte(unchecked((byte)(lead)));
     stream.WriteByte(unchecked((byte)(trail)));
       } else {
     pointer-=(26+26+126)*(0xc7-0x81);
     int lead=pointer/94+0x47;
     int trail=pointer%94+0x21;
     stream.WriteByte(unchecked((byte)(lead)));
     stream.WriteByte(unchecked((byte)(trail)));
       }
     }
     if(state!=0 && length>0){
       state=0;
       stream.WriteByte(unchecked((byte)(0x0F)));
     }
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     if(length==0)return 0;
     int count=0;
     int o=0;
     while(length>0){
       int b=stream.ReadByte();
       if(b<0 && lead==0){
     break;
       } else if(b<0){
     lead=0;
     o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     break;
       }
       if(lead!=0){
     int thislead=lead;
     lead=0;
     int pointer=-1;
     if(thislead>=0x81 && thislead<=0xc6){
       pointer=(26+26+126)*(thislead-0x81);
       if(b>=0x41 && b<=0x5a) {
     pointer+=b-0x41;
       } else if(b>=0x61 && b<=0x7a) {
     pointer+=26+b-0x61;
       } else if(b>=0x81 && b<=0xfe) {
     pointer+=26+26+b-0x81;
       }
     }
     if(thislead>=0xc7 && thislead<=0xfe &&
     b>=0xa1 && b<=0xfe){
       pointer=(26+26+126)*(0xc7-0x81)+(thislead-0xC7)*94+(b-0xA1);
     }
     int cp=Korean.indexToCodePoint(pointer);
     if(pointer<0){
       stream.reset();
     }
     if(cp<=0){
       o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     } else {
       buffer[offset++]=cp;
       count++;
       length--;
       continue;
     }
       }
       if(b<0x80){
     buffer[offset++]=b;
     count++;
     length--;
     continue;
       }
       if(b>=0x81 && b<=0xFE){
     lead=b;
     stream.mark(2);
     continue;
       }
       o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
     }
     return (count==0) ? -1 : count;
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(cp<=0x7f){
     stream.WriteByte(unchecked((byte)(cp)));
       } else {
     int pointer=Korean.codePointToIndex(cp);
     if(pointer<0){
       error.emitEncoderError(stream, cp);
       continue;
     }
     if(pointer<(26+26+126)*(0xc7-0x81)){
       int lead=pointer/(26+26+126)+0x81;
       int trail=pointer%(26+26+126);
       int o=0x4d;
       if(trail<26) {
     o=0x41;
       } else if(trail<26+26) {
     o=0x47;
       }
       trail+=o;
       stream.WriteByte(unchecked((byte)(lead)));
       stream.WriteByte(unchecked((byte)(trail)));
     } else {
       pointer-=(26+26+126)*(0xc7-0x81);
       int lead=pointer/94+0xc7;
       int trail=pointer%94+0xa1;
       stream.WriteByte(unchecked((byte)(lead)));
       stream.WriteByte(unchecked((byte)(trail)));
     }
       }
     }
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x10000){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(cp<=0x7F){
     stream.WriteByte(unchecked((byte)(cp)));
       } else if(cp==0xA5){
     stream.WriteByte(unchecked((byte)(0x5c)));
       } else if(cp==0x203E){
     stream.WriteByte(unchecked((byte)(0x7E)));
       } else {
     int index=JIS0208.codePointToIndex(cp);
     if(index<0){
       error.emitEncoderError(stream, cp);
       continue;
     }
     stream.WriteByte(unchecked((byte)(index/94+0xa1)));
     stream.WriteByte(unchecked((byte)(index%94+0xa1)));
       }
     }
 }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     int count=0;
     while(length>0){
       int b=stream.ReadByte();
       if(state==0){ // ASCII state
     if(b==0x1b){
       stream.mark(4);
       state=2; // escape start state
       continue;
     } else if(b<0){
       break;
     } else if(b<=0x7F){
       buffer[offset++]=(b);
       length--;
       count++;
       continue;
     } else {
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     }
       } else if(state==2){ // escape start state
     if(b==0x24 || b==0x28){
       lead=b;
       state=3; // escape middle state
       continue;
     } else {
       stream.reset(); // 'decrease by one'
       state=0;// ASCII state
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     }
       } else if(state==3){ // escape middle state
     if(lead==0x24 && (b==0x40 || b==0x42)){
       jis0212=false;
       state=5; // lead state
       continue;
     } else if(lead==0x24 && b==0x28){
       state=4; // escape  state
       continue;
     } else if(lead==0x28 && (b==0x42 || b==0x4a)){
       state=0; // ASCII state
       continue;
     } else if(lead==0x28 && (b==0x49)){
       state=7; // Katakana state
       continue;
     } else {
       stream.reset();
       state=0;// ASCII state
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     }
       } else if(state==4){ //  state
     if(b==0x44){
       jis0212=true;
       state=5;
       continue;
     } else {
       stream.reset();
       state=0;// ASCII state
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     }
       } else if(state==5){ // lead state
     if(b==0x0A){
       state=0;// ASCII state
       buffer[offset++]=0x0a;
       length--;
       count++;
       continue;
     } else if(b==0x1B){
       state=1; // escape start state
       continue;
     } else if(b<0){
       break;
     } else {
       lead=b;
       state=6;
       continue;
     }
       } else if(state==6){ // trail state
     state=5; // lead state
     if(b<0){
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     } else {
       int cp=-1;
       int index=(lead-0x21)*94+b-0x21;
       if((lead>=0x21 && lead<=0x7e) &&
       (b>=0x21 && b<=0x7e)){
     if(jis0212){
       cp=JIS0212.indexToCodePoint(index);
     } else {
       cp=JIS0208.indexToCodePoint(index);
     }
       }
       if(cp<=0){
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     continue;
       } else {
     buffer[offset++]=(cp);
     length--;
     count++;
     continue;
       }
     }
       } else { // Katakana state
     if(b==0x1b){
       state=1; // escape start state
       continue;
     } else if((b>=0x21 && b<=0x5F)){
       buffer[offset++]=(0xFF61+b-0x21);
       length--;
       count++;
       continue;
     } else if(b<0){
       break;
     } else {
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
       continue;
     }
       }
     }
     return (count==0) ? -1 : count;
 }
 public int decode(PeterO.Support.InputStream stream, IEncodingError error)
 {
     if(stream==null)
       throw new ArgumentException();
     while(true){
       int b=stream.ReadByte();
       if(b<0 && bytesNeeded!=0){
     bytesNeeded=0;
     if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE))
       return 0xFFFD;
     else {
       int[] data=new int[1];
       int o=error.emitDecoderError(data,0,1);
       if(o>0)return data[0];
       continue;
     }
       } else if(b<0)
     return -1;
       if(bytesNeeded==0){
     if(b<0x80)
       return b;
     else if(b>=0xc2 && b<=0xdf){
       stream.mark(4);
       bytesNeeded=1;
       cp=b-0xc0;
     } else if(b>=0xe0 && b<=0xef){
       stream.mark(4);
       lower=(b==0xe0) ? 0xa0 : 0x80;
       upper=(b==0xed) ? 0x9f : 0xbf;
       bytesNeeded=2;
       cp=b-0xe0;
     } else if(b>=0xf0 && b<=0xf4){
       stream.mark(4);
       lower=(b==0xf0) ? 0x90 : 0x80;
       upper=(b==0xf4) ? 0x8f : 0xbf;
       bytesNeeded=3;
       cp=b-0xf0;
     } else {
       if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE))
     return 0xFFFD;
       else {
     int[] data=new int[1];
     int o=error.emitDecoderError(data,0,1);
     if(o>0)return data[0];
     continue;
       }
     }
     cp<<=(6*bytesNeeded);
     continue;
       }
       if(b<lower || b>upper){
     cp=bytesNeeded=bytesSeen=0;
     lower=0x80;
     upper=0xbf;
     stream.reset(); // 'Decrease the byte pointer by one.'
     if(error.Equals(TextEncoding.ENCODING_ERROR_REPLACE))
       return 0xFFFD;
     else {
       int[] data=new int[1];
       int o=error.emitDecoderError(data,0,1);
       if(o>0)return data[0];
       continue;
     }
       }
       lower=0x80;
       upper=0xbf;
       bytesSeen++;
       cp+=(b-0x80)<<(6*(bytesNeeded-bytesSeen));
       stream.mark(4);
       if(bytesSeen!=bytesNeeded) {
     continue;
       }
       int ret=cp;
       cp=0;
       bytesSeen=0;
       bytesNeeded=0;
       return ret;
     }
 }
   /**
      * Utility method to decode an input byte stream into a _string.
      *
      * @param input an input stream containing character data
      * encoded as bytes. If null,
      * @param decoder a text decoder.
      * @param error an _object that handles encoding errors.  You
      * can use TextEncoding.ENCODING_ERROR_THROW or
      * TextEncoding.ENCODING_ERROR_REPLACE for this.
      *
      * @ if the error handler  exception
      * or another I/O error occurs
      */
   public static string decodeString(
 PeterO.Support.InputStream input, ITextDecoder decoder, IEncodingError error)
   {
       if(decoder==null || input==null || error==null)
         throw new ArgumentException();
       int[] data=new int[64];
       StringBuilder builder=new StringBuilder();
       while(true){
         int count=decoder.decode(input,data,0,data.Length,error);
         if(count<0) {
       break;
         }
         for(int i=0;i<count;i++){
       if(data[i]<=0xFFFF){
         builder.Append((char)data[i]);
       } else {
         int ch=data[i]-0x10000;
         int lead=ch/0x400+0xd800;
         int trail=(ch&0x3FF)+0xdc00;
         builder.Append((char)lead);
         builder.Append((char)trail);
       }
         }
       }
       return builder.ToString();
   }
   public void encode(Stream stream, int[] buffer, int offset, int length,
 IEncodingError error)
   {
       if(stream==null || buffer==null)throw new ArgumentException();
       if(offset<0 || length<0 || offset+length>buffer.Length)
         throw new ArgumentOutOfRangeException();
       for(int i=0;i<buffer.Length;i++){
         int cp=buffer[offset+i];
         if(cp<0 || cp>=0x110000){
       error.emitEncoderError(stream, cp);
       continue;
         }
         if(cp<=0x7F){
       stream.WriteByte(unchecked((byte)(cp)));
       break;
         }
         int pointer=Big5.codePointToIndex(cp);
         if(pointer<0){
       error.emitEncoderError(stream, cp);
       continue;
         }
         int lead=pointer/157+0x81;
         if(lead<0xa1){
       // NOTE: Encoding specification says to
       // "[a]void emitting Hong Kong Supplementary
       // Character Set extensions literally."
       error.emitEncoderError(stream, cp);
       continue;
         }
         int trail=pointer%157;
         if(trail<0x3f) {
       trail+=0x40;
         } else {
       trail+=0x62;
         }
         stream.WriteByte(unchecked((byte)(lead)));
         stream.WriteByte(unchecked((byte)(trail)));
       }
   }
 public int decode(PeterO.Support.InputStream stream, int[] buffer, int offset, int length, IEncodingError error)
 {
     if(stream==null || buffer==null || offset<0 || length<0 ||
     offset+length>buffer.Length)
       throw new ArgumentException();
     if(length==0)return 0;
     int count=0;
     while(length>0){
       int b=stream.ReadByte();
       if(b<0 && lead==0){
     break;
       } else if(b<0){
     lead=0;
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     break;
       }
       if(lead!=0){
     int thislead=lead;
     int pointer=-1;
     lead=0;
     int thisoffset=(b<0x7F) ? 0x40 : 0x41;
     int leadOffset=(thislead<0xA0) ? 0x81 : 0xC1;
     if((b>=0x40 && b<=0xFC) && b!=0x7F){
       pointer=(thislead-leadOffset)*188+b-thisoffset;
     }
     int cp=-1;
     cp=JIS0208.indexToCodePoint(pointer);
     if(pointer<0){
       stream.reset();
     }
     if(cp<=0){
       int o=error.emitDecoderError(buffer, offset, length);
       offset+=o;
       count+=o;
       length-=o;
     } else {
       buffer[offset++]=cp;
       count++;
       length--;
     }
     continue;
       }
       if(b<=0x80){
     buffer[offset++]=b;
     count++;
     length--;
       } else if(b>=0xA1 && b<=0xDF){
     buffer[offset++]=0xFF61+b-0xA1;
     count++;
     length--;
       } else if((b>=0x81 && b<=0x9F) || (b>=0xE0 && b<=0xFC)){
     lead=b;
     stream.mark(2);
     continue;
       } else {
     int o=error.emitDecoderError(buffer, offset, length);
     offset+=o;
     count+=o;
     length-=o;
     continue;
       }
     }
     return (count==0) ? -1 : count;
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x110000 || (cp>=0xd800 && cp<=0xdfff)){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(cp<=0xFFFF){
     int b1=(cp>>8)&0xFF;
     int b2=(cp)&0xFF;
     stream.WriteByte(unchecked((byte)(utf16be ? b1 : b2)));
     stream.WriteByte(unchecked((byte)(utf16be ? b2 : b1)));
       } else {
     cp-=0x10000;
     int lead=cp/0x400+0xd800;
     int trail=cp%0x400+0xdc00;
     int b1=(lead>>8)&0xFF;
     int b2=(lead)&0xFF;
     stream.WriteByte(unchecked((byte)(utf16be ? b1 : b2)));
     stream.WriteByte(unchecked((byte)(utf16be ? b2 : b1)));
     b1=(trail>>8)&0xFF;
     b2=(trail)&0xFF;
     stream.WriteByte(unchecked((byte)(utf16be ? b1 : b2)));
     stream.WriteByte(unchecked((byte)(utf16be ? b2 : b1)));
       }
     }
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if((stream)==null)throw new ArgumentNullException("stream");
     if((error)==null)throw new ArgumentNullException("error");
     if((array)==null)throw new ArgumentNullException("array");
     if((offset)<0)throw new ArgumentOutOfRangeException("offset"+" not greater or equal to "+"0"+" ("+Convert.ToString(offset,CultureInfo.InvariantCulture)+")");
     if((length)<0)throw new ArgumentOutOfRangeException("length"+" not greater or equal to "+"0"+" ("+Convert.ToString(length,CultureInfo.InvariantCulture)+")");
     if((offset+length)>array.Length)throw new ArgumentOutOfRangeException("offset+length"+" not less or equal to "+Convert.ToString(array.Length,CultureInfo.InvariantCulture)+" ("+Convert.ToString(offset+length,CultureInfo.InvariantCulture)+")");
     for(int i=0;i<length;i++){
       int c=array[offset++];
       if(c<0 || c>=0x110000){
     error.emitEncoderError(stream, c);
       } else if(c<0x80){
     stream.WriteByte(unchecked((byte)((byte)c)));
       } else if(c>=0xF780 && c<=0xF7FF){
     c=(c-0xf780+0x80)&0xFF;
     stream.WriteByte(unchecked((byte)((byte)c)));
       } else {
     error.emitEncoderError(stream, c);
       }
     }
 }
 public void encode(Stream stream, int[] array, int offset, int length, IEncodingError error)
 {
     if(stream==null || array==null)throw new ArgumentException();
     if(offset<0 || length<0 || offset+length>array.Length)
       throw new ArgumentOutOfRangeException();
     for(int i=0;i<array.Length;i++){
       int cp=array[offset+i];
       if(cp<0 || cp>=0x10000 || (cp>=0xd800 && cp<=0xdfff)){
     error.emitEncoderError(stream, cp);
     continue;
       }
       if(cp<=0x7F){
     stream.WriteByte(unchecked((byte)(cp)));
       } else if(cp<=0x7FF){
     stream.WriteByte(unchecked((byte)((0xC0|((cp>>6)))&0x1F)));
     stream.WriteByte(unchecked((byte)((0x80|(cp   &0x3F)))));
       } else if(cp<=0xFFFF){
     stream.WriteByte(unchecked((byte)((0xE0|((cp>>12)))&0x0F)));
     stream.WriteByte(unchecked((byte)((0x80|((cp>>6 )))&0x3F)));
     stream.WriteByte(unchecked((byte)((0x80|(cp      &0x3F)))));
       } else {
     stream.WriteByte(unchecked((byte)((0xF0|((cp>>18)))&0x07)));
     stream.WriteByte(unchecked((byte)((0x80|((cp>>12)))&0x3F)));
     stream.WriteByte(unchecked((byte)((0x80|((cp>>6 )))&0x3F)));
     stream.WriteByte(unchecked((byte)((0x80|(cp      &0x3F)))));
       }
     }
 }