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;
49 bool is_readonly = true;
61 Encoding (int codePage)
63 this.codePage = windows_code_page = codePage;
68 // MS has "InternalBestFit{Decoder|Encoder}Fallback
69 // here, but we dunno what they are for.
70 decoder_fallback = DecoderFallback.ReplacementFallback;
71 encoder_fallback = EncoderFallback.ReplacementFallback;
74 case 54936: // GB18030
75 decoder_fallback = DecoderFallback.ReplacementFallback;
76 encoder_fallback = EncoderFallback.ReplacementFallback;
84 decoder_fallback = new DecoderReplacementFallback (String.Empty);
85 encoder_fallback = new EncoderReplacementFallback (String.Empty);
91 // until we change the callers:
92 internal static string _ (string arg) {
97 DecoderFallback decoder_fallback;
98 EncoderFallback encoder_fallback;
101 public bool IsReadOnly {
102 get { return is_readonly; }
106 public virtual bool IsSingleByte {
107 get { return false; }
110 [MonoTODO ("not used yet")]
112 public DecoderFallback DecoderFallback {
114 if (decoder_fallback == null)
115 decoder_fallback = new DecoderReplacementFallback (String.Empty);
116 return decoder_fallback;
120 throw new InvalidOperationException ("This Encoding is readonly.");
122 throw new ArgumentNullException ();
123 decoder_fallback = value;
127 [MonoTODO ("not used yet")]
129 public EncoderFallback EncoderFallback {
131 if (encoder_fallback == null)
132 encoder_fallback = new EncoderReplacementFallback (String.Empty);
133 return encoder_fallback;
137 throw new InvalidOperationException ("This Encoding is readonly.");
139 throw new ArgumentNullException ();
140 encoder_fallback = value;
144 internal void SetFallbackInternal (EncoderFallback e, DecoderFallback d)
147 encoder_fallback = e;
149 decoder_fallback = d;
153 // Convert between two encodings.
154 public static byte[] Convert (Encoding srcEncoding, Encoding dstEncoding,
157 if (srcEncoding == null) {
158 throw new ArgumentNullException ("srcEncoding");
160 if (dstEncoding == null) {
161 throw new ArgumentNullException ("dstEncoding");
164 throw new ArgumentNullException ("bytes");
166 return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, 0, bytes.Length));
168 public static byte[] Convert (Encoding srcEncoding, Encoding dstEncoding,
169 byte[] bytes, int index, int count)
171 if (srcEncoding == null) {
172 throw new ArgumentNullException ("srcEncoding");
174 if (dstEncoding == null) {
175 throw new ArgumentNullException ("dstEncoding");
178 throw new ArgumentNullException ("bytes");
180 if (index < 0 || index > bytes.Length) {
181 throw new ArgumentOutOfRangeException
182 ("index", _("ArgRange_Array"));
184 if (count < 0 || (bytes.Length - index) < count) {
185 throw new ArgumentOutOfRangeException
186 ("count", _("ArgRange_Array"));
188 return dstEncoding.GetBytes (srcEncoding.GetChars (bytes, index, count));
191 // Determine if two Encoding objects are equal.
192 public override bool Equals (Object obj)
194 Encoding enc = (obj as Encoding);
197 return codePage == enc.codePage &&
198 DecoderFallback.Equals (enc.DecoderFallback) &&
199 EncoderFallback.Equals (enc.EncoderFallback);
201 return (codePage == enc.codePage);
208 // Get the number of characters needed to encode a character buffer.
209 public abstract int GetByteCount (char[] chars, int index, int count);
211 // Convenience wrappers for "GetByteCount".
212 public virtual int GetByteCount (String s)
215 throw new ArgumentNullException ("s");
221 fixed (char* cptr = s) {
222 return GetByteCount (cptr, s.Length);
226 char[] chars = s.ToCharArray ();
227 return GetByteCount (chars, 0, chars.Length);
230 public virtual int GetByteCount (char[] chars)
233 return GetByteCount (chars, 0, chars.Length);
235 throw new ArgumentNullException ("chars");
239 // Get the bytes that result from encoding a character buffer.
240 public abstract int GetBytes (char[] chars, int charIndex, int charCount,
241 byte[] bytes, int byteIndex);
243 // Convenience wrappers for "GetBytes".
244 public virtual int GetBytes (String s, int charIndex, int charCount,
245 byte[] bytes, int byteIndex)
248 throw new ArgumentNullException ("s");
250 if (charIndex < 0 || charIndex > s.Length)
251 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
252 if (charCount < 0 || charIndex + charCount > s.Length)
253 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
254 if (byteIndex < 0 || byteIndex > bytes.Length)
255 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
257 if (charCount == 0 || bytes.Length == byteIndex)
260 fixed (char* cptr = s) {
261 fixed (byte* bptr = bytes) {
262 return GetBytes (cptr + charIndex,
265 bytes.Length - byteIndex);
270 return GetBytes (s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
273 public virtual byte[] GetBytes (String s)
276 throw new ArgumentNullException ("s");
281 int byteCount = GetByteCount (s);
285 fixed (char* cptr = s) {
286 byte [] bytes = new byte [byteCount];
287 fixed (byte* bptr = bytes) {
288 GetBytes (cptr, s.Length,
295 char[] chars = s.ToCharArray ();
296 int numBytes = GetByteCount (chars, 0, chars.Length);
297 byte[] bytes = new byte [numBytes];
298 GetBytes (chars, 0, chars.Length, bytes, 0);
302 public virtual byte[] GetBytes (char[] chars, int index, int count)
304 int numBytes = GetByteCount (chars, index, count);
305 byte[] bytes = new byte [numBytes];
306 GetBytes (chars, index, count, bytes, 0);
309 public virtual byte[] GetBytes (char[] chars)
311 int numBytes = GetByteCount (chars, 0, chars.Length);
312 byte[] bytes = new byte [numBytes];
313 GetBytes (chars, 0, chars.Length, bytes, 0);
317 // Get the number of characters needed to decode a byte buffer.
318 public abstract int GetCharCount (byte[] bytes, int index, int count);
320 // Convenience wrappers for "GetCharCount".
321 public virtual int GetCharCount (byte[] bytes)
324 throw new ArgumentNullException ("bytes");
326 return GetCharCount (bytes, 0, bytes.Length);
329 // Get the characters that result from decoding a byte buffer.
330 public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount,
331 char[] chars, int charIndex);
333 // Convenience wrappers for "GetChars".
334 public virtual char[] GetChars (byte[] bytes, int index, int count)
336 int numChars = GetCharCount (bytes, index, count);
337 char[] chars = new char [numChars];
338 GetChars (bytes, index, count, chars, 0);
341 public virtual char[] GetChars (byte[] bytes)
344 throw new ArgumentNullException ("bytes");
346 int numChars = GetCharCount (bytes, 0, bytes.Length);
347 char[] chars = new char [numChars];
348 GetChars (bytes, 0, bytes.Length, chars, 0);
352 // Get a decoder that forwards requests to this object.
353 public virtual Decoder GetDecoder ()
355 return new ForwardingDecoder (this);
358 // Get an encoder that forwards requests to this object.
359 public virtual Encoder GetEncoder ()
361 return new ForwardingEncoder (this);
364 // Loaded copy of the "I18N" assembly. We need to move
365 // this into a class in "System.Private" eventually.
366 private static Assembly i18nAssembly;
367 private static bool i18nDisabled;
369 // Invoke a specific method on the "I18N" manager object.
370 // Returns NULL if the method failed.
371 private static Object InvokeI18N (String name, params Object[] args)
374 // Bail out if we previously detected that there
375 // is insufficent engine support for I18N handling.
380 // Find or load the "I18N" assembly.
381 if (i18nAssembly == null) {
384 i18nAssembly = Assembly.Load (Consts.AssemblyI18N);
385 } catch (NotImplementedException) {
386 // Assembly loading unsupported by the engine.
390 if (i18nAssembly == null) {
393 } catch (SystemException) {
398 // Find the "I18N.Common.Manager" class.
401 managerClass = i18nAssembly.GetType ("I18N.Common.Manager");
402 } catch (NotImplementedException) {
403 // "GetType" is not supported by the engine.
407 if (managerClass == null) {
411 // Get the value of the "PrimaryManager" property.
414 manager = managerClass.InvokeMember
416 BindingFlags.GetProperty |
417 BindingFlags.Static |
419 null, null, null, null, null, null);
420 if (manager == null) {
423 } catch (MissingMethodException) {
425 } catch (SecurityException) {
427 } catch (NotImplementedException) {
428 // "InvokeMember" is not supported by the engine.
433 // Invoke the requested method on the manager.
435 return managerClass.InvokeMember
437 BindingFlags.InvokeMethod |
438 BindingFlags.Instance |
440 null, manager, args, null, null, null);
441 } catch (MissingMethodException) {
443 } catch (SecurityException) {
449 // Get an encoder for a specific code page.
455 static Encoding GetEncoding (int codePage)
457 if (codePage < 0 || codePage > 0xffff)
458 throw new ArgumentOutOfRangeException ("codepage",
459 "Valid values are between 0 and 65535, inclusive.");
461 // Check for the builtin code pages first.
463 case 0: return Default;
465 case ASCIIEncoding.ASCII_CODE_PAGE:
468 case UTF7Encoding.UTF7_CODE_PAGE:
471 case UTF8Encoding.UTF8_CODE_PAGE:
475 case UTF32Encoding.UTF32_CODE_PAGE:
478 case UTF32Encoding.BIG_UTF32_CODE_PAGE:
479 return BigEndianUTF32;
482 case UnicodeEncoding.UNICODE_CODE_PAGE:
485 case UnicodeEncoding.BIG_UNICODE_CODE_PAGE:
486 return BigEndianUnicode;
488 case Latin1Encoding.ISOLATIN_CODE_PAGE:
494 // Try to obtain a code page handler from the I18N handler.
495 Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", codePage));
497 enc.is_readonly = true;
501 // Build a code page class name.
502 String cpName = "System.Text.CP" + codePage.ToString ();
504 // Look for a code page converter in this assembly.
505 Assembly assembly = Assembly.GetExecutingAssembly ();
506 Type type = assembly.GetType (cpName);
508 enc = (Encoding)(Activator.CreateInstance (type));
509 enc.is_readonly = true;
513 // Look in any assembly, in case the application
514 // has provided its own code page handler.
515 type = Type.GetType (cpName);
517 enc = (Encoding)(Activator.CreateInstance (type));
518 enc.is_readonly = true;
522 // We have no idea how to handle this code page.
523 throw new NotSupportedException
524 (String.Format ("CodePage {0} not supported", codePage.ToString ()));
531 public virtual object Clone ()
533 Encoding e = (Encoding) MemberwiseClone ();
534 e.is_readonly = false;
538 public static Encoding GetEncoding (int codePage,
539 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
541 if (encoderFallback == null)
542 throw new ArgumentNullException ("encoderFallback");
543 if (decoderFallback == null)
544 throw new ArgumentNullException ("decoderFallback");
546 Encoding e = GetEncoding (codePage).Clone () as Encoding;
547 e.is_readonly = false;
548 e.encoder_fallback = encoderFallback;
549 e.decoder_fallback = decoderFallback;
553 public static Encoding GetEncoding (string name,
554 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
556 if (encoderFallback == null)
557 throw new ArgumentNullException ("encoderFallback");
558 if (decoderFallback == null)
559 throw new ArgumentNullException ("decoderFallback");
561 Encoding e = GetEncoding (name).Clone () as Encoding;
562 e.is_readonly = false;
563 e.encoder_fallback = encoderFallback;
564 e.decoder_fallback = decoderFallback;
568 static EncodingInfo [] encoding_infos;
570 // FIXME: As everyone would agree, this implementation is so *hacky*
571 // and could be very easily broken. But since there is a test for
572 // this method to make sure that this method always returns
573 // the same number and content of encoding infos, this won't
574 // matter practically.
575 public static EncodingInfo[] GetEncodings ()
577 if (encoding_infos == null) {
578 int [] codepages = new int [] {
580 850, 852, 855, 857, 858, 860, 861, 862, 863,
581 864, 865, 866, 869, 870, 874, 875,
583 1026, 1047, 1140, 1141, 1142, 1143, 1144,
584 1145, 1146, 1147, 1148, 1149,
585 1200, 1201, 1250, 1251, 1252, 1253, 1254,
586 1255, 1256, 1257, 1258,
587 10000, 10079, 12000, 12001,
588 20127, 20273, 20277, 20278, 20280, 20284,
589 20285, 20290, 20297, 20420, 20424, 20866,
590 20871, 21025, 21866, 28591, 28592, 28593,
591 28594, 28595, 28596, 28597, 28598, 28599,
593 50220, 50221, 50222, 51932, 51949, 54936,
594 57002, 57003, 57004, 57005, 57006, 57007,
595 57008, 57009, 57010, 57011,
598 encoding_infos = new EncodingInfo [codepages.Length];
599 for (int i = 0; i < codepages.Length; i++)
600 encoding_infos [i] = new EncodingInfo (codepages [i]);
602 return encoding_infos;
605 public bool IsAlwaysNormalized ()
607 return IsAlwaysNormalized (NormalizationForm.FormC);
610 public virtual bool IsAlwaysNormalized (NormalizationForm form)
612 // umm, ASCIIEncoding should have overriden this method, no?
613 return form == NormalizationForm.FormC && this is ASCIIEncoding;
617 // Table of builtin web encoding names and the corresponding code pages.
618 private static readonly object[] encodings =
620 ASCIIEncoding.ASCII_CODE_PAGE,
621 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
622 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
623 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
625 UTF7Encoding.UTF7_CODE_PAGE,
626 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
627 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
628 "x_unicode_2_0_utf_7",
630 UTF8Encoding.UTF8_CODE_PAGE,
631 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
632 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
634 UnicodeEncoding.UNICODE_CODE_PAGE,
635 "utf_16", "UTF_16LE", "ucs_2", "unicode",
638 UnicodeEncoding.BIG_UNICODE_CODE_PAGE,
639 "unicodefffe", "utf_16be",
642 UTF32Encoding.UTF32_CODE_PAGE,
643 "utf_32", "UTF_32LE", "ucs_4",
645 UTF32Encoding.BIG_UTF32_CODE_PAGE,
649 Latin1Encoding.ISOLATIN_CODE_PAGE,
650 "iso_8859_1", "latin1"
653 // Get an encoding object for a specific web encoding name.
654 public static Encoding GetEncoding (String name)
656 // Validate the parameters.
658 throw new ArgumentNullException ("name");
661 string converted = name.ToLowerInvariant ().Replace ('-', '_');
663 // Search the table for a name match.
665 for (int i = 0; i < encodings.Length; ++i) {
666 object o = encodings [i];
673 if (converted == ((string)encodings [i]))
674 return GetEncoding (code);
677 // Try to obtain a web encoding handler from the I18N handler.
678 Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", name));
683 // Build a web encoding class name.
684 String encName = "System.Text.ENC" + converted;
687 // Look for a code page converter in this assembly.
688 Assembly assembly = Assembly.GetExecutingAssembly ();
689 Type type = assembly.GetType (encName);
691 return (Encoding)(Activator.CreateInstance (type));
694 // Look in any assembly, in case the application
695 // has provided its own code page handler.
696 type = Type.GetType (encName);
698 return (Encoding)(Activator.CreateInstance (type));
701 // We have no idea how to handle this encoding name.
702 throw new ArgumentException (String.Format ("Encoding name '{0}' not "
703 + "supported", name), "name");
706 #endif // !ECMA_COMPAT
708 // Get a hash code for this instance.
709 public override int GetHashCode ()
712 return DecoderFallback.GetHashCode () << 24 + EncoderFallback.GetHashCode () << 16 + codePage;
718 // Get the maximum number of bytes needed to encode a
719 // specified number of characters.
720 public abstract int GetMaxByteCount (int charCount);
722 // Get the maximum number of characters needed to decode a
723 // specified number of bytes.
724 public abstract int GetMaxCharCount (int byteCount);
726 // Get the identifying preamble for this encoding.
727 public virtual byte[] GetPreamble ()
732 // Decode a buffer of bytes into a string.
733 public virtual String GetString (byte[] bytes, int index, int count)
735 return new String (GetChars(bytes, index, count));
737 public virtual String GetString (byte[] bytes)
740 throw new ArgumentNullException ("bytes");
742 return GetString (bytes, 0, bytes.Length);
747 internal string body_name;
748 internal string encoding_name;
749 internal string header_name;
750 internal bool is_mail_news_display;
751 internal bool is_mail_news_save;
752 internal bool is_browser_save = false;
753 internal bool is_browser_display = false;
754 internal string web_name;
756 // Get the mail body name for this encoding.
757 public virtual String BodyName
764 // Get the code page represented by this object.
765 public virtual int CodePage
772 // Get the human-readable name for this encoding.
773 public virtual String EncodingName
776 return encoding_name;
780 // Get the mail agent header name for this encoding.
781 public virtual String HeaderName
788 // Determine if this encoding can be displayed in a Web browser.
789 public virtual bool IsBrowserDisplay
792 return is_browser_display;
796 // Determine if this encoding can be saved from a Web browser.
797 public virtual bool IsBrowserSave
800 return is_browser_save;
804 // Determine if this encoding can be displayed in a mail/news agent.
805 public virtual bool IsMailNewsDisplay
808 return is_mail_news_display;
812 // Determine if this encoding can be saved from a mail/news agent.
813 public virtual bool IsMailNewsSave
816 return is_mail_news_save;
820 // Get the IANA-preferred Web name for this encoding.
821 public virtual String WebName
828 // Get the Windows code page represented by this object.
829 public virtual int WindowsCodePage
832 // We make no distinction between normal and
833 // Windows code pages in this implementation.
834 return windows_code_page;
838 #endif // !ECMA_COMPAT
840 // Storage for standard encoding objects.
841 static volatile Encoding asciiEncoding;
842 static volatile Encoding bigEndianEncoding;
843 static volatile Encoding defaultEncoding;
844 static volatile Encoding utf7Encoding;
845 static volatile Encoding utf8EncodingWithMarkers;
846 static volatile Encoding utf8EncodingWithoutMarkers;
847 static volatile Encoding unicodeEncoding;
848 static volatile Encoding isoLatin1Encoding;
849 static volatile Encoding unixConsoleEncoding;
851 static volatile Encoding utf32Encoding;
852 static volatile Encoding bigEndianUTF32Encoding;
855 static readonly object lockobj = new object ();
857 // Get the standard ASCII encoding object.
858 public static Encoding ASCII
861 if (asciiEncoding == null) {
863 if (asciiEncoding == null) {
864 asciiEncoding = new ASCIIEncoding ();
865 asciiEncoding.is_readonly = true;
870 return asciiEncoding;
874 // Get the standard big-endian Unicode encoding object.
875 public static Encoding BigEndianUnicode
878 if (bigEndianEncoding == null) {
880 if (bigEndianEncoding == null) {
881 bigEndianEncoding = new UnicodeEncoding (true, true);
882 bigEndianEncoding.is_readonly = true;
887 return bigEndianEncoding;
891 [MethodImpl (MethodImplOptions.InternalCall)]
892 extern internal static string InternalCodePage (ref int code_page);
894 // Get the default encoding object.
895 public static Encoding Default
898 if (defaultEncoding == null) {
900 if (defaultEncoding == null) {
901 // See if the underlying system knows what
902 // code page handler we should be using.
905 string code_page_name = InternalCodePage (ref code_page);
908 defaultEncoding = GetEncoding (code_page_name);
910 // map the codepage from internal to our numbers
911 code_page = code_page & 0x0fffffff;
913 case 1: code_page = ASCIIEncoding.ASCII_CODE_PAGE; break;
914 case 2: code_page = UTF7Encoding.UTF7_CODE_PAGE; break;
915 case 3: code_page = UTF8Encoding.UTF8_CODE_PAGE; break;
916 case 4: code_page = UnicodeEncoding.UNICODE_CODE_PAGE; break;
917 case 5: code_page = UnicodeEncoding.BIG_UNICODE_CODE_PAGE; break;
918 case 6: code_page = Latin1Encoding.ISOLATIN_CODE_PAGE; break;
920 defaultEncoding = GetEncoding (code_page);
922 } catch (NotSupportedException) {
923 // code_page is not supported on underlying platform
924 defaultEncoding = UTF8Unmarked;
925 } catch (ArgumentException) {
926 // code_page_name is not a valid code page, or is
927 // not supported by underlying OS
928 defaultEncoding = UTF8Unmarked;
930 defaultEncoding.is_readonly = true;
935 return defaultEncoding;
939 // Get the ISO Latin1 encoding object.
940 private static Encoding ISOLatin1
943 if (isoLatin1Encoding == null) {
945 if (isoLatin1Encoding == null) {
946 isoLatin1Encoding = new Latin1Encoding ();
947 isoLatin1Encoding.is_readonly = true;
952 return isoLatin1Encoding;
956 // Get the standard UTF-7 encoding object.
965 if (utf7Encoding == null) {
967 if (utf7Encoding == null) {
968 utf7Encoding = new UTF7Encoding ();
969 utf7Encoding.is_readonly = true;
978 // Get the standard UTF-8 encoding object.
979 public static Encoding UTF8
982 if (utf8EncodingWithMarkers == null) {
984 if (utf8EncodingWithMarkers == null) {
985 utf8EncodingWithMarkers = new UTF8Encoding (true);
986 utf8EncodingWithMarkers.is_readonly = true;
991 return utf8EncodingWithMarkers;
996 // Only internal, to be used by the class libraries: Unmarked and non-input-validating
998 internal static Encoding UTF8Unmarked {
1000 if (utf8EncodingWithoutMarkers == null) {
1002 if (utf8EncodingWithoutMarkers == null){
1003 utf8EncodingWithoutMarkers = new UTF8Encoding (false, false);
1004 utf8EncodingWithoutMarkers.is_readonly = true;
1009 return utf8EncodingWithoutMarkers;
1013 // Get the standard little-endian Unicode encoding object.
1014 public static Encoding Unicode
1017 if (unicodeEncoding == null) {
1019 if (unicodeEncoding == null) {
1020 unicodeEncoding = new UnicodeEncoding (false, true);
1021 unicodeEncoding.is_readonly = true;
1026 return unicodeEncoding;
1031 // Get the standard little-endian UTF-32 encoding object.
1032 public static Encoding UTF32
1035 if (utf32Encoding == null) {
1037 if (utf32Encoding == null) {
1038 utf32Encoding = new UTF32Encoding (false, true);
1039 utf32Encoding.is_readonly = true;
1044 return utf32Encoding;
1048 // Get the standard big-endian UTF-32 encoding object.
1049 internal static Encoding BigEndianUTF32
1052 if (bigEndianUTF32Encoding == null) {
1054 if (bigEndianUTF32Encoding == null) {
1055 bigEndianUTF32Encoding = new UTF32Encoding (true, true);
1056 bigEndianUTF32Encoding.is_readonly = true;
1061 return bigEndianUTF32Encoding;
1066 // Forwarding decoder implementation.
1067 private sealed class ForwardingDecoder : Decoder
1069 private Encoding encoding;
1072 public ForwardingDecoder (Encoding enc)
1076 Fallback = encoding.DecoderFallback;
1080 // Override inherited methods.
1081 public override int GetCharCount (byte[] bytes, int index, int count)
1083 return encoding.GetCharCount (bytes, index, count);
1085 public override int GetChars (byte[] bytes, int byteIndex,
1086 int byteCount, char[] chars,
1089 return encoding.GetChars (bytes, byteIndex, byteCount, chars, charIndex);
1092 } // class ForwardingDecoder
1094 // Forwarding encoder implementation.
1095 private sealed class ForwardingEncoder : Encoder
1097 private Encoding encoding;
1100 public ForwardingEncoder (Encoding enc)
1104 Fallback = encoding.EncoderFallback;
1108 // Override inherited methods.
1109 public override int GetByteCount (char[] chars, int index, int count, bool flush)
1111 return encoding.GetByteCount (chars, index, count);
1113 public override int GetBytes (char[] chars, int charIndex,
1114 int charCount, byte[] bytes,
1115 int byteCount, bool flush)
1117 return encoding.GetBytes (chars, charIndex, charCount, bytes, byteCount);
1120 } // class ForwardingEncoder
1123 [CLSCompliantAttribute(false)]
1124 [ComVisible (false)]
1125 public unsafe virtual int GetByteCount (char *chars, int count)
1128 throw new ArgumentNullException ("chars");
1130 throw new ArgumentOutOfRangeException ("count");
1131 char [] c = new char [count];
1133 for (int p = 0; p < count; p++)
1136 return GetByteCount (c);
1139 [CLSCompliantAttribute(false)]
1140 [ComVisible (false)]
1141 public unsafe virtual int GetCharCount (byte *bytes, int count)
1144 throw new ArgumentNullException ("bytes");
1146 throw new ArgumentOutOfRangeException ("count");
1148 byte [] ba = new byte [count];
1149 for (int i = 0; i < count; i++)
1151 return GetCharCount (ba, 0, count);
1154 [CLSCompliantAttribute(false)]
1155 [ComVisible (false)]
1156 public unsafe virtual int GetChars (byte *bytes, int byteCount, char *chars, int charCount)
1159 throw new ArgumentNullException ("bytes");
1161 throw new ArgumentNullException ("chars");
1163 throw new ArgumentOutOfRangeException ("charCount");
1165 throw new ArgumentOutOfRangeException ("byteCount");
1167 byte [] ba = new byte [byteCount];
1168 for (int i = 0; i < byteCount; i++)
1170 char [] ret = GetChars (ba, 0, byteCount);
1171 int top = ret.Length;
1173 if (top > charCount)
1174 throw new ArgumentException ("charCount is less than the number of characters produced", "charCount");
1176 for (int i = 0; i < top; i++)
1177 chars [i] = ret [i];
1181 [CLSCompliantAttribute(false)]
1182 [ComVisible (false)]
1183 public unsafe virtual int GetBytes (char *chars, int charCount, byte *bytes, int byteCount)
1186 throw new ArgumentNullException ("bytes");
1188 throw new ArgumentNullException ("chars");
1190 throw new ArgumentOutOfRangeException ("charCount");
1192 throw new ArgumentOutOfRangeException ("byteCount");
1194 char [] c = new char [charCount];
1196 for (int i = 0; i < charCount; i++)
1199 byte [] b = GetBytes (c, 0, charCount);
1201 if (top > byteCount)
1202 throw new ArgumentException ("byteCount is less that the number of bytes produced", "byteCount");
1204 for (int i = 0; i < top; i++)
1211 }; // class Encoding
1213 }; // namespace System.Text