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");
+ }
+ }
}