2 * Encoding.cs - Implementation of the "System.Text.Encoding" class.
4 * Copyright (c) 2001, 2002 Southern Storm Software, Pty Ltd
5 * Copyright (c) 2002, Ximian, Inc.
6 * Copyright (c) 2003, 2004 Novell, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
31 using System.Reflection;
32 using System.Globalization;
33 using System.Security;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
41 public abstract class Encoding
46 // Code page used by this encoding.
47 internal int codePage;
48 internal int windows_code_page;
50 bool is_readonly = true;
63 Encoding (int codePage)
65 this.codePage = windows_code_page = codePage;
70 // MS has "InternalBestFit{Decoder|Encoder}Fallback
71 // here, but we dunno what they are for.
72 decoder_fallback = DecoderFallback.ReplacementFallback;
73 encoder_fallback = EncoderFallback.ReplacementFallback;
76 case 54936: // GB18030
77 decoder_fallback = DecoderFallback.ReplacementFallback;
78 encoder_fallback = EncoderFallback.ReplacementFallback;
86 decoder_fallback = DecoderFallback.StandardSafeFallback;
87 encoder_fallback = EncoderFallback.StandardSafeFallback;
93 // until we change the callers:
94 internal static string _ (string arg) {
99 DecoderFallback decoder_fallback;
100 EncoderFallback encoder_fallback;
103 public bool IsReadOnly {
104 get { return is_readonly; }
108 public virtual bool IsSingleByte {
109 get { return false; }
113 public DecoderFallback DecoderFallback {
114 get { return decoder_fallback; }
117 throw new InvalidOperationException ("This Encoding is readonly.");
119 throw new ArgumentNullException ();
120 decoder_fallback = value;
125 public EncoderFallback EncoderFallback {
126 get { return encoder_fallback; }
129 throw new InvalidOperationException ("This Encoding is readonly.");
131 throw new ArgumentNullException ();
132 encoder_fallback = value;
136 internal void SetFallbackInternal (EncoderFallback e, DecoderFallback d)
139 encoder_fallback = e;
141 decoder_fallback = d;
145 // Convert between two encodings.
146 public static byte[] Convert (Encoding srcEncoding, Encoding dstEncoding,
149 if (srcEncoding == null) {
150 throw new ArgumentNullException ("srcEncoding");
152 if (dstEncoding == null) {
153 throw new ArgumentNullException ("dstEncoding");
156 throw new ArgumentNullException ("bytes");
158 return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, 0, bytes.Length));
160 public static byte[] Convert (Encoding srcEncoding, Encoding dstEncoding,
161 byte[] bytes, int index, int count)
163 if (srcEncoding == null) {
164 throw new ArgumentNullException ("srcEncoding");
166 if (dstEncoding == null) {
167 throw new ArgumentNullException ("dstEncoding");
170 throw new ArgumentNullException ("bytes");
172 if (index < 0 || index > bytes.Length) {
173 throw new ArgumentOutOfRangeException
174 ("index", _("ArgRange_Array"));
176 if (count < 0 || (bytes.Length - index) < count) {
177 throw new ArgumentOutOfRangeException
178 ("count", _("ArgRange_Array"));
180 return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, index, count));
183 // Determine if two Encoding objects are equal.
184 public override bool Equals (Object value)
186 Encoding enc = (value as Encoding);
189 return codePage == enc.codePage &&
190 DecoderFallback.Equals (enc.DecoderFallback) &&
191 EncoderFallback.Equals (enc.EncoderFallback);
193 return (codePage == enc.codePage);
200 // Get the number of characters needed to encode a character buffer.
201 public abstract int GetByteCount (char[] chars, int index, int count);
203 // Convenience wrappers for "GetByteCount".
204 public virtual int GetByteCount (String s)
207 throw new ArgumentNullException ("s");
213 fixed (char* cptr = s) {
214 return GetByteCount (cptr, s.Length);
218 char[] chars = s.ToCharArray ();
219 return GetByteCount (chars, 0, chars.Length);
222 public virtual int GetByteCount (char[] chars)
225 return GetByteCount (chars, 0, chars.Length);
227 throw new ArgumentNullException ("chars");
231 // Get the bytes that result from encoding a character buffer.
232 public abstract int GetBytes (char[] chars, int charIndex, int charCount,
233 byte[] bytes, int byteIndex);
235 // Convenience wrappers for "GetBytes".
236 public virtual int GetBytes (String s, int charIndex, int charCount,
237 byte[] bytes, int byteIndex)
240 throw new ArgumentNullException ("s");
242 if (charIndex < 0 || charIndex > s.Length)
243 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
244 if (charCount < 0 || charIndex > (s.Length - charCount))
245 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
246 if (byteIndex < 0 || byteIndex > bytes.Length)
247 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
249 if (charCount == 0 || bytes.Length == byteIndex)
252 fixed (char* cptr = s) {
253 fixed (byte* bptr = bytes) {
254 return GetBytes (cptr + charIndex,
257 bytes.Length - byteIndex);
262 return GetBytes (s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
265 public virtual byte[] GetBytes (String s)
268 throw new ArgumentNullException ("s");
273 int byteCount = GetByteCount (s);
277 fixed (char* cptr = s) {
278 byte [] bytes = new byte [byteCount];
279 fixed (byte* bptr = bytes) {
280 GetBytes (cptr, s.Length,
287 char[] chars = s.ToCharArray ();
288 int numBytes = GetByteCount (chars, 0, chars.Length);
289 byte[] bytes = new byte [numBytes];
290 GetBytes (chars, 0, chars.Length, bytes, 0);
294 public virtual byte[] GetBytes (char[] chars, int index, int count)
296 int numBytes = GetByteCount (chars, index, count);
297 byte[] bytes = new byte [numBytes];
298 GetBytes (chars, index, count, bytes, 0);
301 public virtual byte[] GetBytes (char[] chars)
303 int numBytes = GetByteCount (chars, 0, chars.Length);
304 byte[] bytes = new byte [numBytes];
305 GetBytes (chars, 0, chars.Length, bytes, 0);
309 // Get the number of characters needed to decode a byte buffer.
310 public abstract int GetCharCount (byte[] bytes, int index, int count);
312 // Convenience wrappers for "GetCharCount".
313 public virtual int GetCharCount (byte[] bytes)
316 throw new ArgumentNullException ("bytes");
318 return GetCharCount (bytes, 0, bytes.Length);
321 // Get the characters that result from decoding a byte buffer.
322 public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount,
323 char[] chars, int charIndex);
325 // Convenience wrappers for "GetChars".
326 public virtual char[] GetChars (byte[] bytes, int index, int count)
328 int numChars = GetCharCount (bytes, index, count);
329 char[] chars = new char [numChars];
330 GetChars (bytes, index, count, chars, 0);
333 public virtual char[] GetChars (byte[] bytes)
336 throw new ArgumentNullException ("bytes");
338 int numChars = GetCharCount (bytes, 0, bytes.Length);
339 char[] chars = new char [numChars];
340 GetChars (bytes, 0, bytes.Length, chars, 0);
344 // Get a decoder that forwards requests to this object.
345 public virtual Decoder GetDecoder ()
347 return new ForwardingDecoder (this);
350 // Get an encoder that forwards requests to this object.
351 public virtual Encoder GetEncoder ()
353 return new ForwardingEncoder (this);
356 // Loaded copy of the "I18N" assembly. We need to move
357 // this into a class in "System.Private" eventually.
358 private static Assembly i18nAssembly;
359 private static bool i18nDisabled;
361 // Invoke a specific method on the "I18N" manager object.
362 // Returns NULL if the method failed.
363 private static Object InvokeI18N (String name, params Object[] args)
366 // Bail out if we previously detected that there
367 // is insufficent engine support for I18N handling.
372 // Find or load the "I18N" assembly.
373 if (i18nAssembly == null) {
376 i18nAssembly = Assembly.Load (Consts.AssemblyI18N);
377 } catch (NotImplementedException) {
378 // Assembly loading unsupported by the engine.
382 if (i18nAssembly == null) {
385 } catch (SystemException) {
390 // Find the "I18N.Common.Manager" class.
393 managerClass = i18nAssembly.GetType ("I18N.Common.Manager");
394 } catch (NotImplementedException) {
395 // "GetType" is not supported by the engine.
399 if (managerClass == null) {
403 // Get the value of the "PrimaryManager" property.
406 manager = managerClass.InvokeMember
408 BindingFlags.GetProperty |
409 BindingFlags.Static |
411 null, null, null, null, null, null);
412 if (manager == null) {
415 } catch (MissingMethodException) {
417 } catch (SecurityException) {
419 } catch (NotImplementedException) {
420 // "InvokeMember" is not supported by the engine.
425 // Invoke the requested method on the manager.
427 return managerClass.InvokeMember
429 BindingFlags.InvokeMethod |
430 BindingFlags.Instance |
432 null, manager, args, null, null, null);
433 } catch (MissingMethodException) {
435 } catch (SecurityException) {
441 // Get an encoder for a specific code page.
447 static Encoding GetEncoding (int codepage)
449 if (codepage < 0 || codepage > 0xffff)
450 throw new ArgumentOutOfRangeException ("codepage",
451 "Valid values are between 0 and 65535, inclusive.");
453 // Check for the builtin code pages first.
455 case 0: return Default;
457 case ASCIIEncoding.ASCII_CODE_PAGE:
460 case UTF7Encoding.UTF7_CODE_PAGE:
463 case UTF8Encoding.UTF8_CODE_PAGE:
467 case UTF32Encoding.UTF32_CODE_PAGE:
470 case UTF32Encoding.BIG_UTF32_CODE_PAGE:
471 return BigEndianUTF32;
474 case UnicodeEncoding.UNICODE_CODE_PAGE:
477 case UnicodeEncoding.BIG_UNICODE_CODE_PAGE:
478 return BigEndianUnicode;
481 case Latin1Encoding.ISOLATIN_CODE_PAGE:
487 // Try to obtain a code page handler from the I18N handler.
488 Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", codepage));
491 enc.is_readonly = true;
496 // Build a code page class name.
497 String cpName = "System.Text.CP" + codepage.ToString ();
499 // Look for a code page converter in this assembly.
500 Assembly assembly = Assembly.GetExecutingAssembly ();
501 Type type = assembly.GetType (cpName);
503 enc = (Encoding)(Activator.CreateInstance (type));
505 enc.is_readonly = true;
510 // Look in any assembly, in case the application
511 // has provided its own code page handler.
512 type = Type.GetType (cpName);
514 enc = (Encoding)(Activator.CreateInstance (type));
516 enc.is_readonly = true;
521 // We have no idea how to handle this code page.
522 throw new NotSupportedException
523 (String.Format ("CodePage {0} not supported", codepage.ToString ()));
530 public virtual object Clone ()
532 Encoding e = (Encoding) MemberwiseClone ();
533 e.is_readonly = false;
539 public static Encoding GetEncoding (int codepage,
540 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
542 if (encoderFallback == null)
543 throw new ArgumentNullException ("encoderFallback");
544 if (decoderFallback == null)
545 throw new ArgumentNullException ("decoderFallback");
547 Encoding e = GetEncoding (codepage).Clone () as Encoding;
548 e.is_readonly = false;
549 e.encoder_fallback = encoderFallback;
550 e.decoder_fallback = decoderFallback;
554 public static Encoding GetEncoding (string name,
555 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
557 if (encoderFallback == null)
558 throw new ArgumentNullException ("encoderFallback");
559 if (decoderFallback == null)
560 throw new ArgumentNullException ("decoderFallback");
562 Encoding e = GetEncoding (name).Clone () as Encoding;
563 e.is_readonly = false;
564 e.encoder_fallback = encoderFallback;
565 e.decoder_fallback = decoderFallback;
571 static EncodingInfo [] encoding_infos;
573 // FIXME: As everyone would agree, this implementation is so *hacky*
574 // and could be very easily broken. But since there is a test for
575 // this method to make sure that this method always returns
576 // the same number and content of encoding infos, this won't
577 // matter practically.
578 public static EncodingInfo[] GetEncodings ()
580 if (encoding_infos == null) {
581 int [] codepages = new int [] {
583 850, 852, 855, 857, 858, 860, 861, 862, 863,
584 864, 865, 866, 869, 870, 874, 875,
586 1026, 1047, 1140, 1141, 1142, 1143, 1144,
587 1145, 1146, 1147, 1148, 1149,
588 1200, 1201, 1250, 1251, 1252, 1253, 1254,
589 1255, 1256, 1257, 1258,
590 10000, 10079, 12000, 12001,
591 20127, 20273, 20277, 20278, 20280, 20284,
592 20285, 20290, 20297, 20420, 20424, 20866,
593 20871, 21025, 21866, 28591, 28592, 28593,
594 28594, 28595, 28596, 28597, 28598, 28599,
596 50220, 50221, 50222, 51932, 51949, 54936,
597 57002, 57003, 57004, 57005, 57006, 57007,
598 57008, 57009, 57010, 57011,
601 encoding_infos = new EncodingInfo [codepages.Length];
602 for (int i = 0; i < codepages.Length; i++)
603 encoding_infos [i] = new EncodingInfo (codepages [i]);
605 return encoding_infos;
608 #if !NET_2_1 || MONOTOUCH
610 public bool IsAlwaysNormalized ()
612 return IsAlwaysNormalized (NormalizationForm.FormC);
616 public virtual bool IsAlwaysNormalized (NormalizationForm form)
618 // umm, ASCIIEncoding should have overriden this method, no?
619 return form == NormalizationForm.FormC && this is ASCIIEncoding;
625 // Table of builtin web encoding names and the corresponding code pages.
626 private static readonly object[] encodings =
628 ASCIIEncoding.ASCII_CODE_PAGE,
629 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
630 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
631 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
633 UTF7Encoding.UTF7_CODE_PAGE,
634 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
635 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
636 "x_unicode_2_0_utf_7",
638 UTF8Encoding.UTF8_CODE_PAGE,
639 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
640 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
642 UnicodeEncoding.UNICODE_CODE_PAGE,
643 "utf_16", "UTF_16LE", "ucs_2", "unicode",
646 UnicodeEncoding.BIG_UNICODE_CODE_PAGE,
647 "unicodefffe", "utf_16be",
649 UTF32Encoding.UTF32_CODE_PAGE,
650 "utf_32", "UTF_32LE", "ucs_4",
652 UTF32Encoding.BIG_UTF32_CODE_PAGE,
657 Latin1Encoding.ISOLATIN_CODE_PAGE,
658 "iso_8859_1", "latin1"
662 // Get an encoding object for a specific web encoding name.
663 public static Encoding GetEncoding (String name)
665 // Validate the parameters.
667 throw new ArgumentNullException ("name");
670 string converted = name.ToLowerInvariant ().Replace ('-', '_');
672 // Search the table for a name match.
674 for (int i = 0; i < encodings.Length; ++i) {
675 object o = encodings [i];
682 if (converted == ((string)encodings [i]))
683 return GetEncoding (code);
686 // Try to obtain a web encoding handler from the I18N handler.
687 Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", name));
692 // Build a web encoding class name.
693 String encName = "System.Text.ENC" + converted;
696 // Look for a code page converter in this assembly.
697 Assembly assembly = Assembly.GetExecutingAssembly ();
698 Type type = assembly.GetType (encName);
700 return (Encoding)(Activator.CreateInstance (type));
703 // Look in any assembly, in case the application
704 // has provided its own code page handler.
705 type = Type.GetType (encName);
707 return (Encoding)(Activator.CreateInstance (type));
710 // We have no idea how to handle this encoding name.
711 throw new ArgumentException (String.Format ("Encoding name '{0}' not "
712 + "supported", name), "name");
715 #endif // !ECMA_COMPAT
717 // Get a hash code for this instance.
718 public override int GetHashCode ()
721 return DecoderFallback.GetHashCode () << 24 + EncoderFallback.GetHashCode () << 16 + codePage;
727 // Get the maximum number of bytes needed to encode a
728 // specified number of characters.
729 public abstract int GetMaxByteCount (int charCount);
731 // Get the maximum number of characters needed to decode a
732 // specified number of bytes.
733 public abstract int GetMaxCharCount (int byteCount);
735 // Get the identifying preamble for this encoding.
736 public virtual byte[] GetPreamble ()
741 // Decode a buffer of bytes into a string.
742 public virtual String GetString (byte[] bytes, int index, int count)
744 return new String (GetChars(bytes, index, count));
746 public virtual String GetString (byte[] bytes)
749 throw new ArgumentNullException ("bytes");
751 return GetString (bytes, 0, bytes.Length);
756 internal string body_name;
757 internal string encoding_name;
758 internal string header_name;
759 internal bool is_mail_news_display;
760 internal bool is_mail_news_save;
761 internal bool is_browser_save = false;
762 internal bool is_browser_display = false;
763 internal string web_name;
765 // Get the mail body name for this encoding.
766 public virtual String BodyName
773 // Get the code page represented by this object.
774 public virtual int CodePage
781 // Get the human-readable name for this encoding.
782 public virtual String EncodingName
785 return encoding_name;
789 // Get the mail agent header name for this encoding.
790 public virtual String HeaderName
797 // Determine if this encoding can be displayed in a Web browser.
798 public virtual bool IsBrowserDisplay
801 return is_browser_display;
805 // Determine if this encoding can be saved from a Web browser.
806 public virtual bool IsBrowserSave
809 return is_browser_save;
813 // Determine if this encoding can be displayed in a mail/news agent.
814 public virtual bool IsMailNewsDisplay
817 return is_mail_news_display;
821 // Determine if this encoding can be saved from a mail/news agent.
822 public virtual bool IsMailNewsSave
825 return is_mail_news_save;
829 // Get the IANA-preferred Web name for this encoding.
830 public virtual String WebName
837 // Get the Windows code page represented by this object.
838 public virtual int WindowsCodePage
841 // We make no distinction between normal and
842 // Windows code pages in this implementation.
843 return windows_code_page;
847 #endif // !ECMA_COMPAT
849 // Storage for standard encoding objects.
850 static volatile Encoding asciiEncoding;
851 static volatile Encoding bigEndianEncoding;
852 static volatile Encoding defaultEncoding;
853 static volatile Encoding utf7Encoding;
854 static volatile Encoding utf8EncodingWithMarkers;
855 static volatile Encoding utf8EncodingWithoutMarkers;
856 static volatile Encoding unicodeEncoding;
857 static volatile Encoding isoLatin1Encoding;
859 static volatile Encoding utf8EncodingUnsafe;
860 static volatile Encoding utf32Encoding;
861 static volatile Encoding bigEndianUTF32Encoding;
864 static readonly object lockobj = new object ();
866 // Get the standard ASCII encoding object.
867 public static Encoding ASCII
870 if (asciiEncoding == null) {
872 if (asciiEncoding == null) {
873 asciiEncoding = new ASCIIEncoding ();
874 // asciiEncoding.is_readonly = true;
879 return asciiEncoding;
883 // Get the standard big-endian Unicode encoding object.
884 public static Encoding BigEndianUnicode
887 if (bigEndianEncoding == null) {
889 if (bigEndianEncoding == null) {
890 bigEndianEncoding = new UnicodeEncoding (true, true);
891 // bigEndianEncoding.is_readonly = true;
896 return bigEndianEncoding;
900 [MethodImpl (MethodImplOptions.InternalCall)]
901 extern internal static string InternalCodePage (ref int code_page);
903 // Get the default encoding object.
904 public static Encoding Default
907 if (defaultEncoding == null) {
909 if (defaultEncoding == null) {
910 // See if the underlying system knows what
911 // code page handler we should be using.
914 string code_page_name = InternalCodePage (ref code_page);
917 defaultEncoding = GetEncoding (code_page_name);
919 // map the codepage from internal to our numbers
920 code_page = code_page & 0x0fffffff;
922 case 1: code_page = ASCIIEncoding.ASCII_CODE_PAGE; break;
923 case 2: code_page = UTF7Encoding.UTF7_CODE_PAGE; break;
924 case 3: code_page = UTF8Encoding.UTF8_CODE_PAGE; break;
925 case 4: code_page = UnicodeEncoding.UNICODE_CODE_PAGE; break;
926 case 5: code_page = UnicodeEncoding.BIG_UNICODE_CODE_PAGE; break;
928 case 6: code_page = Latin1Encoding.ISOLATIN_CODE_PAGE; break;
931 defaultEncoding = GetEncoding (code_page);
933 } catch (NotSupportedException) {
934 // code_page is not supported on underlying platform
935 defaultEncoding = UTF8Unmarked;
936 } catch (ArgumentException) {
937 // code_page_name is not a valid code page, or is
938 // not supported by underlying OS
939 defaultEncoding = UTF8Unmarked;
942 defaultEncoding.is_readonly = true;
948 return defaultEncoding;
954 // Get the ISO Latin1 encoding object.
955 private static Encoding ISOLatin1
958 if (isoLatin1Encoding == null) {
960 if (isoLatin1Encoding == null) {
961 isoLatin1Encoding = new Latin1Encoding ();
962 // isoLatin1Encoding.is_readonly = true;
967 return isoLatin1Encoding;
973 // Get the standard UTF-7 encoding object.
982 if (utf7Encoding == null) {
984 if (utf7Encoding == null) {
985 utf7Encoding = new UTF7Encoding ();
986 // utf7Encoding.is_readonly = true;
995 // Get the standard UTF-8 encoding object.
996 public static Encoding UTF8
999 if (utf8EncodingWithMarkers == null) {
1001 if (utf8EncodingWithMarkers == null) {
1002 utf8EncodingWithMarkers = new UTF8Encoding (true);
1003 // utf8EncodingWithMarkers.is_readonly = true;
1008 return utf8EncodingWithMarkers;
1013 // Only internal, to be used by the class libraries: Unmarked and non-input-validating
1015 internal static Encoding UTF8Unmarked {
1017 if (utf8EncodingWithoutMarkers == null) {
1019 if (utf8EncodingWithoutMarkers == null){
1020 utf8EncodingWithoutMarkers = new UTF8Encoding (false, false);
1021 // utf8EncodingWithoutMarkers.is_readonly = true;
1026 return utf8EncodingWithoutMarkers;
1031 // Only internal, to be used by the class libraries: Unmarked and non-input-validating
1033 internal static Encoding UTF8UnmarkedUnsafe {
1036 if (utf8EncodingUnsafe == null) {
1038 if (utf8EncodingUnsafe == null){
1039 utf8EncodingUnsafe = new UTF8Encoding (false, false);
1040 utf8EncodingUnsafe.is_readonly = false;
1041 utf8EncodingUnsafe.DecoderFallback = new DecoderReplacementFallback (String.Empty);
1042 utf8EncodingUnsafe.is_readonly = true;
1047 return utf8EncodingUnsafe;
1049 return UTF8Unmarked;
1054 // Get the standard little-endian Unicode encoding object.
1055 public static Encoding Unicode
1058 if (unicodeEncoding == null) {
1060 if (unicodeEncoding == null) {
1061 unicodeEncoding = new UnicodeEncoding (false, true);
1062 // unicodeEncoding.is_readonly = true;
1067 return unicodeEncoding;
1072 // Get the standard little-endian UTF-32 encoding object.
1073 public static Encoding UTF32
1076 if (utf32Encoding == null) {
1078 if (utf32Encoding == null) {
1079 utf32Encoding = new UTF32Encoding (false, true);
1080 // utf32Encoding.is_readonly = true;
1085 return utf32Encoding;
1089 // Get the standard big-endian UTF-32 encoding object.
1090 internal static Encoding BigEndianUTF32
1093 if (bigEndianUTF32Encoding == null) {
1095 if (bigEndianUTF32Encoding == null) {
1096 bigEndianUTF32Encoding = new UTF32Encoding (true, true);
1097 // bigEndianUTF32Encoding.is_readonly = true;
1102 return bigEndianUTF32Encoding;
1107 // Forwarding decoder implementation.
1108 private sealed class ForwardingDecoder : Decoder
1110 private Encoding encoding;
1113 public ForwardingDecoder (Encoding enc)
1117 DecoderFallback fallback = encoding.DecoderFallback;
1118 if (fallback != null)
1119 Fallback = fallback;
1123 // Override inherited methods.
1124 public override int GetCharCount (byte[] bytes, int index, int count)
1126 return encoding.GetCharCount (bytes, index, count);
1128 public override int GetChars (byte[] bytes, int byteIndex,
1129 int byteCount, char[] chars,
1132 return encoding.GetChars (bytes, byteIndex, byteCount, chars, charIndex);
1135 } // class ForwardingDecoder
1137 // Forwarding encoder implementation.
1138 private sealed class ForwardingEncoder : Encoder
1140 private Encoding encoding;
1143 public ForwardingEncoder (Encoding enc)
1147 EncoderFallback fallback = encoding.EncoderFallback;
1148 if (fallback != null)
1149 Fallback = fallback;
1153 // Override inherited methods.
1154 public override int GetByteCount (char[] chars, int index, int count, bool flush)
1156 return encoding.GetByteCount (chars, index, count);
1158 public override int GetBytes (char[] chars, int charIndex,
1159 int charCount, byte[] bytes,
1160 int byteCount, bool flush)
1162 return encoding.GetBytes (chars, charIndex, charCount, bytes, byteCount);
1165 } // class ForwardingEncoder
1168 [CLSCompliantAttribute(false)]
1169 [ComVisible (false)]
1170 public unsafe virtual int GetByteCount (char *chars, int count)
1173 throw new ArgumentNullException ("chars");
1175 throw new ArgumentOutOfRangeException ("count");
1176 char [] c = new char [count];
1178 for (int p = 0; p < count; p++)
1181 return GetByteCount (c);
1184 [CLSCompliantAttribute(false)]
1185 [ComVisible (false)]
1186 public unsafe virtual int GetCharCount (byte *bytes, int count)
1189 throw new ArgumentNullException ("bytes");
1191 throw new ArgumentOutOfRangeException ("count");
1193 byte [] ba = new byte [count];
1194 for (int i = 0; i < count; i++)
1196 return GetCharCount (ba, 0, count);
1199 [CLSCompliantAttribute(false)]
1200 [ComVisible (false)]
1201 public unsafe virtual int GetChars (byte *bytes, int byteCount, char *chars, int charCount)
1204 throw new ArgumentNullException ("bytes");
1206 throw new ArgumentNullException ("chars");
1208 throw new ArgumentOutOfRangeException ("charCount");
1210 throw new ArgumentOutOfRangeException ("byteCount");
1212 byte [] ba = new byte [byteCount];
1213 for (int i = 0; i < byteCount; i++)
1215 char [] ret = GetChars (ba, 0, byteCount);
1216 int top = ret.Length;
1218 if (top > charCount)
1219 throw new ArgumentException ("charCount is less than the number of characters produced", "charCount");
1221 for (int i = 0; i < top; i++)
1222 chars [i] = ret [i];
1226 [CLSCompliantAttribute(false)]
1227 [ComVisible (false)]
1228 public unsafe virtual int GetBytes (char *chars, int charCount, byte *bytes, int byteCount)
1231 throw new ArgumentNullException ("bytes");
1233 throw new ArgumentNullException ("chars");
1235 throw new ArgumentOutOfRangeException ("charCount");
1237 throw new ArgumentOutOfRangeException ("byteCount");
1239 char [] c = new char [charCount];
1241 for (int i = 0; i < charCount; i++)
1244 byte [] b = GetBytes (c, 0, charCount);
1246 if (top > byteCount)
1247 throw new ArgumentException ("byteCount is less that the number of bytes produced", "byteCount");
1249 for (int i = 0; i < top; i++)
1256 }; // class Encoding
1258 }; // namespace System.Text