|
|
@@ -1,384 +1,815 @@
|
|
|
-// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
|
|
-//
|
|
|
-// System.Text.Encoding.cs
|
|
|
-//
|
|
|
-// Author:
|
|
|
-// Sean MacIsaac ([email protected])
|
|
|
-// Dietmar Maurer ([email protected])
|
|
|
-//
|
|
|
-// (C) Ximian, Inc. http://www.ximian.com
|
|
|
-//
|
|
|
-
|
|
|
-using System.Runtime.CompilerServices;
|
|
|
-
|
|
|
-namespace System.Text {
|
|
|
-
|
|
|
- [Serializable]
|
|
|
- public abstract class Encoding {
|
|
|
- private static ASCIIEncoding ascii_encoding;
|
|
|
- private static UnicodeEncoding big_endian_unicode;
|
|
|
- private static UnicodeEncoding unicode_encoding;
|
|
|
- private static UTF7Encoding utf7_encoding;
|
|
|
- private static UTF8Encoding utf8_encoding;
|
|
|
-
|
|
|
- private int codepage;
|
|
|
-
|
|
|
- protected string body_name;
|
|
|
- protected string encoding_name;
|
|
|
- protected string header_name;
|
|
|
- protected string web_name;
|
|
|
-
|
|
|
- protected bool is_browser_display = false;
|
|
|
- protected bool is_browser_save = false;
|
|
|
- protected bool is_mail_news_display = false;
|
|
|
- protected bool is_mail_news_save = false;
|
|
|
-
|
|
|
- private Encoder default_encoder = null;
|
|
|
- private Decoder default_decoder = null;
|
|
|
-
|
|
|
- // used for iconv
|
|
|
- private string iconv_name;
|
|
|
- private bool big_endian;
|
|
|
- private Encoder iconv_encoder = null;
|
|
|
- private Decoder iconv_decoder = null;
|
|
|
-
|
|
|
- protected Encoding()
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- protected Encoding (int codepage)
|
|
|
- {
|
|
|
- this.codepage = codepage;
|
|
|
- }
|
|
|
-
|
|
|
- internal protected Encoding (string name, bool big_endian)
|
|
|
- {
|
|
|
- this.iconv_name = name;
|
|
|
- this.big_endian = big_endian;
|
|
|
-
|
|
|
- iconv_decoder = new IConvDecoder (iconv_name, big_endian);
|
|
|
- iconv_encoder = new IConvEncoder (iconv_name, big_endian);
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding Unicode {
|
|
|
- get {
|
|
|
- if (unicode_encoding == null) {
|
|
|
- unicode_encoding = new UnicodeEncoding();
|
|
|
- }
|
|
|
- return unicode_encoding;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding UTF7 {
|
|
|
- get {
|
|
|
- if (utf7_encoding == null) {
|
|
|
- utf7_encoding = new UTF7Encoding();
|
|
|
- }
|
|
|
- return utf7_encoding;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding UTF8 {
|
|
|
- get {
|
|
|
- if (utf8_encoding == null) {
|
|
|
- utf8_encoding = new UTF8Encoding();
|
|
|
- }
|
|
|
- return utf8_encoding;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding ASCII {
|
|
|
- get {
|
|
|
- if (ascii_encoding == null)
|
|
|
- ascii_encoding = new ASCIIEncoding ();
|
|
|
- return ascii_encoding;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding BigEndianUnicode {
|
|
|
- get {
|
|
|
- if (big_endian_unicode == null)
|
|
|
- big_endian_unicode = new UnicodeEncoding (true, true);
|
|
|
- return big_endian_unicode;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string BodyName {
|
|
|
- get {
|
|
|
- return body_name;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int CodePage {
|
|
|
- get {
|
|
|
- return codepage;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static Encoding Default {
|
|
|
- get {
|
|
|
- return ASCII;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string EncodingName {
|
|
|
- get {
|
|
|
- return encoding_name;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string HeaderName {
|
|
|
- get {
|
|
|
- return header_name;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool IsBrowserDisplay {
|
|
|
- get {
|
|
|
- return is_browser_display;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool IsBrowserSave {
|
|
|
- get {
|
|
|
- return is_browser_save;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool IsMailNewsDisplay {
|
|
|
- get {
|
|
|
- return is_mail_news_display;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool IsMailNewsSave {
|
|
|
- get {
|
|
|
- return is_mail_news_save;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string WebName {
|
|
|
- get {
|
|
|
- return web_name;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- public virtual int WindowsCodePage {
|
|
|
- get {
|
|
|
- // FIXME
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes)
|
|
|
- {
|
|
|
- return dstEncoding.GetBytes (srcEncoding.GetChars (bytes));
|
|
|
- }
|
|
|
-
|
|
|
- public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
|
|
|
- byte[] bytes, int index, int count)
|
|
|
- {
|
|
|
- return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, index, count));
|
|
|
- }
|
|
|
-
|
|
|
- public override bool Equals (object value)
|
|
|
- {
|
|
|
- if (!(value is Encoding))
|
|
|
- return false;
|
|
|
-
|
|
|
- Encoding e = (Encoding) value;
|
|
|
-
|
|
|
- if (e.codepage != codepage)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (e.body_name != body_name)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (e.encoding_name != encoding_name)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (e.header_name != header_name)
|
|
|
- return false;
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetByteCount (char[] chars)
|
|
|
- {
|
|
|
- return GetByteCount (chars, 0, chars.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetByteCount (string s)
|
|
|
- {
|
|
|
- char [] chars = s.ToCharArray ();
|
|
|
-
|
|
|
- return GetByteCount (chars, 0, chars.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetByteCount (char[] chars, int index, int count)
|
|
|
- {
|
|
|
- return iconv_encoder.GetByteCount (chars, index, count, false);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual byte[] GetBytes(char[] chars)
|
|
|
- {
|
|
|
- return GetBytes (chars, 0, chars.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual byte[] GetBytes(string s)
|
|
|
- {
|
|
|
- char [] chars = s.ToCharArray ();
|
|
|
- return GetBytes (chars, 0, chars.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual byte[] GetBytes(char[] chars, int index, int count)
|
|
|
- {
|
|
|
- int bc = GetByteCount (chars, index, count);
|
|
|
- byte [] bytes = new byte [bc];
|
|
|
-
|
|
|
- int len = GetBytes (chars, index, count, bytes, 0);
|
|
|
- byte [] res = new byte [len];
|
|
|
-
|
|
|
- Array.Copy (bytes, res, len);
|
|
|
-
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetBytes (char[] chars, int charIndex, int charCount,
|
|
|
- byte[] bytes, int byteIndex)
|
|
|
- {
|
|
|
- return iconv_encoder.GetBytes (chars, charIndex, charCount, bytes, byteIndex, true);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetBytes(string s, int charIndex, int charCount,
|
|
|
- byte[] bytes, int byteIndex)
|
|
|
- {
|
|
|
- return GetBytes (s.ToCharArray (), charIndex, charCount, bytes, byteIndex);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetCharCount (byte[] bytes)
|
|
|
- {
|
|
|
- return GetCharCount (bytes, 0, bytes.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetCharCount (byte[] bytes, int index, int count)
|
|
|
- {
|
|
|
- return iconv_decoder.GetCharCount (bytes, index, count);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual char[] GetChars (byte[] bytes)
|
|
|
- {
|
|
|
- return GetChars (bytes, 0, bytes.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual char[] GetChars (byte[] bytes, int index, int count)
|
|
|
- {
|
|
|
- int cc = GetMaxCharCount (count);
|
|
|
- char [] chars = new char [cc];
|
|
|
-
|
|
|
- int len = GetChars (bytes, index, count, chars, 0);
|
|
|
- char [] res = new char [len];
|
|
|
-
|
|
|
- Array.Copy (chars, res, len);
|
|
|
-
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
|
|
|
- {
|
|
|
- return iconv_decoder.GetChars (bytes, byteIndex, byteCount, chars, charIndex);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual Decoder GetDecoder()
|
|
|
- {
|
|
|
- if (iconv_name != null)
|
|
|
- return new IConvDecoder (iconv_name, big_endian);
|
|
|
-
|
|
|
- if (default_decoder == null)
|
|
|
- default_decoder = new DefaultDecoder (this);
|
|
|
-
|
|
|
- return default_decoder;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual Encoder GetEncoder()
|
|
|
- {
|
|
|
- if (iconv_name != null)
|
|
|
- return new IConvEncoder (iconv_name, big_endian);
|
|
|
-
|
|
|
- if (default_encoder == null)
|
|
|
- default_encoder = new DefaultEncoder (this);
|
|
|
-
|
|
|
- return default_encoder;
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- public static Encoding GetEncoding (int codepage)
|
|
|
- {
|
|
|
- // FIXME
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- public static Encoding GetEncoding (string name)
|
|
|
- {
|
|
|
- // FIXME
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- public override int GetHashCode()
|
|
|
- {
|
|
|
- // FIXME
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- public abstract int GetMaxByteCount (int charCount);
|
|
|
-
|
|
|
- public abstract int GetMaxCharCount (int byteCount);
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- public virtual byte[] GetPreamble()
|
|
|
- {
|
|
|
- // FIXME
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string GetString(byte[] bytes)
|
|
|
- {
|
|
|
- return GetString (bytes, 0, bytes.Length);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual string GetString(byte[] bytes, int index, int count)
|
|
|
- {
|
|
|
- char [] chars = GetChars (bytes, index, count);
|
|
|
-
|
|
|
- return new String (chars);
|
|
|
- }
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static IntPtr IConvNewEncoder (string name, bool big_endian);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static IntPtr IConvNewDecoder (string name, bool big_endian);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static void IConvReset (IntPtr converter);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static int IConvGetByteCount (IntPtr converter, char[] chars,
|
|
|
- int index, int count);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static int IConvGetBytes (IntPtr converter, char[] chars, int charIndex,
|
|
|
- int charCount, byte[] bytes, int byteIndex);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static int IConvGetCharCount (IntPtr converter, byte[] bytes,
|
|
|
- int index, int count);
|
|
|
-
|
|
|
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
|
|
|
- internal extern static int IConvGetChars (IntPtr converter, byte[] bytes, int byteIndex,
|
|
|
- int byteCount, char[] chars, int charIndex);
|
|
|
- }
|
|
|
-}
|
|
|
+/*
|
|
|
+ * Encoding.cs - Implementation of the "System.Text.Encoding" class.
|
|
|
+ *
|
|
|
+ * Copyright (c) 2001, 2002 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
|
|
|
+{
|
|
|
+
|
|
|
+using System;
|
|
|
+using System.Reflection;
|
|
|
+using System.Globalization;
|
|
|
+using System.Security;
|
|
|
+
|
|
|
+public abstract class Encoding
|
|
|
+{
|
|
|
+ // Code page used by this encoding.
|
|
|
+ internal int codePage;
|
|
|
+
|
|
|
+ // Constructor.
|
|
|
+ protected Encoding()
|
|
|
+ {
|
|
|
+ codePage = 0;
|
|
|
+ }
|
|
|
+#if ECMA_COMPAT
|
|
|
+ protected internal
|
|
|
+#else
|
|
|
+ protected
|
|
|
+#endif
|
|
|
+ Encoding(int codePage)
|
|
|
+ {
|
|
|
+ this.codePage = codePage;
|
|
|
+ }
|
|
|
+
|
|
|
+ // until we change the callers:
|
|
|
+ internal static string _ (string arg) {
|
|
|
+ return arg;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert between two encodings.
|
|
|
+ public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
|
|
|
+ byte[] bytes)
|
|
|
+ {
|
|
|
+ if(srcEncoding == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("srcEncoding");
|
|
|
+ }
|
|
|
+ if(dstEncoding == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("dstEncoding");
|
|
|
+ }
|
|
|
+ if(bytes == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("bytes");
|
|
|
+ }
|
|
|
+ return dstEncoding.GetBytes(srcEncoding.GetChars
|
|
|
+ (bytes, 0, bytes.Length));
|
|
|
+ }
|
|
|
+ public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
|
|
|
+ byte[] bytes, int index, int count)
|
|
|
+ {
|
|
|
+ if(srcEncoding == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("srcEncoding");
|
|
|
+ }
|
|
|
+ if(dstEncoding == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("dstEncoding");
|
|
|
+ }
|
|
|
+ if(bytes == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("bytes");
|
|
|
+ }
|
|
|
+ if(index < 0 || index > bytes.Length)
|
|
|
+ {
|
|
|
+ throw new ArgumentOutOfRangeException
|
|
|
+ ("index", _("ArgRange_Array"));
|
|
|
+ }
|
|
|
+ if(count < 0 || (bytes.Length - index) < count)
|
|
|
+ {
|
|
|
+ throw new ArgumentOutOfRangeException
|
|
|
+ ("count", _("ArgRange_Array"));
|
|
|
+ }
|
|
|
+ return dstEncoding.GetBytes(srcEncoding.GetChars
|
|
|
+ (bytes, index, count));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Determine if two Encoding objects are equal.
|
|
|
+ public override bool Equals(Object obj)
|
|
|
+ {
|
|
|
+ Encoding enc = (obj as Encoding);
|
|
|
+ if(enc != null)
|
|
|
+ {
|
|
|
+ return (codePage == enc.codePage);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the number of characters needed to encode a character buffer.
|
|
|
+ public abstract int GetByteCount(char[] chars, int index, int count);
|
|
|
+
|
|
|
+ // Convenience wrappers for "GetByteCount".
|
|
|
+ public virtual int GetByteCount(String s)
|
|
|
+ {
|
|
|
+ if(s != null)
|
|
|
+ {
|
|
|
+ char[] chars = s.ToCharArray();
|
|
|
+ return GetByteCount(chars, 0, chars.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("s");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public virtual int GetByteCount(char[] chars)
|
|
|
+ {
|
|
|
+ if(chars != null)
|
|
|
+ {
|
|
|
+ return GetByteCount(chars, 0, chars.Length);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("chars");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the bytes that result from encoding a character buffer.
|
|
|
+ public abstract int GetBytes(char[] chars, int charIndex, int charCount,
|
|
|
+ byte[] bytes, int byteIndex);
|
|
|
+
|
|
|
+ // Convenience wrappers for "GetBytes".
|
|
|
+ public virtual int GetBytes(String s, int charIndex, int charCount,
|
|
|
+ byte[] bytes, int byteIndex)
|
|
|
+ {
|
|
|
+ if(s == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("s");
|
|
|
+ }
|
|
|
+ return GetBytes(s.ToCharArray(), charIndex, charCount,
|
|
|
+ bytes, byteIndex);
|
|
|
+ }
|
|
|
+ public virtual byte[] GetBytes(String s)
|
|
|
+ {
|
|
|
+ if(s == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("s");
|
|
|
+ }
|
|
|
+ char[] chars = s.ToCharArray();
|
|
|
+ int numBytes = GetByteCount(chars, 0, chars.Length);
|
|
|
+ byte[] bytes = new byte [numBytes];
|
|
|
+ GetBytes(chars, 0, chars.Length, bytes, 0);
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+ public virtual byte[] GetBytes(char[] chars, int index, int count)
|
|
|
+ {
|
|
|
+ int numBytes = GetByteCount(chars, index, count);
|
|
|
+ byte[] bytes = new byte [numBytes];
|
|
|
+ GetBytes(chars, index, count, bytes, 0);
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+ public virtual byte[] GetBytes(char[] chars)
|
|
|
+ {
|
|
|
+ int numBytes = GetByteCount(chars, 0, chars.Length);
|
|
|
+ byte[] bytes = new byte [numBytes];
|
|
|
+ GetBytes(chars, 0, chars.Length, bytes, 0);
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the number of characters needed to decode a byte buffer.
|
|
|
+ public abstract int GetCharCount(byte[] bytes, int index, int count);
|
|
|
+
|
|
|
+ // Convenience wrappers for "GetCharCount".
|
|
|
+ public virtual int GetCharCount(byte[] bytes)
|
|
|
+ {
|
|
|
+ if(bytes == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("bytes");
|
|
|
+ }
|
|
|
+ return GetCharCount(bytes, 0, bytes.Length);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the characters that result from decoding a byte buffer.
|
|
|
+ public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount,
|
|
|
+ char[] chars, int charIndex);
|
|
|
+
|
|
|
+ // Convenience wrappers for "GetChars".
|
|
|
+ public virtual char[] GetChars(byte[] bytes, int index, int count)
|
|
|
+ {
|
|
|
+ int numChars = GetCharCount(bytes, index, count);
|
|
|
+ char[] chars = new char [numChars];
|
|
|
+ GetChars(bytes, index, count, chars, 0);
|
|
|
+ return chars;
|
|
|
+ }
|
|
|
+ public virtual char[] GetChars(byte[] bytes)
|
|
|
+ {
|
|
|
+ if(bytes == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("bytes");
|
|
|
+ }
|
|
|
+ int numChars = GetCharCount(bytes, 0, bytes.Length);
|
|
|
+ char[] chars = new char [numChars];
|
|
|
+ GetChars(bytes, 0, bytes.Length, chars, 0);
|
|
|
+ return chars;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get a decoder that forwards requests to this object.
|
|
|
+ public virtual Decoder GetDecoder()
|
|
|
+ {
|
|
|
+ return new ForwardingDecoder(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get an encoder that forwards requests to this object.
|
|
|
+ public virtual Encoder GetEncoder()
|
|
|
+ {
|
|
|
+ return new ForwardingEncoder(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Loaded copy of the "I18N" assembly. We need to move
|
|
|
+ // this into a class in "System.Private" eventually.
|
|
|
+ private static Assembly i18nAssembly;
|
|
|
+ private static bool i18nDisabled;
|
|
|
+
|
|
|
+ // Invoke a specific method on the "I18N" manager object.
|
|
|
+ // Returns NULL if the method failed.
|
|
|
+ private static Object InvokeI18N(String name, params Object[] args)
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ // Bail out if we previously detected that there
|
|
|
+ // is insufficent engine support for I18N handling.
|
|
|
+ if(i18nDisabled)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find or load the "I18N" assembly.
|
|
|
+ if(i18nAssembly == null)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ i18nAssembly = Assembly.Load("I18N");
|
|
|
+ }
|
|
|
+ catch(NotImplementedException)
|
|
|
+ {
|
|
|
+ // Assembly loading unsupported by the engine.
|
|
|
+ i18nDisabled = true;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if(i18nAssembly == null)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(SystemException)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find the "I18N.Common.Manager" class.
|
|
|
+ Type managerClass;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ managerClass =
|
|
|
+ i18nAssembly.GetType("I18N.Common.Manager");
|
|
|
+ }
|
|
|
+ catch(NotImplementedException)
|
|
|
+ {
|
|
|
+ // "GetType" is not supported by the engine.
|
|
|
+ i18nDisabled = true;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if(managerClass == null)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the value of the "PrimaryManager" property.
|
|
|
+ Object manager;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ manager = managerClass.InvokeMember
|
|
|
+ ("PrimaryManager",
|
|
|
+ BindingFlags.GetProperty |
|
|
|
+ BindingFlags.Static |
|
|
|
+ BindingFlags.Public,
|
|
|
+ null, null, null, null, null, null);
|
|
|
+ if(manager == null)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(MissingMethodException)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ catch(SecurityException)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ catch(NotImplementedException)
|
|
|
+ {
|
|
|
+ // "InvokeMember" is not supported by the engine.
|
|
|
+ i18nDisabled = true;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Invoke the requested method on the manager.
|
|
|
+ try
|
|
|
+ {
|
|
|
+ return managerClass.InvokeMember
|
|
|
+ (name,
|
|
|
+ BindingFlags.InvokeMethod |
|
|
|
+ BindingFlags.Instance |
|
|
|
+ BindingFlags.Public,
|
|
|
+ null, manager, args, null, null, null);
|
|
|
+ }
|
|
|
+ catch(MissingMethodException)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ catch(SecurityException)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get an encoder for a specific code page.
|
|
|
+#if ECMA_COMPAT
|
|
|
+ private
|
|
|
+#else
|
|
|
+ public
|
|
|
+#endif
|
|
|
+ static Encoding GetEncoding(int codePage)
|
|
|
+ {
|
|
|
+ // Check for the builtin code pages first.
|
|
|
+ switch(codePage)
|
|
|
+ {
|
|
|
+ case 0: return Default;
|
|
|
+
|
|
|
+ case ASCIIEncoding.ASCII_CODE_PAGE:
|
|
|
+ return ASCII;
|
|
|
+
|
|
|
+ case UTF7Encoding.UTF7_CODE_PAGE:
|
|
|
+ return UTF7;
|
|
|
+
|
|
|
+ case UTF8Encoding.UTF8_CODE_PAGE:
|
|
|
+ return UTF8;
|
|
|
+
|
|
|
+ case UnicodeEncoding.UNICODE_CODE_PAGE:
|
|
|
+ return Unicode;
|
|
|
+
|
|
|
+ case UnicodeEncoding.BIG_UNICODE_CODE_PAGE:
|
|
|
+ return BigEndianUnicode;
|
|
|
+
|
|
|
+ case Latin1Encoding.ISOLATIN_CODE_PAGE:
|
|
|
+ return ISOLatin1;
|
|
|
+
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Try to obtain a code page handler from the I18N handler.
|
|
|
+ Encoding enc = (Encoding)(InvokeI18N("GetEncoding", codePage));
|
|
|
+ if(enc != null)
|
|
|
+ {
|
|
|
+ return enc;
|
|
|
+ }
|
|
|
+
|
|
|
+#if false
|
|
|
+ // Build a code page class name.
|
|
|
+ String cpName = "System.Text.CP" + codePage.ToString();
|
|
|
+
|
|
|
+ // Look for a code page converter in this assembly.
|
|
|
+ Assembly assembly = Assembly.GetExecutingAssembly();
|
|
|
+ Type type = assembly.GetType(cpName);
|
|
|
+ if(type != null)
|
|
|
+ {
|
|
|
+ return (Encoding)(Activator.CreateInstance(type));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Look in any assembly, in case the application
|
|
|
+ // has provided its own code page handler.
|
|
|
+ type = Type.GetType(cpName);
|
|
|
+ if(type != null)
|
|
|
+ {
|
|
|
+ return (Encoding)(Activator.CreateInstance(type));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ // We have no idea how to handle this code page.
|
|
|
+ throw new NotSupportedException
|
|
|
+ (String.Format
|
|
|
+ (_("NotSupp_CodePage"), codePage.ToString()));
|
|
|
+ }
|
|
|
+
|
|
|
+#if !ECMA_COMPAT
|
|
|
+
|
|
|
+ // Table of builtin web encoding names and the corresponding code pages.
|
|
|
+ private static readonly String[] encodingNames =
|
|
|
+ {"us-ascii", "utf-7", "utf-8", "utf-16",
|
|
|
+ "unicodeFFFE", "iso-8859-1"};
|
|
|
+ private static readonly int[] encodingCodePages =
|
|
|
+ {ASCIIEncoding.ASCII_CODE_PAGE,
|
|
|
+ UTF7Encoding.UTF7_CODE_PAGE,
|
|
|
+ UTF8Encoding.UTF8_CODE_PAGE,
|
|
|
+ UnicodeEncoding.UNICODE_CODE_PAGE,
|
|
|
+ UnicodeEncoding.BIG_UNICODE_CODE_PAGE,
|
|
|
+ Latin1Encoding.ISOLATIN_CODE_PAGE};
|
|
|
+
|
|
|
+ // Get an encoding object for a specific web encoding name.
|
|
|
+ public static Encoding GetEncoding(String name)
|
|
|
+ {
|
|
|
+ // Validate the parameters.
|
|
|
+ if(name == null)
|
|
|
+ {
|
|
|
+ throw new ArgumentNullException("name");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Search the table for a name match.
|
|
|
+ int posn;
|
|
|
+ for(posn = 0; posn < encodingNames.Length; ++posn)
|
|
|
+ {
|
|
|
+ if(String.Compare(name, encodingNames[posn], true,
|
|
|
+ CultureInfo.InvariantCulture) == 0)
|
|
|
+ {
|
|
|
+ return GetEncoding(encodingCodePages[posn]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Try to obtain a web encoding handler from the I18N handler.
|
|
|
+ Encoding enc = (Encoding)(InvokeI18N("GetEncoding", name));
|
|
|
+ if(enc != null)
|
|
|
+ {
|
|
|
+ return enc;
|
|
|
+ }
|
|
|
+
|
|
|
+#if false
|
|
|
+ // Build a web encoding class name.
|
|
|
+ String encName = "System.Text.ENC" +
|
|
|
+ name.ToLower(CultureInfo.InvariantCulture)
|
|
|
+ .Replace('-', '_');
|
|
|
+
|
|
|
+ // Look for a code page converter in this assembly.
|
|
|
+ Assembly assembly = Assembly.GetExecutingAssembly();
|
|
|
+ Type type = assembly.GetType(encName);
|
|
|
+ if(type != null)
|
|
|
+ {
|
|
|
+ return (Encoding)(Activator.CreateInstance(type));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Look in any assembly, in case the application
|
|
|
+ // has provided its own code page handler.
|
|
|
+ type = Type.GetType(encName);
|
|
|
+ if(type != null)
|
|
|
+ {
|
|
|
+ return (Encoding)(Activator.CreateInstance(type));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ // We have no idea how to handle this encoding name.
|
|
|
+ throw new NotSupportedException
|
|
|
+ (String.Format(_("NotSupp_EncodingName"), name));
|
|
|
+ }
|
|
|
+
|
|
|
+#endif // !ECMA_COMPAT
|
|
|
+
|
|
|
+ // Get a hash code for this instance.
|
|
|
+ public override int GetHashCode()
|
|
|
+ {
|
|
|
+ return codePage;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the maximum number of bytes needed to encode a
|
|
|
+ // specified number of characters.
|
|
|
+ public abstract int GetMaxByteCount(int charCount);
|
|
|
+
|
|
|
+ // Get the maximum number of characters needed to decode a
|
|
|
+ // specified number of bytes.
|
|
|
+ public abstract int GetMaxCharCount(int byteCount);
|
|
|
+
|
|
|
+ // Get the identifying preamble for this encoding.
|
|
|
+ public virtual byte[] GetPreamble()
|
|
|
+ {
|
|
|
+ return new byte [0];
|
|
|
+ }
|
|
|
+
|
|
|
+ // Decode a buffer of bytes into a string.
|
|
|
+ public virtual String GetString(byte[] bytes, int index, int count)
|
|
|
+ {
|
|
|
+ return new String(GetChars(bytes, index, count));
|
|
|
+ }
|
|
|
+ public virtual String GetString(byte[] bytes)
|
|
|
+ {
|
|
|
+ return new String(GetChars(bytes));
|
|
|
+ }
|
|
|
+
|
|
|
+#if !ECMA_COMPAT
|
|
|
+
|
|
|
+ // Get the mail body name for this encoding.
|
|
|
+ public virtual String BodyName
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the code page represented by this object.
|
|
|
+ public virtual int CodePage
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return codePage;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the human-readable name for this encoding.
|
|
|
+ public virtual String EncodingName
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the mail agent header name for this encoding.
|
|
|
+ public virtual String HeaderName
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Determine if this encoding can be displayed in a Web browser.
|
|
|
+ public virtual bool IsBrowserDisplay
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Determine if this encoding can be saved from a Web browser.
|
|
|
+ public virtual bool IsBrowserSave
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Determine if this encoding can be displayed in a mail/news agent.
|
|
|
+ public virtual bool IsMailNewsDisplay
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Determine if this encoding can be saved from a mail/news agent.
|
|
|
+ public virtual bool IsMailNewsSave
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the IANA-preferred Web name for this encoding.
|
|
|
+ public virtual String WebName
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the Windows code page represented by this object.
|
|
|
+ public virtual int WindowsCodePage
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ // We make no distinction between normal and
|
|
|
+ // Windows code pages in this implementation.
|
|
|
+ return codePage;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#endif // !ECMA_COMPAT
|
|
|
+
|
|
|
+ // Storage for standard encoding objects.
|
|
|
+ private static Encoding asciiEncoding = null;
|
|
|
+ private static Encoding bigEndianEncoding = null;
|
|
|
+ private static Encoding defaultEncoding = null;
|
|
|
+ private static Encoding utf7Encoding = null;
|
|
|
+ private static Encoding utf8Encoding = null;
|
|
|
+ private static Encoding unicodeEncoding = null;
|
|
|
+ private static Encoding isoLatin1Encoding = null;
|
|
|
+
|
|
|
+ // Get the standard ASCII encoding object.
|
|
|
+ public static Encoding ASCII
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(asciiEncoding == null)
|
|
|
+ {
|
|
|
+ asciiEncoding = new ASCIIEncoding();
|
|
|
+ }
|
|
|
+ return asciiEncoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the standard big-endian Unicode encoding object.
|
|
|
+ public static Encoding BigEndianUnicode
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(bigEndianEncoding == null)
|
|
|
+ {
|
|
|
+ bigEndianEncoding = new UnicodeEncoding(true, true);
|
|
|
+ }
|
|
|
+ return bigEndianEncoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the default encoding object.
|
|
|
+ public static Encoding Default
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(defaultEncoding == null)
|
|
|
+ {
|
|
|
+ // See if the underlying system knows what
|
|
|
+ // code page handler we should be using.
|
|
|
+ int codePage = DefaultEncoding.InternalCodePage();
|
|
|
+ if(codePage != 0)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ defaultEncoding = GetEncoding(codePage);
|
|
|
+ }
|
|
|
+ catch(NotSupportedException)
|
|
|
+ {
|
|
|
+ defaultEncoding = new DefaultEncoding();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ defaultEncoding = new DefaultEncoding();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return defaultEncoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the ISO Latin1 encoding object.
|
|
|
+ private static Encoding ISOLatin1
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(isoLatin1Encoding == null)
|
|
|
+ {
|
|
|
+ isoLatin1Encoding = new Latin1Encoding();
|
|
|
+ }
|
|
|
+ return isoLatin1Encoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the standard UTF-7 encoding object.
|
|
|
+#if ECMA_COMPAT
|
|
|
+ private
|
|
|
+#else
|
|
|
+ public
|
|
|
+#endif
|
|
|
+ static Encoding UTF7
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(utf7Encoding == null)
|
|
|
+ {
|
|
|
+ utf7Encoding = new UTF7Encoding();
|
|
|
+ }
|
|
|
+ return utf7Encoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the standard UTF-8 encoding object.
|
|
|
+ public static Encoding UTF8
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(utf8Encoding == null)
|
|
|
+ {
|
|
|
+ utf8Encoding = new UTF8Encoding();
|
|
|
+ }
|
|
|
+ return utf8Encoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the standard little-endian Unicode encoding object.
|
|
|
+ public static Encoding Unicode
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ lock(typeof(Encoding))
|
|
|
+ {
|
|
|
+ if(unicodeEncoding == null)
|
|
|
+ {
|
|
|
+ unicodeEncoding = new UnicodeEncoding();
|
|
|
+ }
|
|
|
+ return unicodeEncoding;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Forwarding decoder implementation.
|
|
|
+ private sealed class ForwardingDecoder : Decoder
|
|
|
+ {
|
|
|
+ private Encoding encoding;
|
|
|
+
|
|
|
+ // Constructor.
|
|
|
+ public ForwardingDecoder(Encoding enc)
|
|
|
+ {
|
|
|
+ encoding = enc;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Override inherited methods.
|
|
|
+ public override int GetCharCount(byte[] bytes, int index, int count)
|
|
|
+ {
|
|
|
+ return encoding.GetCharCount(bytes, index, count);
|
|
|
+ }
|
|
|
+ public override int GetChars(byte[] bytes, int byteIndex,
|
|
|
+ int byteCount, char[] chars,
|
|
|
+ int charIndex)
|
|
|
+ {
|
|
|
+ return encoding.GetChars(bytes, byteIndex, byteCount,
|
|
|
+ chars, charIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ } // class ForwardingDecoder
|
|
|
+
|
|
|
+ // Forwarding encoder implementation.
|
|
|
+ private sealed class ForwardingEncoder : Encoder
|
|
|
+ {
|
|
|
+ private Encoding encoding;
|
|
|
+
|
|
|
+ // Constructor.
|
|
|
+ public ForwardingEncoder(Encoding enc)
|
|
|
+ {
|
|
|
+ encoding = enc;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Override inherited methods.
|
|
|
+ public override int GetByteCount(char[] chars, int index,
|
|
|
+ int count, bool flush)
|
|
|
+ {
|
|
|
+ return encoding.GetByteCount(chars, index, count);
|
|
|
+ }
|
|
|
+ public override int GetBytes(char[] chars, int charIndex,
|
|
|
+ int charCount, byte[] bytes,
|
|
|
+ int byteCount, bool flush)
|
|
|
+ {
|
|
|
+ return encoding.GetBytes(chars, charIndex, charCount,
|
|
|
+ bytes, byteCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ } // class ForwardingEncoder
|
|
|
+
|
|
|
+}; // class Encoding
|
|
|
+
|
|
|
+}; // namespace System.Text
|