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
;
39 public abstract class Encoding
: ICloneable
41 // Code page used by this encoding.
42 internal int codePage
;
43 internal int windows_code_page
;
44 bool is_readonly
= true;
56 Encoding (int codePage
)
58 this.codePage
= windows_code_page
= codePage
;
62 // MS has "InternalBestFit{Decoder|Encoder}Fallback
63 // here, but we dunno what they are for.
64 decoder_fallback
= DecoderFallback
.ReplacementFallback
;
65 encoder_fallback
= EncoderFallback
.ReplacementFallback
;
68 case 54936: // GB18030
69 decoder_fallback
= DecoderFallback
.ReplacementFallback
;
70 encoder_fallback
= EncoderFallback
.ReplacementFallback
;
78 decoder_fallback
= DecoderFallback
.StandardSafeFallback
;
79 encoder_fallback
= EncoderFallback
.StandardSafeFallback
;
84 // until we change the callers:
85 internal static string _ (string arg
) {
89 DecoderFallback decoder_fallback
;
90 EncoderFallback encoder_fallback
;
93 public bool IsReadOnly
{
94 get { return is_readonly; }
98 public virtual bool IsSingleByte
{
103 public DecoderFallback DecoderFallback
{
104 get { return decoder_fallback; }
107 throw new InvalidOperationException ("This Encoding is readonly.");
109 throw new ArgumentNullException ();
110 decoder_fallback
= value;
115 public EncoderFallback EncoderFallback
{
116 get { return encoder_fallback; }
119 throw new InvalidOperationException ("This Encoding is readonly.");
121 throw new ArgumentNullException ();
122 encoder_fallback
= value;
126 internal void SetFallbackInternal (EncoderFallback e
, DecoderFallback d
)
129 encoder_fallback
= e
;
131 decoder_fallback
= d
;
134 // Convert between two encodings.
135 public static byte[] Convert (Encoding srcEncoding
, Encoding dstEncoding
,
138 if (srcEncoding
== null) {
139 throw new ArgumentNullException ("srcEncoding");
141 if (dstEncoding
== null) {
142 throw new ArgumentNullException ("dstEncoding");
145 throw new ArgumentNullException ("bytes");
147 return dstEncoding
.GetBytes (srcEncoding
.GetChars (bytes
, 0, bytes
.Length
));
149 public static byte[] Convert (Encoding srcEncoding
, Encoding dstEncoding
,
150 byte[] bytes
, int index
, int count
)
152 if (srcEncoding
== null) {
153 throw new ArgumentNullException ("srcEncoding");
155 if (dstEncoding
== null) {
156 throw new ArgumentNullException ("dstEncoding");
159 throw new ArgumentNullException ("bytes");
161 if (index
< 0 || index
> bytes
.Length
) {
162 throw new ArgumentOutOfRangeException
163 ("index", _("ArgRange_Array"));
165 if (count
< 0 || (bytes
.Length
- index
) < count
) {
166 throw new ArgumentOutOfRangeException
167 ("count", _("ArgRange_Array"));
169 return dstEncoding
.GetBytes (srcEncoding
.GetChars (bytes
, index
, count
));
172 // Determine if two Encoding objects are equal.
173 public override bool Equals (Object
value)
175 Encoding enc
= (value as Encoding
);
177 return codePage
== enc
.codePage
&&
178 DecoderFallback
.Equals (enc
.DecoderFallback
) &&
179 EncoderFallback
.Equals (enc
.EncoderFallback
);
185 // Get the number of characters needed to encode a character buffer.
186 public abstract int GetByteCount (char[] chars
, int index
, int count
);
188 // Convenience wrappers for "GetByteCount".
189 public virtual int GetByteCount (String s
)
192 throw new ArgumentNullException ("s");
197 fixed (char* cptr
= s
) {
198 return GetByteCount (cptr
, s
.Length
);
202 public virtual int GetByteCount (char[] chars
)
205 return GetByteCount (chars
, 0, chars
.Length
);
207 throw new ArgumentNullException ("chars");
211 // Get the bytes that result from encoding a character buffer.
212 public abstract int GetBytes (char[] chars
, int charIndex
, int charCount
,
213 byte[] bytes
, int byteIndex
);
215 // Convenience wrappers for "GetBytes".
216 public virtual int GetBytes (String s
, int charIndex
, int charCount
,
217 byte[] bytes
, int byteIndex
)
220 throw new ArgumentNullException ("s");
221 if (charIndex
< 0 || charIndex
> s
.Length
)
222 throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
223 if (charCount
< 0 || charIndex
> (s
.Length
- charCount
))
224 throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
225 if (byteIndex
< 0 || byteIndex
> bytes
.Length
)
226 throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
228 if (charCount
== 0 || bytes
.Length
== byteIndex
)
231 fixed (char* cptr
= s
) {
232 fixed (byte* bptr
= bytes
) {
233 return GetBytes (cptr
+ charIndex
,
236 bytes
.Length
- byteIndex
);
241 public virtual byte[] GetBytes (String s
)
244 throw new ArgumentNullException ("s");
248 int byteCount
= GetByteCount (s
);
252 fixed (char* cptr
= s
) {
253 byte [] bytes
= new byte [byteCount
];
254 fixed (byte* bptr
= bytes
) {
255 GetBytes (cptr
, s
.Length
,
263 public virtual byte[] GetBytes (char[] chars
, int index
, int count
)
265 int numBytes
= GetByteCount (chars
, index
, count
);
266 byte[] bytes
= new byte [numBytes
];
267 GetBytes (chars
, index
, count
, bytes
, 0);
270 public virtual byte[] GetBytes (char[] chars
)
272 int numBytes
= GetByteCount (chars
, 0, chars
.Length
);
273 byte[] bytes
= new byte [numBytes
];
274 GetBytes (chars
, 0, chars
.Length
, bytes
, 0);
278 // Get the number of characters needed to decode a byte buffer.
279 public abstract int GetCharCount (byte[] bytes
, int index
, int count
);
281 // Convenience wrappers for "GetCharCount".
282 public virtual int GetCharCount (byte[] bytes
)
285 throw new ArgumentNullException ("bytes");
287 return GetCharCount (bytes
, 0, bytes
.Length
);
290 // Get the characters that result from decoding a byte buffer.
291 public abstract int GetChars (byte[] bytes
, int byteIndex
, int byteCount
,
292 char[] chars
, int charIndex
);
294 // Convenience wrappers for "GetChars".
295 public virtual char[] GetChars (byte[] bytes
, int index
, int count
)
297 int numChars
= GetCharCount (bytes
, index
, count
);
298 char[] chars
= new char [numChars
];
299 GetChars (bytes
, index
, count
, chars
, 0);
302 public virtual char[] GetChars (byte[] bytes
)
305 throw new ArgumentNullException ("bytes");
307 int numChars
= GetCharCount (bytes
, 0, bytes
.Length
);
308 char[] chars
= new char [numChars
];
309 GetChars (bytes
, 0, bytes
.Length
, chars
, 0);
313 // Get a decoder that forwards requests to this object.
314 public virtual Decoder
GetDecoder ()
316 return new ForwardingDecoder (this);
319 // Get an encoder that forwards requests to this object.
320 public virtual Encoder
GetEncoder ()
322 return new ForwardingEncoder (this);
325 // Loaded copy of the "I18N" assembly. We need to move
326 // this into a class in "System.Private" eventually.
327 private static Assembly i18nAssembly
;
328 private static bool i18nDisabled
;
330 // Invoke a specific method on the "I18N" manager object.
331 // Returns NULL if the method failed.
332 private static Object
InvokeI18N (String name
, params Object
[] args
)
335 // Bail out if we previously detected that there
336 // is insufficent engine support for I18N handling.
341 // Find or load the "I18N" assembly.
342 if (i18nAssembly
== null) {
345 i18nAssembly
= Assembly
.Load (Consts
.AssemblyI18N
);
346 } catch (NotImplementedException
) {
347 // Assembly loading unsupported by the engine.
351 if (i18nAssembly
== null) {
354 } catch (SystemException
) {
359 // Find the "I18N.Common.Manager" class.
362 managerClass
= i18nAssembly
.GetType ("I18N.Common.Manager");
363 } catch (NotImplementedException
) {
364 // "GetType" is not supported by the engine.
368 if (managerClass
== null) {
372 // Get the value of the "PrimaryManager" property.
375 manager
= managerClass
.InvokeMember
377 BindingFlags
.GetProperty
|
378 BindingFlags
.Static
|
380 null, null, null, null, null, null);
381 if (manager
== null) {
384 } catch (MissingMethodException
) {
386 } catch (SecurityException
) {
388 } catch (NotImplementedException
) {
389 // "InvokeMember" is not supported by the engine.
394 // Invoke the requested method on the manager.
396 return managerClass
.InvokeMember
398 BindingFlags
.InvokeMethod
|
399 BindingFlags
.Instance
|
401 null, manager
, args
, null, null, null);
402 } catch (MissingMethodException
) {
404 } catch (SecurityException
) {
410 // Get an encoder for a specific code page.
416 static Encoding
GetEncoding (int codepage
)
418 if (codepage
< 0 || codepage
> 0xffff)
419 throw new ArgumentOutOfRangeException ("codepage",
420 "Valid values are between 0 and 65535, inclusive.");
422 // Check for the builtin code pages first.
424 case 0: return Default
;
426 case ASCIIEncoding
.ASCII_CODE_PAGE
:
429 case UTF7Encoding
.UTF7_CODE_PAGE
:
432 case UTF8Encoding
.UTF8_CODE_PAGE
:
435 case UTF32Encoding
.UTF32_CODE_PAGE
:
438 case UTF32Encoding
.BIG_UTF32_CODE_PAGE
:
439 return BigEndianUTF32
;
441 case UnicodeEncoding
.UNICODE_CODE_PAGE
:
444 case UnicodeEncoding
.BIG_UNICODE_CODE_PAGE
:
445 return BigEndianUnicode
;
448 case Latin1Encoding
.ISOLATIN_CODE_PAGE
:
454 // Try to obtain a code page handler from the I18N handler.
455 Encoding enc
= (Encoding
)(InvokeI18N ("GetEncoding", codepage
));
457 enc
.is_readonly
= true;
461 // Build a code page class name.
462 String cpName
= "System.Text.CP" + codepage
.ToString ();
464 // Look for a code page converter in this assembly.
465 Assembly assembly
= Assembly
.GetExecutingAssembly ();
466 Type type
= assembly
.GetType (cpName
);
468 enc
= (Encoding
)(Activator
.CreateInstance (type
));
469 enc
.is_readonly
= true;
473 // Look in any assembly, in case the application
474 // has provided its own code page handler.
475 type
= Type
.GetType (cpName
);
477 enc
= (Encoding
)(Activator
.CreateInstance (type
));
478 enc
.is_readonly
= true;
482 // We have no idea how to handle this code page.
483 throw new NotSupportedException
484 (String
.Format ("CodePage {0} not supported", codepage
.ToString ()));
490 public virtual object Clone ()
492 Encoding e
= (Encoding
) MemberwiseClone ();
493 e
.is_readonly
= false;
499 public static Encoding
GetEncoding (int codepage
,
500 EncoderFallback encoderFallback
, DecoderFallback decoderFallback
)
502 if (encoderFallback
== null)
503 throw new ArgumentNullException ("encoderFallback");
504 if (decoderFallback
== null)
505 throw new ArgumentNullException ("decoderFallback");
507 Encoding e
= GetEncoding (codepage
).Clone () as Encoding
;
508 e
.is_readonly
= false;
509 e
.encoder_fallback
= encoderFallback
;
510 e
.decoder_fallback
= decoderFallback
;
514 public static Encoding
GetEncoding (string name
,
515 EncoderFallback encoderFallback
, DecoderFallback decoderFallback
)
517 if (encoderFallback
== null)
518 throw new ArgumentNullException ("encoderFallback");
519 if (decoderFallback
== null)
520 throw new ArgumentNullException ("decoderFallback");
522 Encoding e
= GetEncoding (name
).Clone () as Encoding
;
523 e
.is_readonly
= false;
524 e
.encoder_fallback
= encoderFallback
;
525 e
.decoder_fallback
= decoderFallback
;
531 static EncodingInfo
[] encoding_infos
;
533 // FIXME: As everyone would agree, this implementation is so *hacky*
534 // and could be very easily broken. But since there is a test for
535 // this method to make sure that this method always returns
536 // the same number and content of encoding infos, this won't
537 // matter practically.
538 public static EncodingInfo
[] GetEncodings ()
540 if (encoding_infos
== null) {
541 int [] codepages
= new int [] {
543 850, 852, 855, 857, 858, 860, 861, 862, 863,
544 864, 865, 866, 869, 870, 874, 875,
546 1026, 1047, 1140, 1141, 1142, 1143, 1144,
547 1145, 1146, 1147, 1148, 1149,
548 1200, 1201, 1250, 1251, 1252, 1253, 1254,
549 1255, 1256, 1257, 1258,
550 10000, 10079, 12000, 12001,
551 20127, 20273, 20277, 20278, 20280, 20284,
552 20285, 20290, 20297, 20420, 20424, 20866,
553 20871, 21025, 21866, 28591, 28592, 28593,
554 28594, 28595, 28596, 28597, 28598, 28599,
556 50220, 50221, 50222, 51932, 51949, 54936,
557 57002, 57003, 57004, 57005, 57006, 57007,
558 57008, 57009, 57010, 57011,
561 encoding_infos
= new EncodingInfo
[codepages
.Length
];
562 for (int i
= 0; i
< codepages
.Length
; i
++)
563 encoding_infos
[i
] = new EncodingInfo (codepages
[i
]);
565 return encoding_infos
;
570 public bool IsAlwaysNormalized ()
572 return IsAlwaysNormalized (NormalizationForm
.FormC
);
576 public virtual bool IsAlwaysNormalized (NormalizationForm form
)
578 // umm, ASCIIEncoding should have overriden this method, no?
579 return form
== NormalizationForm
.FormC
&& this is ASCIIEncoding
;
583 // Table of builtin web encoding names and the corresponding code pages.
584 private static readonly object[] encodings
=
586 ASCIIEncoding
.ASCII_CODE_PAGE
,
587 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
588 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
589 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
591 UTF7Encoding
.UTF7_CODE_PAGE
,
592 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
593 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
594 "x_unicode_2_0_utf_7",
596 UTF8Encoding
.UTF8_CODE_PAGE
,
597 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
598 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
600 UnicodeEncoding
.UNICODE_CODE_PAGE
,
601 "utf_16", "UTF_16LE", "ucs_2", "unicode",
604 UnicodeEncoding
.BIG_UNICODE_CODE_PAGE
,
605 "unicodefffe", "utf_16be",
607 UTF32Encoding
.UTF32_CODE_PAGE
,
608 "utf_32", "UTF_32LE", "ucs_4",
610 UTF32Encoding
.BIG_UTF32_CODE_PAGE
,
614 Latin1Encoding
.ISOLATIN_CODE_PAGE
,
615 "iso_8859_1", "latin1"
619 // Get an encoding object for a specific web encoding name.
620 public static Encoding
GetEncoding (String name
)
622 // Validate the parameters.
624 throw new ArgumentNullException ("name");
627 string converted
= name
.ToLowerInvariant ().Replace ('-', '_');
629 // Search the table for a name match.
631 for (int i
= 0; i
< encodings
.Length
; ++i
) {
632 object o
= encodings
[i
];
639 if (converted
== ((string)encodings
[i
]))
640 return GetEncoding (code
);
643 // Try to obtain a web encoding handler from the I18N handler.
644 Encoding enc
= (Encoding
)(InvokeI18N ("GetEncoding", name
));
649 // Build a web encoding class name.
650 String encName
= "System.Text.ENC" + converted
;
653 // Look for a code page converter in this assembly.
654 Assembly assembly
= Assembly
.GetExecutingAssembly ();
655 Type type
= assembly
.GetType (encName
);
657 return (Encoding
)(Activator
.CreateInstance (type
));
660 // Look in any assembly, in case the application
661 // has provided its own code page handler.
662 type
= Type
.GetType (encName
);
664 return (Encoding
)(Activator
.CreateInstance (type
));
667 // We have no idea how to handle this encoding name.
668 throw new ArgumentException (String
.Format ("Encoding name '{0}' not "
669 + "supported", name
), "name");
672 #endif // !ECMA_COMPAT
674 // Get a hash code for this instance.
675 public override int GetHashCode ()
677 return DecoderFallback
.GetHashCode () << 24 + EncoderFallback
.GetHashCode () << 16 + codePage
;
680 // Get the maximum number of bytes needed to encode a
681 // specified number of characters.
682 public abstract int GetMaxByteCount (int charCount
);
684 // Get the maximum number of characters needed to decode a
685 // specified number of bytes.
686 public abstract int GetMaxCharCount (int byteCount
);
688 // Get the identifying preamble for this encoding.
689 public virtual byte[] GetPreamble ()
694 // Decode a buffer of bytes into a string.
695 public virtual String
GetString (byte[] bytes
, int index
, int count
)
697 return new String (GetChars(bytes
, index
, count
));
699 public virtual String
GetString (byte[] bytes
)
702 throw new ArgumentNullException ("bytes");
704 return GetString (bytes
, 0, bytes
.Length
);
709 internal string body_name
;
710 internal string encoding_name
;
711 internal string header_name
;
712 internal bool is_mail_news_display
;
713 internal bool is_mail_news_save
;
714 internal bool is_browser_save
= false;
715 internal bool is_browser_display
= false;
716 internal string web_name
;
718 // Get the mail body name for this encoding.
719 public virtual String BodyName
726 // Get the code page represented by this object.
727 public virtual int CodePage
734 // Get the human-readable name for this encoding.
735 public virtual String EncodingName
738 return encoding_name
;
742 // Get the mail agent header name for this encoding.
743 public virtual String HeaderName
750 // Determine if this encoding can be displayed in a Web browser.
751 public virtual bool IsBrowserDisplay
754 return is_browser_display
;
758 // Determine if this encoding can be saved from a Web browser.
759 public virtual bool IsBrowserSave
762 return is_browser_save
;
766 // Determine if this encoding can be displayed in a mail/news agent.
767 public virtual bool IsMailNewsDisplay
770 return is_mail_news_display
;
774 // Determine if this encoding can be saved from a mail/news agent.
775 public virtual bool IsMailNewsSave
778 return is_mail_news_save
;
782 // Get the IANA-preferred Web name for this encoding.
783 public virtual String WebName
790 // Get the Windows code page represented by this object.
791 public virtual int WindowsCodePage
794 // We make no distinction between normal and
795 // Windows code pages in this implementation.
796 return windows_code_page
;
800 #endif // !ECMA_COMPAT
802 // Storage for standard encoding objects.
803 static volatile Encoding asciiEncoding
;
804 static volatile Encoding bigEndianEncoding
;
805 static volatile Encoding defaultEncoding
;
806 static volatile Encoding utf7Encoding
;
807 static volatile Encoding utf8EncodingWithMarkers
;
808 static volatile Encoding utf8EncodingWithoutMarkers
;
809 static volatile Encoding unicodeEncoding
;
810 static volatile Encoding isoLatin1Encoding
;
811 static volatile Encoding utf8EncodingUnsafe
;
812 static volatile Encoding utf32Encoding
;
813 static volatile Encoding bigEndianUTF32Encoding
;
815 static readonly object lockobj
= new object ();
817 // Get the standard ASCII encoding object.
818 public static Encoding ASCII
821 if (asciiEncoding
== null) {
823 if (asciiEncoding
== null) {
824 asciiEncoding
= new ASCIIEncoding ();
825 // asciiEncoding.is_readonly = true;
830 return asciiEncoding
;
834 // Get the standard big-endian Unicode encoding object.
835 public static Encoding BigEndianUnicode
838 if (bigEndianEncoding
== null) {
840 if (bigEndianEncoding
== null) {
841 bigEndianEncoding
= new UnicodeEncoding (true, true);
842 // bigEndianEncoding.is_readonly = true;
847 return bigEndianEncoding
;
851 [MethodImpl (MethodImplOptions
.InternalCall
)]
852 extern internal static string InternalCodePage (ref int code_page
);
854 // Get the default encoding object.
855 public static Encoding Default
858 if (defaultEncoding
== null) {
860 if (defaultEncoding
== null) {
861 // See if the underlying system knows what
862 // code page handler we should be using.
865 string code_page_name
= InternalCodePage (ref code_page
);
868 defaultEncoding
= GetEncoding (code_page_name
);
870 // map the codepage from internal to our numbers
871 code_page
= code_page
& 0x0fffffff;
873 case 1: code_page
= ASCIIEncoding
.ASCII_CODE_PAGE
; break;
874 case 2: code_page
= UTF7Encoding
.UTF7_CODE_PAGE
; break;
875 case 3: code_page
= UTF8Encoding
.UTF8_CODE_PAGE
; break;
876 case 4: code_page
= UnicodeEncoding
.UNICODE_CODE_PAGE
; break;
877 case 5: code_page
= UnicodeEncoding
.BIG_UNICODE_CODE_PAGE
; break;
879 case 6: code_page
= Latin1Encoding
.ISOLATIN_CODE_PAGE
; break;
882 defaultEncoding
= GetEncoding (code_page
);
884 } catch (NotSupportedException
) {
886 defaultEncoding
= UTF8
;
888 // code_page is not supported on underlying platform
889 defaultEncoding
= UTF8Unmarked
;
891 } catch (ArgumentException
) {
892 // code_page_name is not a valid code page, or is
893 // not supported by underlying OS
895 defaultEncoding
= UTF8
;
897 defaultEncoding
= UTF8Unmarked
;
900 defaultEncoding
.is_readonly
= true;
905 return defaultEncoding
;
911 // Get the ISO Latin1 encoding object.
912 private static Encoding ISOLatin1
915 if (isoLatin1Encoding
== null) {
917 if (isoLatin1Encoding
== null) {
918 isoLatin1Encoding
= new Latin1Encoding ();
919 // isoLatin1Encoding.is_readonly = true;
924 return isoLatin1Encoding
;
930 // Get the standard UTF-7 encoding object.
939 if (utf7Encoding
== null) {
941 if (utf7Encoding
== null) {
942 utf7Encoding
= new UTF7Encoding ();
943 // utf7Encoding.is_readonly = true;
952 // Get the standard UTF-8 encoding object.
953 public static Encoding UTF8
956 if (utf8EncodingWithMarkers
== null) {
958 if (utf8EncodingWithMarkers
== null) {
959 utf8EncodingWithMarkers
= new UTF8Encoding (true);
960 // utf8EncodingWithMarkers.is_readonly = true;
965 return utf8EncodingWithMarkers
;
970 // Only internal, to be used by the class libraries: Unmarked and non-input-validating
972 internal static Encoding UTF8Unmarked
{
974 if (utf8EncodingWithoutMarkers
== null) {
976 if (utf8EncodingWithoutMarkers
== null){
977 utf8EncodingWithoutMarkers
= new UTF8Encoding (false, false);
978 // utf8EncodingWithoutMarkers.is_readonly = true;
983 return utf8EncodingWithoutMarkers
;
988 // Only internal, to be used by the class libraries: Unmarked and non-input-validating
990 internal static Encoding UTF8UnmarkedUnsafe
{
992 if (utf8EncodingUnsafe
== null) {
994 if (utf8EncodingUnsafe
== null){
995 utf8EncodingUnsafe
= new UTF8Encoding (false, false);
996 utf8EncodingUnsafe
.is_readonly
= false;
997 utf8EncodingUnsafe
.DecoderFallback
= new DecoderReplacementFallback (String
.Empty
);
998 utf8EncodingUnsafe
.is_readonly
= true;
1003 return utf8EncodingUnsafe
;
1007 // Get the standard little-endian Unicode encoding object.
1008 public static Encoding Unicode
1011 if (unicodeEncoding
== null) {
1013 if (unicodeEncoding
== null) {
1014 unicodeEncoding
= new UnicodeEncoding (false, true);
1015 // unicodeEncoding.is_readonly = true;
1020 return unicodeEncoding
;
1024 // Get the standard little-endian UTF-32 encoding object.
1025 public static Encoding UTF32
1028 if (utf32Encoding
== null) {
1030 if (utf32Encoding
== null) {
1031 utf32Encoding
= new UTF32Encoding (false, true);
1032 // utf32Encoding.is_readonly = true;
1037 return utf32Encoding
;
1041 // Get the standard big-endian UTF-32 encoding object.
1042 internal static Encoding BigEndianUTF32
1045 if (bigEndianUTF32Encoding
== null) {
1047 if (bigEndianUTF32Encoding
== null) {
1048 bigEndianUTF32Encoding
= new UTF32Encoding (true, true);
1049 // bigEndianUTF32Encoding.is_readonly = true;
1054 return bigEndianUTF32Encoding
;
1058 // Forwarding decoder implementation.
1059 private sealed class ForwardingDecoder
: Decoder
1061 private Encoding encoding
;
1064 public ForwardingDecoder (Encoding enc
)
1067 DecoderFallback fallback
= encoding
.DecoderFallback
;
1068 if (fallback
!= null)
1069 Fallback
= fallback
;
1072 // Override inherited methods.
1073 public override int GetCharCount (byte[] bytes
, int index
, int count
)
1075 return encoding
.GetCharCount (bytes
, index
, count
);
1077 public override int GetChars (byte[] bytes
, int byteIndex
,
1078 int byteCount
, char[] chars
,
1081 return encoding
.GetChars (bytes
, byteIndex
, byteCount
, chars
, charIndex
);
1084 } // class ForwardingDecoder
1086 // Forwarding encoder implementation.
1087 private sealed class ForwardingEncoder
: Encoder
1089 private Encoding encoding
;
1092 public ForwardingEncoder (Encoding enc
)
1095 EncoderFallback fallback
= encoding
.EncoderFallback
;
1096 if (fallback
!= null)
1097 Fallback
= fallback
;
1100 // Override inherited methods.
1101 public override int GetByteCount (char[] chars
, int index
, int count
, bool flush
)
1103 return encoding
.GetByteCount (chars
, index
, count
);
1105 public override int GetBytes (char[] chars
, int charIndex
,
1106 int charCount
, byte[] bytes
,
1107 int byteCount
, bool flush
)
1109 return encoding
.GetBytes (chars
, charIndex
, charCount
, bytes
, byteCount
);
1112 } // class ForwardingEncoder
1114 [CLSCompliantAttribute(false)]
1115 [ComVisible (false)]
1116 public unsafe virtual int GetByteCount (char *chars
, int count
)
1119 throw new ArgumentNullException ("chars");
1121 throw new ArgumentOutOfRangeException ("count");
1122 char [] c
= new char [count
];
1124 for (int p
= 0; p
< count
; p
++)
1127 return GetByteCount (c
);
1130 [CLSCompliantAttribute(false)]
1131 [ComVisible (false)]
1132 public unsafe virtual int GetCharCount (byte *bytes
, int count
)
1135 throw new ArgumentNullException ("bytes");
1137 throw new ArgumentOutOfRangeException ("count");
1139 byte [] ba
= new byte [count
];
1140 for (int i
= 0; i
< count
; i
++)
1142 return GetCharCount (ba
, 0, count
);
1145 [CLSCompliantAttribute(false)]
1146 [ComVisible (false)]
1147 public unsafe virtual int GetChars (byte *bytes
, int byteCount
, char *chars
, int charCount
)
1150 throw new ArgumentNullException ("bytes");
1152 throw new ArgumentNullException ("chars");
1154 throw new ArgumentOutOfRangeException ("charCount");
1156 throw new ArgumentOutOfRangeException ("byteCount");
1158 byte [] ba
= new byte [byteCount
];
1159 for (int i
= 0; i
< byteCount
; i
++)
1161 char [] ret
= GetChars (ba
, 0, byteCount
);
1162 int top
= ret
.Length
;
1164 if (top
> charCount
)
1165 throw new ArgumentException ("charCount is less than the number of characters produced", "charCount");
1167 for (int i
= 0; i
< top
; i
++)
1168 chars
[i
] = ret
[i
];
1172 [CLSCompliantAttribute(false)]
1173 [ComVisible (false)]
1174 public unsafe virtual int GetBytes (char *chars
, int charCount
, byte *bytes
, int byteCount
)
1177 throw new ArgumentNullException ("bytes");
1179 throw new ArgumentNullException ("chars");
1181 throw new ArgumentOutOfRangeException ("charCount");
1183 throw new ArgumentOutOfRangeException ("byteCount");
1185 char [] c
= new char [charCount
];
1187 for (int i
= 0; i
< charCount
; i
++)
1190 byte [] b
= GetBytes (c
, 0, charCount
);
1192 if (top
> byteCount
)
1193 throw new ArgumentException ("byteCount is less that the number of bytes produced", "byteCount");
1195 for (int i
= 0; i
< top
; i
++)
1200 }; // class Encoding
1202 }; // namespace System.Text