-//
-// System.Text.ASCIIEncoding.cs
-//
-// Author:
-// Sean MacIsaac (macisaac@ximian.com)
-// Dietmar Maurer (dietmar@ximian.com)
-//
-// (C) Ximian, Inc. http://www.ximian.com
-//
+/*
+ * ASCIIEncoding.cs - Implementation of the "System.Text.ASCIIEncoding" class.
+ *
+ * Copyright (c) 2001 Southern Storm Software, Pty Ltd
+ * Copyright (C) 2003 Novell, Inc.
+ * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+ *
+ * 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
+{
+
+using System;
+using System.Runtime.InteropServices;
+
+[Serializable]
+#if NET_2_0
+[ComVisible (true)]
+#endif
+[MonoTODO ("Serialization format not compatible with .NET")]
+public class ASCIIEncoding : Encoding
+{
+ // Magic number used by Windows for "ASCII".
+ internal const int ASCII_CODE_PAGE = 20127;
+
+ // Constructor.
+ public ASCIIEncoding () : base(ASCII_CODE_PAGE) {
+ body_name = header_name = web_name= "us-ascii";
+ encoding_name = "US-ASCII";
+ is_mail_news_display = true;
+ is_mail_news_save = true;
+ }
+#if NET_2_0
+ [ComVisible (false)]
+ public override bool IsSingleByte {
+ get { return true; }
+ }
+#endif
-namespace System.Text {
-
- [Serializable]
- public class ASCIIEncoding : Encoding
+ // Get the number of bytes needed to encode a character buffer.
+ public override int GetByteCount (char[] chars, int index, int count)
{
- public ASCIIEncoding () : base ()
- {
- encoding_name = "US-ASCII";
- body_name = "us-ascii";
- header_name = "us-ascii";
- web_name = "us-ascii";
- is_browser_display = false;
- is_browser_save = false;
- is_mail_news_display = true;
- is_mail_news_save = true;
+ if (chars == null) {
+ throw new ArgumentNullException ("chars");
}
-
- public override int GetByteCount (string chars)
- {
- if (chars == null)
- throw new ArgumentNullException ();
-
- return chars.Length;
+ if (index < 0 || index > chars.Length) {
+ throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
}
-
- public override int GetByteCount (char[] chars)
- {
- if (chars == null)
- throw new ArgumentNullException ();
-
- return chars.Length;
+ if (count < 0 || count > (chars.Length - index)) {
+ throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
}
+ return count;
+ }
- public override int GetByteCount (char[] chars, int index, int count)
- {
- if (chars == null)
- throw new ArgumentNullException ();
-
- if ((index < 0) || (count <= 0) || ((index + count) > chars.Length))
- throw new ArgumentOutOfRangeException ();
-
- return count;
+ // Convenience wrappers for "GetByteCount".
+ public override int GetByteCount (String s)
+ {
+ if (s == null) {
+ throw new ArgumentNullException ("s");
}
+ return s.Length;
+ }
- public override int GetBytes (char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- if ((bytes == null) || (chars == null))
- throw new ArgumentNullException ();
+ // Get the bytes that result from encoding a character buffer.
+ public override int GetBytes (char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+#if NET_2_0
+// well, yes, I know this #if is ugly, but I think it is the simplest switch.
+ EncoderFallbackBuffer buffer = null;
+ char [] fallback_chars = null;
+ return GetBytes (chars, charIndex, charCount, bytes,
+ byteIndex, ref buffer, ref fallback_chars);
+ }
- if ((byteIndex < 0) || (charIndex < 0) || (charCount < 0) ||
- ((charIndex + charCount) > chars.Length) ||
- (byteIndex >= bytes.Length))
- throw new ArgumentOutOfRangeException ();
+ int GetBytes (char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex,
+ ref EncoderFallbackBuffer buffer,
+ ref char [] fallback_chars)
+ {
+#endif
+ if (chars == null) {
+ throw new ArgumentNullException ("chars");
+ }
+ if (bytes == null) {
+ throw new ArgumentNullException ("bytes");
+ }
+ if (charIndex < 0 || charIndex > chars.Length) {
+ throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
+ }
+ if (charCount < 0 || charCount > (chars.Length - charIndex)) {
+ throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length) {
+ throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
+ }
+ if ((bytes.Length - byteIndex) < charCount) {
+ throw new ArgumentException (_("Arg_InsufficientSpace"));
+ }
+ int count = charCount;
+ char ch;
+ while (count-- > 0) {
+ ch = chars [charIndex++];
+ if (ch < (char)0x80) {
+ bytes [byteIndex++] = (byte)ch;
+ } else {
+#if NET_2_0
+ if (buffer == null)
+ buffer = EncoderFallback.CreateFallbackBuffer ();
+ if (Char.IsSurrogate (ch) && count > 1 &&
+ Char.IsSurrogate (chars [charIndex]))
+ buffer.Fallback (ch, chars [charIndex], charIndex++ - 1);
+ else
+ buffer.Fallback (ch, charIndex - 1);
+ if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
+ fallback_chars = new char [buffer.Remaining];
+ for (int i = 0; i < fallback_chars.Length; i++)
+ fallback_chars [i] = buffer.GetNextChar ();
+ byteIndex += GetBytes (fallback_chars, 0,
+ fallback_chars.Length, bytes, byteIndex,
+ ref buffer, ref fallback_chars);
+#else
+ bytes [byteIndex++] = (byte)'?';
+#endif
+ }
+ }
+ return charCount;
+ }
- if ((bytes.Length - byteIndex) < charCount)
- throw new ArgumentException ();
+ // Convenience wrappers for "GetBytes".
+ public override int GetBytes (String s, int charIndex, int charCount, byte[] bytes, int byteIndex)
+ {
+#if NET_2_0
+// I know this #if is ugly, but I think it is the simplest switch.
+ EncoderFallbackBuffer buffer = null;
+ char [] fallback_chars = null;
+ return GetBytes (s, charIndex, charCount, bytes, byteIndex,
+ ref buffer, ref fallback_chars);
+ }
- for (int i = 0; i < charCount; i++)
- if (chars[charIndex+i] > 0x7f)
- bytes[byteIndex+i] = (byte) '?';
+ int GetBytes (String s, int charIndex, int charCount,
+ byte[] bytes, int byteIndex,
+ ref EncoderFallbackBuffer buffer,
+ ref char [] fallback_chars)
+ {
+#endif
+ if (s == null) {
+ throw new ArgumentNullException ("s");
+ }
+ if (bytes == null) {
+ throw new ArgumentNullException ("bytes");
+ }
+ if (charIndex < 0 || charIndex > s.Length) {
+ throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_StringIndex"));
+ }
+ if (charCount < 0 || charCount > (s.Length - charIndex)) {
+ throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_StringRange"));
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length) {
+ throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
+ }
+ if ((bytes.Length - byteIndex) < charCount) {
+ throw new ArgumentException (_("Arg_InsufficientSpace"));
+ }
+ int count = charCount;
+ char ch;
+ while (count-- > 0) {
+ ch = s [charIndex++];
+ if (ch < (char)0x80) {
+ bytes [byteIndex++] = (byte)ch;
+ } else {
+#if NET_2_0
+ if (buffer == null)
+ buffer = EncoderFallback.CreateFallbackBuffer ();
+ if (Char.IsSurrogate (ch) && count > 1 &&
+ Char.IsSurrogate (s [charIndex]))
+ buffer.Fallback (ch, s [charIndex], charIndex++ - 1);
else
- bytes[byteIndex+i] = (byte) chars[charIndex+i];
-
- return charCount;
+ buffer.Fallback (ch, charIndex - 1);
+ if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
+ fallback_chars = new char [buffer.Remaining];
+ for (int i = 0; i < fallback_chars.Length; i++)
+ fallback_chars [i] = buffer.GetNextChar ();
+ byteIndex += GetBytes (fallback_chars, 0,
+ fallback_chars.Length, bytes, byteIndex,
+ ref buffer, ref fallback_chars);
+#else
+ bytes [byteIndex++] = (byte)'?';
+#endif
+ }
}
+ return charCount;
+ }
- public override int GetBytes (string chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return GetBytes (chars.ToCharArray (), charIndex, charCount,
- bytes, byteIndex);
+ // Get the number of characters needed to decode a byte buffer.
+ public override int GetCharCount (byte[] bytes, int index, int count)
+ {
+ if (bytes == null) {
+ throw new ArgumentNullException ("bytes");
}
-
- public override int GetCharCount (byte[] bytes)
- {
- if (bytes == null)
- throw new ArgumentNullException ();
-
- return bytes.Length;
+ if (index < 0 || index > bytes.Length) {
+ throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
}
-
- public override int GetCharCount (byte[] bytes, int index, int count)
- {
- if (bytes == null)
- throw new ArgumentNullException ();
-
- if ((index < 0) || (count <= 0) || ((index + count) > bytes.Length))
- throw new ArgumentOutOfRangeException ();
-
- return count;
+ if (count < 0 || count > (bytes.Length - index)) {
+ throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
}
+ return count;
+ }
- public override int GetChars (byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- if ((bytes == null) || (chars == null))
- throw new ArgumentNullException ();
-
- if ((byteIndex < 0) || (charIndex < 0) || (byteCount < 0) ||
- ((byteIndex + byteCount) > bytes.Length) ||
- (charIndex >= chars.Length))
- throw new ArgumentOutOfRangeException ();
-
- if ((chars.Length - charIndex) < byteCount)
- throw new ArgumentException ();
+ // Get the characters that result from decoding a byte buffer.
+ public override int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
+ {
+#if NET_2_0
+// well, yes, I know this #if is ugly, but I think it is the simplest switch.
+ DecoderFallbackBuffer buffer = null;
+ return GetChars (bytes, byteIndex, byteCount, chars,
+ charIndex, ref buffer);
+ }
- for (int i = 0; i < byteCount; i++)
- if (bytes[byteIndex+i] > 0x7f)
- chars[charIndex+i] = '?';
- else
- chars[charIndex+i] = (char) bytes[byteIndex+i];
+ int GetChars (byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex,
+ ref DecoderFallbackBuffer buffer)
+ {
+#endif
+ if (bytes == null)
+ throw new ArgumentNullException ("bytes");
+ if (chars == null)
+ throw new ArgumentNullException ("chars");
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
+ if (byteCount < 0 || byteCount > (bytes.Length - byteIndex))
+ throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
+
+ if ((chars.Length - charIndex) < byteCount)
+ throw new ArgumentException (_("Arg_InsufficientSpace"));
+
+ int count = byteCount;
+ while (count-- > 0) {
+ char c = (char) bytes [byteIndex++];
+ if (c < '\x80')
+ chars [charIndex++] = c;
+ else {
+#if NET_2_0
+ if (buffer == null)
+ buffer = DecoderFallback.CreateFallbackBuffer ();
+ buffer.Fallback (bytes, byteIndex);
+ while (buffer.Remaining > 0)
+ chars [charIndex++] = buffer.GetNextChar ();
+#else
+ chars [charIndex++] = '?';
+#endif
+ }
+ }
+ return byteCount;
+ }
- return byteCount;
+ // Get the maximum number of bytes needed to encode a
+ // specified number of characters.
+ public override int GetMaxByteCount (int charCount)
+ {
+ if (charCount < 0) {
+ throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative"));
}
+ return charCount;
+ }
- public override int GetMaxByteCount (int charCount)
- {
- if (charCount < 0)
- throw new ArgumentOutOfRangeException ();
+ // Get the maximum number of characters needed to decode a
+ // specified number of bytes.
+ public override int GetMaxCharCount (int byteCount)
+ {
+ if (byteCount < 0) {
+ throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_NonNegative"));
+ }
+ return byteCount;
+ }
- return charCount;
+ // Decode a buffer of bytes into a string.
+ public override String GetString (byte[] bytes, int index, int count)
+ {
+ if (bytes == null) {
+ throw new ArgumentNullException ("bytes");
+ }
+ if (index < 0 || index > bytes.Length) {
+ throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
+ }
+ if (count < 0 || count > (bytes.Length - index)) {
+ throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
}
+ if (count == 0)
+ return String.Empty;
+
+ unsafe {
+ fixed (byte* bytePtr = bytes) {
+ string s = string.InternalAllocateStr (count);
+
+ fixed (char* charPtr = s) {
+ byte* currByte = bytePtr + index;
+ byte* lastByte = currByte + count;
+ char* currChar = charPtr;
+
+ while (currByte < lastByte) {
+#if NET_2_0
+ byte b = currByte++ [0];
+ currChar++ [0] = b <= 0x7F ? (char) b : (char) '?';
+#else
+ // GetString is incompatible with GetChars
+ currChar++ [0] = (char) (currByte++ [0] & 0x7F);
+#endif
+ }
+ }
+
+ return s;
+ }
+ }
+ }
- public override int GetMaxCharCount (int byteCount)
- {
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException ();
+#if NET_2_0
+ [CLSCompliantAttribute (false)]
+ [ComVisible (false)]
+ public unsafe override int GetBytes (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");
+
+ if (byteCount < charCount)
+ throw new ArgumentException ("bytecount is less than the number of bytes required", "byteCount");
+
+ for (int i = 0; i < charCount; i++){
+ char c = chars [i];
+ bytes [i] = (byte) ((c < (char) 0x80) ? c : '?');
+ }
+ return charCount;
+ }
- return byteCount;
+ [CLSCompliantAttribute(false)]
+ [ComVisible (false)]
+ public unsafe override int GetChars (byte *bytes, int byteCount, char *chars, int charCount)
+ {
+ if (bytes == null)
+ throw new ArgumentNullException ("bytes");
+ if (chars == null)
+ throw new ArgumentNullException ("chars");
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException ("charCount");
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException ("byteCount");
+ if (charCount < byteCount)
+ throw new ArgumentException ("charcount is less than the number of bytes required", "charCount");
+
+ for (int i = 0; i < byteCount; i++){
+ byte b = bytes [i];
+ chars [i] = b > 127 ? '?' : (char) b;
}
+ return byteCount;
+
+ }
- public override string GetString (byte[] bytes)
- {
- if (bytes == null)
- throw new ArgumentNullException ();
+ [CLSCompliantAttribute(false)]
+ [ComVisible (false)]
+ public unsafe override int GetCharCount (byte *bytes, int count)
+ {
+ return count;
+ }
- return new String (GetChars (bytes, 0, bytes.Length));
+ [CLSCompliantAttribute(false)]
+ [ComVisible (false)]
+ public unsafe override int GetByteCount (char *chars, int count)
+ {
+ return count;
+ }
+#else
+ // This routine is gone in 2.x
+ public override String GetString (byte[] bytes)
+ {
+ if (bytes == null) {
+ throw new ArgumentNullException ("bytes");
}
- public override string GetString (byte[] bytes, int byteIndex, int byteCount)
- {
- if (bytes == null)
- throw new ArgumentNullException ();
-
- if ((byteIndex < 0) || (byteCount <= 0) ||
- ((byteIndex + byteCount) > bytes.Length))
- throw new ArgumentOutOfRangeException ();
+ return GetString (bytes, 0, bytes.Length);
+ }
+#endif
- return new String (GetChars (bytes, byteIndex, byteCount));
- }
+#if NET_2_0
+ [MonoTODO ("we have simple override to match method signature.")]
+ [ComVisible (false)]
+ public override Decoder GetDecoder ()
+ {
+ return base.GetDecoder ();
+ }
+ [MonoTODO ("we have simple override to match method signature.")]
+ [ComVisible (false)]
+ public override Encoder GetEncoder ()
+ {
+ return base.GetEncoder ();
}
-}
+#endif
+}; // class ASCIIEncoding
+}; // namespace System.Text