X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FI18N%2FCommon%2FMonoEncoding.cs;h=2c736c600e1bb3b7f7a7624eed5ce23a1e0b170f;hb=66e33aa2ee25b9de6ff80e41aa7036b9a8352479;hp=f36f71f86776124342c530f9fda2ee3906d400ea;hpb=b39d5edf62fb3908e10647e1a7e60dadeb88b2be;p=mono.git diff --git a/mcs/class/I18N/Common/MonoEncoding.cs b/mcs/class/I18N/Common/MonoEncoding.cs index f36f71f8677..2c736c600e1 100644 --- a/mcs/class/I18N/Common/MonoEncoding.cs +++ b/mcs/class/I18N/Common/MonoEncoding.cs @@ -32,16 +32,34 @@ namespace I18N.Common get { return win_code_page != 0 ? win_code_page : base.WindowsCodePage; } } -#if NET_2_0 - [CLSCompliant (false)] + /// + /// GetBytes method used internally by state-full encoders/encodings. + /// + /// The chars. + /// Index of the char. + /// The char count. + /// The bytes. + /// Index of the byte. + /// if set to true [flush]. + /// The encoding class to use (or null if state-less). + /// + /// + /// Only state-full encoders need to implement this method (ie. ISO-2022-JP) + /// + protected unsafe virtual int GetBytesInternal(char *chars, int charCount, + byte *bytes, int byteCount, bool flush, object state) + { + throw new NotImplementedException("Statefull encoding is not implemented (yet?) by this encoding class."); + } + public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer, char* chars, ref int charIndex, ref int charCount, - byte* bytes, ref int byteIndex, ref int byteCount) + byte* bytes, ref int byteIndex, ref int byteCount, object state) { if (buffer == null) buffer = EncoderFallback.CreateFallbackBuffer (); - if (Char.IsSurrogate (chars [charIndex]) && charCount > 0 && - Char.IsSurrogate (chars [charIndex + 1])) { + + if (charCount > 1 && (Char.IsSurrogate (chars [charIndex]) && Char.IsSurrogate (chars [charIndex + 1]))) { buffer.Fallback (chars [charIndex], chars [charIndex + 1], charIndex); charIndex++; charCount--; @@ -52,11 +70,25 @@ namespace I18N.Common int idx = 0; while (buffer.Remaining > 0) tmp [idx++] = buffer.GetNextChar (); + fixed (char* tmparr = tmp) { - byteIndex += GetBytes (tmparr, tmp.Length, bytes + byteIndex, byteCount); + var outbytes = bytes == null ? null : bytes + byteIndex; + var len = state == null ? + GetBytes(tmparr, tmp.Length, outbytes, byteCount) + : GetBytesInternal(tmparr, tmp.Length, outbytes, byteCount, true, state); + + byteIndex += len; + byteCount -= len; } } -#endif + + public unsafe void HandleFallback (ref EncoderFallbackBuffer buffer, + char* chars, ref int charIndex, ref int charCount, + byte* bytes, ref int byteIndex, ref int byteCount) + { + HandleFallback(ref buffer, chars, ref charIndex, ref charCount, + bytes, ref byteIndex, ref byteCount, null); + } // Get the bytes that result from encoding a character buffer. public override int GetByteCount ( @@ -159,7 +191,6 @@ namespace I18N.Common } } -#if NET_2_0 public unsafe override int GetByteCount (char* chars, int count) { @@ -172,14 +203,18 @@ namespace I18N.Common { return GetBytesImpl (chars, charCount, bytes, byteCount); } -#endif - [CLSCompliant (false)] + //[CLSCompliant (false)] public unsafe abstract int GetByteCountImpl (char* chars, int charCount); - [CLSCompliant (false)] + //[CLSCompliant (false)] public unsafe abstract int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount); + + public override Encoder GetEncoder () + { + return new MonoEncodingDefaultEncoder (this); + } } public abstract class MonoEncoder : Encoder @@ -251,22 +286,99 @@ namespace I18N.Common public unsafe abstract int GetBytesImpl (char* chars, int charCount, byte* bytes, int byteCount, bool refresh); - #if NET_2_0 public unsafe override int GetBytes (char* chars, int charCount, byte* bytes, int byteCount, bool flush) { return GetBytesImpl (chars, charCount, bytes, byteCount, flush); } - //[CLSCompliant (false)] public unsafe void HandleFallback ( char* chars, ref int charIndex, ref int charCount, - byte* bytes, ref int byteIndex, ref int byteCount) + byte* bytes, ref int byteIndex, ref int byteCount, object state) { EncoderFallbackBuffer buffer = FallbackBuffer; encoding.HandleFallback (ref buffer, chars, ref charIndex, ref charCount, - bytes, ref byteIndex, ref byteCount); + bytes, ref byteIndex, ref byteCount, state); } - #endif + +/* public unsafe void HandleFallback( + char* chars, ref int charIndex, ref int charCount, + byte* bytes, ref int byteIndex, ref int byteCount) + { + HandleFallback(chars, ref charIndex, ref charCount, + bytes, ref byteIndex, ref byteCount, null); + }*/ } + + public class MonoEncodingDefaultEncoder : ReferenceSourceDefaultEncoder + { + public MonoEncodingDefaultEncoder (Encoding encoding) + : base (encoding) + { + } + + [CLSCompliant (false)] + [ComVisible (false)] + public unsafe override void Convert ( + char* chars, int charCount, + byte* bytes, int byteCount, bool flush, + out int charsUsed, out int bytesUsed, out bool completed) + { + CheckArguments (chars, charCount, bytes, byteCount); + + charsUsed = charCount; + while (true) { + bytesUsed = GetByteCount (chars, charsUsed, flush); + if (bytesUsed <= byteCount) + break; + flush = false; + charsUsed >>= 1; + } + completed = charsUsed == charCount; + bytesUsed = GetBytes (chars, charsUsed, bytes, byteCount, flush); + } + + [ComVisible (false)] + public override void Convert ( + char [] chars, int charIndex, int charCount, + byte [] bytes, int byteIndex, int byteCount, bool flush, + out int charsUsed, out int bytesUsed, out bool completed) + { + if (chars == null) + throw new ArgumentNullException ("chars"); + if (bytes == null) + throw new ArgumentNullException ("bytes"); + if (charIndex < 0) + throw new ArgumentOutOfRangeException ("charIndex"); + if (charCount < 0 || chars.Length < charIndex + charCount) + throw new ArgumentOutOfRangeException ("charCount"); + if (byteIndex < 0) + throw new ArgumentOutOfRangeException ("byteIndex"); + if (byteCount < 0 || bytes.Length < byteIndex + byteCount) + throw new ArgumentOutOfRangeException ("byteCount"); + + charsUsed = charCount; + while (true) { + bytesUsed = GetByteCount (chars, charIndex, charsUsed, flush); + if (bytesUsed <= byteCount) + break; + flush = false; + charsUsed >>= 1; + } + completed = charsUsed == charCount; + bytesUsed = GetBytes (chars, charIndex, charsUsed, bytes, byteIndex, flush); + } + + unsafe void CheckArguments (char* chars, int charCount, byte* bytes, int byteCount) + { + if (chars == null) + throw new ArgumentNullException ("chars"); + if (bytes == null) + throw new ArgumentNullException ("bytes"); + if (charCount < 0) + throw new ArgumentOutOfRangeException ("charCount"); + if (byteCount < 0) + throw new ArgumentOutOfRangeException ("byteCount"); + } + } }