New test.
[mono.git] / mcs / class / corlib / System.Text / Decoder.cs
index b133c1240467edc65c9f316dae17579acbf192ad..74062465718f4c05303dfe4d855bbcbf831dd165 100644 (file)
-//
-// System.Text.Decoder.cs
-//
-// Authors:
-//   Dietmar Maurer (dietmar@ximian.com)
-//
-// (C) 2001 Ximian, Inc.  http://www.ximian.com
-//
+/*
+ * Decoder.cs - Implementation of the "System.Text.Decoder" class.
+ *
+ * Copyright (c) 2001  Southern Storm Software, Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
 
 namespace System.Text
 {
 
-       [Serializable]
-       public abstract class Decoder
-       {
-               
-               protected Decoder ()
-               {
-                       // fixme: dont know what do do here
-               }
-
-               public abstract int GetCharCount (byte[] bytes, int index, int count);
+using System;
+using System.Runtime.InteropServices;
 
-               public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount,
-                                             char[] chars, int charIndex);
-       }
+[Serializable]
+#if NET_2_0
+[ComVisible (true)]
+#endif
+public abstract class Decoder
+{
 
-       internal class DefaultDecoder : Decoder {
+       // Constructor.
+       protected Decoder () {}
 
-               public Encoding encoding;
+#if NET_2_0
+       DecoderFallback fallback = new DecoderReplacementFallback ();
+       DecoderFallbackBuffer fallback_buffer;
 
-               public DefaultDecoder (Encoding enc)
-               {
-                       encoding = enc;
+       [ComVisible (false)]
+       public DecoderFallback Fallback {
+               get { return fallback; }
+               set {
+                       if (value == null)
+                               throw new ArgumentNullException ();
+                       fallback = value;
+                       fallback_buffer = null;
                }
+       }
 
-               public override int GetCharCount (byte[] bytes, int index, int count)
-               {
-                       return encoding.GetCharCount (bytes, index, count);
+       [ComVisible (false)]
+       public DecoderFallbackBuffer FallbackBuffer {
+               get {
+                       if (fallback_buffer == null)
+                               fallback_buffer = fallback.CreateFallbackBuffer ();
+                       return fallback_buffer;
                }
+       }
+#endif
 
-               public override int GetChars (byte[] bytes, int byteIndex, int byteCount,
-                                             char[] chars, int charIndex)
-               {
-                       return encoding.GetChars (bytes, byteIndex, byteCount, chars, charIndex);
-               }
+       // Get the number of characters needed to decode a buffer.
+       public abstract int GetCharCount (byte[] bytes, int index, int count);
+
+       // Get the characters that result from decoding a buffer.
+       public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount,
+                                                                char[] chars, int charIndex);
 
+#if NET_2_0
+       [ComVisible (false)]
+       public virtual int GetCharCount (byte [] bytes, int index, int count, bool flush)
+       {
+               if (flush)
+                       Reset ();
+               return GetCharCount (bytes, index, count);
        }
-       
-       internal class IConvDecoder : Decoder {
-               
-               private IntPtr converter;
-
-               public IConvDecoder (string name, bool big_endian)
-               {
-                       converter = Encoding.IConvNewDecoder (name, big_endian);
-               }
 
-               public override int GetCharCount (byte[] bytes, int index, int count)
-               {
-                       if (bytes == null)
-                               throw new ArgumentNullException ();
+       [CLSCompliant (false)]
+       [ComVisible (false)]
+       public unsafe virtual int GetCharCount (byte* bytes, int count, bool flush)
+       {
+               if (bytes == null)
+                       throw new ArgumentNullException ("bytes");
+               if (count < 0)
+                       throw new ArgumentOutOfRangeException ("count");
+
+               byte [] barr = new byte [count];
+               Marshal.Copy ((IntPtr) bytes, barr, 0, count);
+               return GetCharCount (barr, 0, count, flush);
+       }
 
-                       if (index + count > bytes.Length)
-                               throw new ArgumentOutOfRangeException ();
+       public virtual int GetChars (
+               byte[] bytes, int byteIndex, int byteCount,
+               char[] chars, int charIndex, bool flush)
+       {
+               CheckArguments (bytes, byteIndex, byteCount);
+               CheckArguments (chars, charIndex);
 
-                       return Encoding.IConvGetCharCount (converter, bytes, index, count);
-               }
+               if (flush)
+                       Reset ();
+               return GetChars (bytes, byteIndex, byteCount, chars, charIndex);
+       }
 
-               public override int GetChars (byte[] bytes, int byteIndex, int byteCount,
-                                             char[] chars, int charIndex)
-               {
-                       if ((bytes == null) || (chars == null))
-                               throw new ArgumentNullException ();
+       [CLSCompliant (false)]
+       [ComVisible (false)]
+       public unsafe virtual int GetChars (byte* bytes, int byteCount,
+               char* chars, int charCount, bool flush)
+       {
+               CheckArguments (chars, charCount, bytes, byteCount);
 
-                       if ((byteIndex < 0) || (byteCount < 0) || (charIndex < 0))
-                               throw new ArgumentOutOfRangeException ();
+               char [] carr = new char [charCount];
+               Marshal.Copy ((IntPtr) chars, carr, 0, charCount);
+               byte [] barr = new byte [byteCount];
+               Marshal.Copy ((IntPtr) bytes, barr, 0, byteCount);
+               return GetChars (barr, 0, byteCount, carr, 0, flush);
+       }
 
-                       if (byteIndex + byteCount > bytes.Length)
-                               throw new ArgumentOutOfRangeException ();
+       [ComVisible (false)]
+       public virtual void Reset ()
+       {
+               if (fallback_buffer != null)
+                       fallback_buffer.Reset ();
+       }
 
-                       if (charIndex > chars.Length)
-                               throw new ArgumentOutOfRangeException ();
+       [CLSCompliant (false)]
+       [ComVisible (false)]
+       public unsafe virtual void Convert (
+               byte* bytes, int byteCount,
+               char* chars, int charCount, bool flush,
+               out int bytesUsed, out int charsUsed, out bool completed)
+       {
+               CheckArguments (chars, charCount, bytes, byteCount);
+
+               bytesUsed = byteCount;
+               while (true) {
+                       charsUsed = GetCharCount (bytes, bytesUsed, flush);
+                       if (charsUsed <= charCount)
+                               break;
+                       flush = false;
+                       bytesUsed >>= 1;
+               }
+               completed = bytesUsed == byteCount;
+               charsUsed = GetChars (bytes, bytesUsed, chars, charCount, flush);
+       }
 
-                       return Encoding.IConvGetChars (converter, bytes, byteIndex, byteCount,
-                                                      chars, charIndex);
+       [ComVisible (false)]
+       public virtual void Convert (
+               byte [] bytes, int byteIndex, int byteCount,
+               char [] chars, int charIndex, int charCount, bool flush,
+               out int bytesUsed, out int charsUsed, out bool completed)
+       {
+               CheckArguments (bytes, byteIndex, byteCount);
+               CheckArguments (chars, charIndex);
+               if (charCount < 0 || chars.Length < charIndex + charCount)
+                       throw new ArgumentOutOfRangeException ("charCount");
+
+               bytesUsed = byteCount;
+               while (true) {
+                       charsUsed = GetCharCount (bytes, byteIndex, bytesUsed, flush);
+                       if (charsUsed <= charCount)
+                               break;
+                       flush = false;
+                       bytesUsed >>= 1;
                }
-       }       
-}
+               completed = bytesUsed == byteCount;
+               charsUsed = GetChars (bytes, byteIndex, bytesUsed, chars, charIndex, flush);
+       }
+
+       void CheckArguments (char [] chars, int charIndex)
+       {
+               if (chars == null)
+                       throw new ArgumentNullException ("chars");
+               if (charIndex < 0 || chars.Length <= charIndex)
+                       throw new ArgumentOutOfRangeException ("charIndex");
+       }
+
+       void CheckArguments (byte [] bytes, int byteIndex, int byteCount)
+       {
+               if (bytes == null)
+                       throw new ArgumentNullException ("bytes");
+               if (byteIndex < 0 || bytes.Length <= byteIndex)
+                       throw new ArgumentOutOfRangeException ("byteIndex");
+               if (byteCount < 0 || bytes.Length < byteIndex + byteCount)
+                       throw new ArgumentOutOfRangeException ("byteCount");
+       }
+
+       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");
+       }
+#endif
+
+}; // class Decoder
+
+}; // namespace System.Text