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; }
private static string sniffEncoding(PeterO.Support.InputStream s) { byte[] data=new byte[4]; int count=0; s.mark(data.Length+2); try { count=s.Read(data,0,data.Length); } finally { s.reset(); } if(count>=2 && (data[0]&0xFF)==0xfe && (data[1]&0xFF)==0xff) return "utf-16be"; if(count>=2 && (data[0]&0xFF)==0xff && (data[1]&0xFF)==0xfe) return "utf-16le"; if(count>=3 && (data[0]&0xFF)==0xef && (data[1]&0xFF)==0xbb && (data[2]&0xFF)==0xbf) return "utf-8"; if(count>=4 && (data[0]&0xFF)==0x00 && data[1]==0x3c && data[2]==0x00 && data[3]==0x3f) return "utf-16be"; if(count>=4 && data[0]==0x3c && data[1]==0x00 && data[2]==0x3f && data[3]==0x00) return "utf-16le"; if(count>=4 && data[0]==0x3c && data[1]==0x3f && data[2]==0x78 && data[3]==0x6d){ // <?xm data=new byte[128]; s.mark(data.Length+2); try { count=s.Read(data,0,data.Length); } finally { s.reset(); } int i=4; if(i+1>count)return "utf-8"; if(data[i++]!='l')return "utf-8"; // l in <?xml bool space=false; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { space=true; i++; } else { break; } } if(!space || i+7>count)return "utf-8"; if(!(data[i]=='v' && data[i+1]=='e' && data[i+2]=='r' && data[i+3]=='s' && data[i+4]=='i' && data[i+5]=='o' && data[i+6]=='n'))return "utf-8"; i+=7; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { i++; } else { break; } } if(i+1>count || data[i++]!='=')return "utf-8"; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { i++; } else { break; } } if(i+1>count)return "utf-8"; int ch=data[i++]; if(ch!='"' && ch!='\'')return "utf-8"; while(i<count){ if(data[i]==ch){ i++; break; } i++; } space=false; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { space=true; i++; } else { break; } } if(i+8>count)return "utf-8"; if(!(data[i]=='e' && data[i+1]=='n' && data[i+2]=='c' && data[i+3]=='o' && data[i+4]=='d' && data[i+5]=='i' && data[i+6]=='n' && data[i+7]=='g'))return "utf-8"; i+=8; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { i++; } else { break; } } if(i+1>count || data[i++]!='=')return "utf-8"; while(i<count){ if(data[i]==0x09||data[i]==0x0a||data[i]==0x0d||data[i]==0x20) { i++; } else { break; } } if(i+1>count)return "utf-8"; ch=data[i++]; if(ch!='"' && ch!='\'')return "utf-8"; StringBuilder builder=new StringBuilder(); while(i<count){ if(data[i]==ch){ string encoding=TextEncoding.resolveEncoding(builder.ToString()); if(encoding==null) return null; if(encoding.Equals("utf-16le") || encoding.Equals("utf-16be")) return null; return builder.ToString(); } builder.Append((char)data[i]); i++; } return "utf-8"; } return "utf-8"; }
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 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, 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 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==0x7e){ lead=0; if(b==0x7b){ flag=true; continue; } else if(b==0x7d){ flag=false; continue; } else if(b==0x7e){ buffer[offset++]=0x7e; length--; count++; continue; } else if(b==0x0a){ continue; } else { stream.reset(); int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } } if(lead!=0){ int thislead=lead; int cp=-1; lead=0; if(b>=0x21 && b<=0x7e){ cp=(thislead-1)*190+(b+0x3f); cp=GBK.indexToCodePoint(cp); } if(b==0x0a) { flag=false; } if(cp<0){ int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } else { buffer[offset++]=cp; length--; count++; continue; } } if(b==0x7e){ lead=0x7e; stream.mark(2); continue; } if(flag){ if(b>=0x20 && b<=0x7f){ lead=b; continue; } if(b==0x0a){ flag=false; } int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } if(b<=0x7f){ buffer[offset++]=b; length--; count++; continue; } 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, 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; }
private static string readUtf8(PeterO.Support.InputStream stream, int byteLength) { StringBuilder builder=new StringBuilder(); int cp=0; int bytesSeen=0; int bytesNeeded=0; int lower=0x80; int upper=0xBF; int pointer=0; int markedPointer=-1; while(pointer<byteLength || byteLength<0){ int b=stream.ReadByte(); if(b<0 && bytesNeeded!=0){ bytesNeeded=0; throw new BEncodeException("Invalid UTF-8"); } else if(b<0){ if(byteLength>0 && pointer>=byteLength) throw new BEncodeException("Premature end of stream"); break; // end of stream } if(byteLength>0) { pointer++; } if(bytesNeeded==0){ if(b<0x80){ builder.Append((char)b); } else if(b>=0xc2 && b<=0xdf){ stream.mark(4); markedPointer=pointer; bytesNeeded=1; cp=b-0xc0; } else if(b>=0xe0 && b<=0xef){ stream.mark(4); markedPointer=pointer; lower=(b==0xe0) ? 0xa0 : 0x80; upper=(b==0xed) ? 0x9f : 0xbf; bytesNeeded=2; cp=b-0xe0; } else if(b>=0xf0 && b<=0xf4){ stream.mark(4); markedPointer=pointer; lower=(b==0xf0) ? 0x90 : 0x80; upper=(b==0xf4) ? 0x8f : 0xbf; bytesNeeded=3; cp=b-0xf0; } else throw new BEncodeException("Invalid UTF-8"); cp<<=(6*bytesNeeded); continue; } if(b<lower || b>upper){ cp=bytesNeeded=bytesSeen=0; lower=0x80; upper=0xbf; stream.reset(); pointer=markedPointer; throw new BEncodeException("Invalid UTF-8"); } lower=0x80; upper=0xbf; bytesSeen++; cp+=(b-0x80)<<(6*(bytesNeeded-bytesSeen)); stream.mark(4); markedPointer=pointer; if(bytesSeen!=bytesNeeded) { continue; } int ret=cp; cp=0; bytesSeen=0; bytesNeeded=0; if(ret<=0xFFFF){ builder.Append((char)ret); } else { int ch=ret-0x10000; int lead=ch/0x400+0xd800; int trail=(ch&0x3FF)+0xdc00; builder.Append((char)lead); builder.Append((char)trail); } } return builder.ToString(); }
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 && bytesNeeded!=0){ bytesNeeded=0; int o=error.emitDecoderError(buffer,offset,length); offset+=o; count+=o; length-=o; break; } else if(b<0){ break; } if(bytesNeeded==0){ if(b<0x80){ buffer[offset++]=(b); count++; length--; continue; } 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 { int o=error.emitDecoderError(buffer,offset,length); offset+=o; count+=o; length-=o; 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.' int o=error.emitDecoderError(buffer,offset,length); offset+=o; count+=o; length-=o; } lower=0x80; upper=0xbf; bytesSeen++; cp+=(b-0x80)<<(6*(bytesNeeded-bytesSeen)); stream.mark(4); if(bytesSeen!=bytesNeeded) { continue; } buffer[offset++]=(cp); count++; length--; cp=0; bytesSeen=0; bytesNeeded=0; } return (count<=0) ? -1 : count; }
private static Object readObject(PeterO.Support.InputStream stream) { stream.mark(2); int c=stream.ReadByte(); if(c=='d') return readDictionary(stream); else if(c=='l') return readList(stream); else if(c=='i') return readInteger(stream); else if(c>='0' && c<='9'){ stream.reset(); return readString(stream); } else { if(c>=0) { stream.reset(); } throw new BEncodeException("Object expected"); } }
private static int readPositiveInteger(PeterO.Support.InputStream stream) { bool haveNumber=false; while(true){ // skip zeros stream.mark(2); int c=stream.ReadByte(); if(c!='0'){ if(c>=0) { stream.reset(); } break; } haveNumber=true; } long value=0; while(true){ stream.mark(2); int number=stream.ReadByte(); if(number>='0' && number<='9'){ value=(value*10)+(number-'0'); haveNumber=true; } else { if(number>=0) { stream.reset(); } break; } if(value>Int32.MaxValue) throw new BEncodeException("Integer too big"); } if(!haveNumber) throw new BEncodeException("Positive integer expected"); return (int)value; }
private static IList<BEncodeObject> readList(PeterO.Support.InputStream stream) { IList<BEncodeObject> list=new List<BEncodeObject>(); while(true){ stream.mark(2); int c=stream.ReadByte(); if(c=='e') { break; } stream.reset(); Object o=readObject(stream); list.Add(new BEncodeObject(o)); } return list; }
private static long readInteger(PeterO.Support.InputStream stream) { bool haveHex=false; char[] buffer=new char[21]; // enough space for the biggest long long int bufOffset=0; bool negative=false; stream.mark(2); if(stream.ReadByte()=='-'){ buffer[bufOffset++]='-'; negative=true; } else { stream.reset(); } while(true){ // skip zeros stream.mark(2); int c=stream.ReadByte(); if(c!='0'){ if(c>=0) { stream.reset(); } break; } haveHex=true; } while(true){ stream.mark(2); int number=stream.ReadByte(); if(number>='0' && number<='9'){ if(bufOffset>=buffer.Length) throw new BEncodeException(negative ? "Integer too small" : "Integer too big"); buffer[bufOffset++]=(char)number; haveHex=true; } else if(number=='e'){ break; } else { if(number>=0) { stream.reset(); } throw new BEncodeException("'e' expected"); } } if(!haveHex) throw new BEncodeException("Positive integer expected"); if(bufOffset==(negative ? 1 : 0)) return 0; try { string retstr=new String(buffer,0,bufOffset); return Int64.Parse(retstr,NumberStyles.AllowLeadingSign,CultureInfo.InvariantCulture); } catch(FormatException){ throw new BEncodeException(negative ? "Integer too small" : "Integer too big"); } }
private static IDictionary<string, BEncodeObject> readDictionary(PeterO.Support.InputStream stream) { IDictionary<string,BEncodeObject> map=new PeterO.Support.LenientDictionary<string,BEncodeObject>(); while(true){ stream.mark(2); int c=stream.ReadByte(); if(c=='e') { break; } stream.reset(); string s=readString(stream); Object o=readObject(stream); map.Add(s,new BEncodeObject(o)); } return map; }
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; }
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; } }
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, 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 && (gbk1|gbk2|gbk3)==0) return count; else if(b<0){ gbk1=gbk2=gbk3=0; int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; break; } if(gbk3!=0){ int cp=0; if(b>=0x30 && b<=0x39){ int index=(((gbk1-0x81)*10+gbk2-0x30)*126+gbk3-0x81)*10+b-0x30; cp=GB18030CodePoint(index); } gbk1=gbk2=gbk3=0; if(cp==0){ stream.reset(); // 'decrease the byte pointer by three' int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } else { buffer[offset++]=(cp); count++; length--; continue; } } if(gbk2!=0){ if(b>=0x80 && b<=0xFE){ gbk3=b; continue; } else { gbk1=gbk2=0; stream.reset(); // 'decrease the byte pointer by two' int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } } if(gbk1!=0){ if(b>=0x30 && b<=0x39 && gb18030){ gbk2=b; continue; } else { int pointer=-1; int lead=gbk1; gbk1=0; if((b>=0x40 && b<=0x7E) || (b>=0x80 && b<=0xFE)){ int offset2=(b<0x7F) ? 0x40 : 0x41; pointer=(lead-0x81)*190+(b-offset2); } int cp=GBK.indexToCodePoint(pointer); if(pointer==-1){ stream.reset(); // 'decrease byte pointer by one' } 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==0x80){ buffer[offset++]=(0x20AC); count++; length--; continue; } else if(b<=0xFE){ stream.mark(4); gbk1=b; } else { int o=error.emitDecoderError(buffer, offset, length); offset+=o; count+=o; length-=o; continue; } } return (count==0) ? -1 : count; }