X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FI18N%2FCJK%2FCP950.cs;h=8e2420ca14c516256d55d92bef0c84820b7d2a1e;hb=79cc1aeccd086b2d9006d6e549426d4ac1ceb80e;hp=785b9cb412825ae9c99b434afad42c0a47cc4576;hpb=fefd6f1d0578964f8ec15e061c5b2db1f9ef4fbc;p=mono.git diff --git a/mcs/class/I18N/CJK/CP950.cs b/mcs/class/I18N/CJK/CP950.cs index 785b9cb4128..8e2420ca14c 100644 --- a/mcs/class/I18N/CJK/CP950.cs +++ b/mcs/class/I18N/CJK/CP950.cs @@ -3,6 +3,7 @@ // // Author: // Alan Tam Siu Lung (Tam@SiuLung.com) +// Atsushi Enomoto // using System; @@ -11,6 +12,7 @@ using I18N.Common; namespace I18N.CJK { + [Serializable] internal class CP950 : DbcsEncoding { // Magic number used by Windows for the Big5 code page. @@ -18,18 +20,53 @@ namespace I18N.CJK // Constructor. public CP950() : base(BIG5_CODE_PAGE) { - convert = Big5Convert.Convert; } - + + internal override DbcsConvert GetConvert () + { + return DbcsConvert.Big5; + } + +#if !DISABLE_UNSAFE // Get the bytes that result from encoding a character buffer. - public override int GetBytes(char[] chars, int charIndex, int charCount, - byte[] bytes, int byteIndex) + public unsafe override int GetByteCountImpl (char* chars, int count) { - // 00 00 - FF FF - base.GetBytes(chars, charIndex, charCount, bytes, byteIndex); + DbcsConvert convert = GetConvert (); + int index = 0; + int length = 0; + + while (count-- > 0) { + char c = chars[index++]; + if (c <= 0x80 || c == 0xFF) { // ASCII + length++; + continue; + } + byte b1 = convert.u2n[((int)c) * 2 + 1]; + byte b2 = convert.u2n[((int)c) * 2]; + if (b1 == 0 && b2 == 0) { + // FIXME: handle fallback for GetByteCountImpl(). + length++; + } + else + length += 2; + } + return length; + } + + // Get the bytes that result from encoding a character buffer. + public unsafe override int GetBytesImpl (char* chars, int charCount, + byte* bytes, int byteCount) + { + DbcsConvert convert = GetConvert (); + int charIndex = 0; + int byteIndex = 0; + int end = charCount; + EncoderFallbackBuffer buffer = null; + int origIndex = byteIndex; - while (charCount-- > 0) { - char c = chars[charIndex++]; + for (int i = charIndex; i < end; i++, charCount--) + { + char c = chars[i]; if (c <= 0x80 || c == 0xFF) { // ASCII bytes[byteIndex++] = (byte)c; continue; @@ -37,7 +74,9 @@ namespace I18N.CJK byte b1 = convert.u2n[((int)c) * 2 + 1]; byte b2 = convert.u2n[((int)c) * 2]; if (b1 == 0 && b2 == 0) { - bytes[byteIndex++] = (byte)'?'; + HandleFallback (ref buffer, chars, + ref i, ref charCount, + bytes, ref byteIndex, ref byteCount, null); } else { bytes[byteIndex++] = b1; bytes[byteIndex++] = b2; @@ -45,11 +84,74 @@ namespace I18N.CJK } return byteIndex - origIndex; } - +#else + // Get the bytes that result from encoding a character buffer. + public override int GetByteCount(char[] chars, int index, int count) + { + DbcsConvert convert = GetConvert(); + int length = 0; + + while (count-- > 0) + { + char c = chars[index++]; + if (c <= 0x80 || c == 0xFF) + { // ASCII + length++; + continue; + } + byte b1 = convert.u2n[((int)c) * 2 + 1]; + byte b2 = convert.u2n[((int)c) * 2]; + if (b1 == 0 && b2 == 0) + { + // FIXME: handle fallback for GetByteCountImpl(). + length++; + } + else + length += 2; + } + return length; + } + + // Get the bytes that result from encoding a character buffer. + public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + int byteCount = bytes.Length; + int end = charIndex + charCount; + + DbcsConvert convert = GetConvert(); + EncoderFallbackBuffer buffer = null; + + int origIndex = byteIndex; + for (int i = charIndex; i < end; i++, charCount--) + { + char c = chars[i]; + if (c <= 0x80 || c == 0xFF) + { // ASCII + bytes[byteIndex++] = (byte)c; + continue; + } + byte b1 = convert.u2n[((int)c) * 2 + 1]; + byte b2 = convert.u2n[((int)c) * 2]; + if (b1 == 0 && b2 == 0) + { + HandleFallback (ref buffer, chars, ref i, ref charCount, + bytes, ref byteIndex, ref byteCount, null); + } + else + { + bytes[byteIndex++] = b1; + bytes[byteIndex++] = b2; + } + } + return byteIndex - origIndex; + } +#endif // Get the characters that result from decoding a byte buffer. public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { + /* + DbcsConvert convert = GetConvert (); // A1 40 - FA FF base.GetChars(bytes, byteIndex, byteCount, chars, charIndex); int origIndex = charIndex; @@ -59,29 +161,38 @@ namespace I18N.CJK if (lastByte == 0) { if (b <= 0x80 || b == 0xFF) { // ASCII chars[charIndex++] = (char)b; - continue; } else if (b < 0xA1 || b >= 0xFA) { - continue; + // incorrect first byte. + chars[charIndex++] = '?'; + byteCount--; // cut one more byte. } else { lastByte = b; - continue; } + continue; } int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2; - char c1 = (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256); + char c1 = ord < 0 || ord > convert.n2u.Length ? + '\0' : + (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256); if (c1 == 0) chars[charIndex++] = '?'; else chars[charIndex++] = c1; lastByte = 0; } + if (lastByte != 0) + chars[charIndex++] = '?'; + return charIndex - origIndex; + */ + + return GetDecoder ().GetChars (bytes, byteIndex, byteCount, chars, charIndex); } // Get a decoder that handles a rolling Big5 state. public override Decoder GetDecoder() { - return new CP950Decoder(convert); + return new CP950Decoder(GetConvert ()); } // Get the mail body name for this encoding. @@ -121,39 +232,109 @@ namespace I18N.CJK { // Constructor. public CP950Decoder(DbcsConvert convert) : base(convert) {} - + int last_byte_count, last_byte_conv; + + public override int GetCharCount (byte[] bytes, int index, int count) + { + return GetCharCount (bytes, index, count, false); + } + + public override + int GetCharCount (byte[] bytes, int index, int count, bool refresh) + { + CheckRange (bytes, index, count); + + int lastByte = last_byte_count; + last_byte_count = 0; + int length = 0; + while (count-- > 0) { + int b = bytes[index++]; + if (lastByte == 0) { + if (b <= 0x80 || b == 0xFF) { // ASCII + length++; + } else if (b < 0xA1 || b >= 0xFA) { + // incorrect first byte. + length++; + count--; // cut one more byte. + } else { + lastByte = b; + } + continue; + } + int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2; + char c1 = ord < 0 || ord > convert.n2u.Length ? + '\0' : + (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256); + if (c1 == 0) + // FIXME: fallback + length++; + else + length++; + lastByte = 0; + } + + if (lastByte != 0) { + if (refresh) + // FIXME: fallback + length++; + else + last_byte_count = lastByte; + } + return length; + } + public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { - base.GetChars(bytes, byteIndex, byteCount, chars, charIndex); + return GetChars (bytes, byteIndex, byteCount, chars, charIndex, false); + } + + public override + int GetChars(byte[] bytes, int byteIndex, int byteCount, + char[] chars, int charIndex, bool refresh) + { + CheckRange (bytes, byteIndex, byteCount, chars, charIndex); + int origIndex = charIndex; + int lastByte = last_byte_conv; + last_byte_conv = 0; while (byteCount-- > 0) { int b = bytes[byteIndex++]; if (lastByte == 0) { if (b <= 0x80 || b == 0xFF) { // ASCII chars[charIndex++] = (char)b; - continue; } else if (b < 0xA1 || b >= 0xFA) { - continue; + // incorrect first byte. + chars[charIndex++] = '?'; + byteCount--; // cut one more byte. } else { lastByte = b; - continue; } + continue; } int ord = ((lastByte - 0xA1) * 191 + b - 0x40) * 2; - char c1 = (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256); - if (c1 == 0) { + char c1 = ord < 0 || ord > convert.n2u.Length ? + '\0' : + (char)(convert.n2u[ord] + convert.n2u[ord + 1] * 256); + if (c1 == 0) chars[charIndex++] = '?'; - } else { + else chars[charIndex++] = c1; - } lastByte = 0; } + + if (lastByte != 0) { + if (refresh) + chars [charIndex++] = '?'; + else + last_byte_conv = lastByte; + } return charIndex - origIndex; } } } + [Serializable] internal class ENCbig5 : CP950 { public ENCbig5() {}