3 // Copyright (c) Microsoft Corporation. All rights reserved.
9 using System
.Collections
.Generic
;
11 using System
.Runtime
.Remoting
;
12 using System
.Runtime
.Serialization
;
13 using System
.Globalization
;
14 using System
.Security
;
15 using System
.Security
.Permissions
;
16 using System
.Threading
;
18 using System
.Diagnostics
.CodeAnalysis
;
19 using System
.Diagnostics
.Contracts
;
20 using System
.Diagnostics
;
21 using System
.Runtime
.InteropServices
;
22 #if FEATURE_CODEPAGES_FILE
23 using Win32Native
= Microsoft
.Win32
.Win32Native
;
26 // This abstract base class represents a character encoding. The class provides
27 // methods to convert arrays and strings of Unicode characters to and from
28 // arrays of bytes. A number of Encoding implementations are provided in
29 // the System.Text package, including:
31 // ASCIIEncoding, which encodes Unicode characters as single 7-bit
32 // ASCII characters. This encoding only supports character values between 0x00
34 // BaseCodePageEncoding, which encapsulates a Windows code page. Any
35 // installed code page can be accessed through this encoding, and conversions
36 // are performed using the WideCharToMultiByte and
37 // MultiByteToWideChar Windows API functions.
38 // UnicodeEncoding, which encodes each Unicode character as two
39 // consecutive bytes. Both little-endian (code page 1200) and big-endian (code
40 // page 1201) encodings are recognized.
41 // UTF7Encoding, which encodes Unicode characters using the UTF-7
42 // encoding (UTF-7 stands for UCS Transformation Format, 7-bit form). This
43 // encoding supports all Unicode character values, and can also be accessed
44 // as code page 65000.
45 // UTF8Encoding, which encodes Unicode characters using the UTF-8
46 // encoding (UTF-8 stands for UCS Transformation Format, 8-bit form). This
47 // encoding supports all Unicode character values, and can also be accessed
48 // as code page 65001.
49 // UTF32Encoding, both 12000 (little endian) & 12001 (big endian)
51 // In addition to directly instantiating Encoding objects, an
52 // application can use the ForCodePage, GetASCII,
53 // GetDefault, GetUnicode, GetUTF7, and GetUTF8
54 // methods in this class to obtain encodings.
56 // Through an encoding, the GetBytes method is used to convert arrays
57 // of characters to arrays of bytes, and the GetChars method is used to
58 // convert arrays of bytes to arrays of characters. The GetBytes and
59 // GetChars methods maintain no state between conversions, and are
60 // generally intended for conversions of complete blocks of bytes and
61 // characters in one operation. When the data to be converted is only available
62 // in sequential blocks (such as data read from a stream) or when the amount of
63 // data is so large that it needs to be divided into smaller blocks, an
64 // application may choose to use a Decoder or an Encoder to
65 // perform the conversion. Decoders and encoders allow sequential blocks of
66 // data to be converted and they maintain the state required to support
67 // conversions of data that spans adjacent blocks. Decoders and encoders are
68 // obtained using the GetDecoder and GetEncoder methods.
70 // The core GetBytes and GetChars methods require the caller
71 // to provide the destination buffer and ensure that the buffer is large enough
72 // to hold the entire result of the conversion. When using these methods,
73 // either directly on an Encoding object or on an associated
74 // Decoder or Encoder, an application can use one of two methods
75 // to allocate destination buffers.
77 // The GetByteCount and GetCharCount methods can be used to
78 // compute the exact size of the result of a particular conversion, and an
79 // appropriately sized buffer for that conversion can then be allocated.
80 // The GetMaxByteCount and GetMaxCharCount methods can be
81 // be used to compute the maximum possible size of a conversion of a given
82 // number of bytes or characters, and a buffer of that size can then be reused
83 // for multiple conversions.
85 // The first method generally uses less memory, whereas the second method
86 // generally executes faster.
89 [System
.Runtime
.InteropServices
.ComVisible(true)]
91 public abstract class Encoding
: ICloneable
93 private static volatile Encoding defaultEncoding
;
94 private static volatile Encoding unicodeEncoding
;
95 private static volatile Encoding bigEndianUnicode
;
97 private static volatile Encoding utf7Encoding
;
99 private static volatile Encoding utf8Encoding
;
101 private static volatile Encoding utf32Encoding
;
104 private static volatile Encoding asciiEncoding
;
107 private static volatile Encoding latin1Encoding
;
109 static volatile Dictionary
<int, Encoding
> encodings
;
112 // The following values are from mlang.idl. These values
113 // should be in sync with those in mlang.idl.
115 private const int MIMECONTF_MAILNEWS
= 0x00000001;
116 private const int MIMECONTF_BROWSER
= 0x00000002;
117 private const int MIMECONTF_SAVABLE_MAILNEWS
= 0x00000100;
118 private const int MIMECONTF_SAVABLE_BROWSER
= 0x00000200;
120 // Special Case Code Pages
121 private const int CodePageDefault
= 0;
122 private const int CodePageNoOEM
= 1; // OEM Code page not supported
123 private const int CodePageNoMac
= 2; // MAC code page not supported
124 private const int CodePageNoThread
= 3; // Thread code page not supported
125 private const int CodePageNoSymbol
= 42; // Symbol code page not supported
126 private const int CodePageUnicode
= 1200; // Unicode
127 private const int CodePageBigEndian
= 1201; // Big Endian Unicode
128 private const int CodePageWindows1252
= 1252; // Windows 1252 code page
130 // 20936 has same code page as 10008, so we'll special case it
131 private const int CodePageMacGB2312
= 10008;
132 private const int CodePageGB2312
= 20936;
133 private const int CodePageMacKorean
= 10003;
134 private const int CodePageDLLKorean
= 20949;
136 // ISO 2022 Code Pages
137 private const int ISO2022JP
= 50220;
138 private const int ISO2022JPESC
= 50221;
139 private const int ISO2022JPSISO
= 50222;
140 private const int ISOKorean
= 50225;
141 private const int ISOSimplifiedCN
= 50227;
142 private const int EUCJP
= 51932;
143 private const int ChineseHZ
= 52936; // HZ has ~}~{~~ sequences
145 // 51936 is the same as 936
146 private const int DuplicateEUCCN
= 51936;
147 private const int EUCCN
= 936;
149 private const int EUCKR
= 51949;
151 // Latin 1 & ASCII Code Pages
152 internal const int CodePageASCII
= 20127; // ASCII
153 internal const int ISO_8859_1
= 28591; // Latin1
156 private const int ISCIIAssemese
= 57006;
157 private const int ISCIIBengali
= 57003;
158 private const int ISCIIDevanagari
= 57002;
159 private const int ISCIIGujarathi
= 57010;
160 private const int ISCIIKannada
= 57008;
161 private const int ISCIIMalayalam
= 57009;
162 private const int ISCIIOriya
= 57007;
163 private const int ISCIIPanjabi
= 57011;
164 private const int ISCIITamil
= 57004;
165 private const int ISCIITelugu
= 57005;
168 private const int GB18030
= 54936;
171 private const int ISO_8859_8I
= 38598;
172 private const int ISO_8859_8_Visual
= 28598;
174 // 50229 is currently unsupported // "Chinese Traditional (ISO-2022)"
175 private const int ENC50229
= 50229;
177 // Special code pages
178 private const int CodePageUTF7
= 65000;
179 private const int CodePageUTF8
= 65001;
180 private const int CodePageUTF32
= 12000;
181 private const int CodePageUTF32BE
= 12001;
183 internal int m_codePage
= 0;
185 // dataItem should be internal (not private). otherwise it will break during the deserialization
186 // of the data came from Everett
187 internal CodePageDataItem dataItem
= null;
190 internal bool m_deserializedFromEverett
= false;
192 // Because of encoders we may be read only
193 [OptionalField(VersionAdded
= 2)]
194 private bool m_isReadOnly
= true;
196 // Encoding (encoder) fallback
197 [OptionalField(VersionAdded
= 2)]
198 internal EncoderFallback encoderFallback
= null;
199 [OptionalField(VersionAdded
= 2)]
200 internal DecoderFallback decoderFallback
= null;
202 protected Encoding() : this(0)
207 protected Encoding(int codePage
)
209 // Validate code page
212 throw new ArgumentOutOfRangeException("codePage");
214 Contract
.EndContractBlock();
216 // Remember code page
217 m_codePage
= codePage
;
219 // Use default encoder/decoder fallbacks
220 this.SetDefaultFallbacks();
223 // This constructor is needed to allow any sub-classing implementation to provide encoder/decoder fallback objects
224 // because the encoding object is always created as read-only object and don’t allow setting encoder/decoder fallback
225 // after the creation is done.
226 protected Encoding(int codePage
, EncoderFallback encoderFallback
, DecoderFallback decoderFallback
)
228 // Validate code page
231 throw new ArgumentOutOfRangeException("codePage");
233 Contract
.EndContractBlock();
235 // Remember code page
236 m_codePage
= codePage
;
238 this.encoderFallback
= encoderFallback
?? new InternalEncoderBestFitFallback(this);
239 this.decoderFallback
= decoderFallback
?? new InternalDecoderBestFitFallback(this);
242 // Default fallback that we'll use.
243 internal virtual void SetDefaultFallbacks()
245 // For UTF-X encodings, we use a replacement fallback with an "\xFFFD" string,
246 // For ASCII we use "?" replacement fallback, etc.
247 this.encoderFallback
= new InternalEncoderBestFitFallback(this);
248 this.decoderFallback
= new InternalDecoderBestFitFallback(this);
252 #region Serialization
253 internal void OnDeserializing()
255 // intialize the optional Whidbey fields
256 encoderFallback
= null;
257 decoderFallback
= null;
261 internal void OnDeserialized()
263 if (encoderFallback
== null || decoderFallback
== null)
265 m_deserializedFromEverett
= true;
266 SetDefaultFallbacks();
269 // dataItem is always recalculated from the code page #
274 private void OnDeserializing(StreamingContext ctx
)
281 private void OnDeserialized(StreamingContext ctx
)
287 private void OnSerializing(StreamingContext ctx
)
289 // to be consistent with SerializeEncoding
293 // the following two methods are used for the inherited classes which implemented ISerializable
294 // Deserialization Helper
295 internal void DeserializeEncoding(SerializationInfo info
, StreamingContext context
)
298 if (info
==null) throw new ArgumentNullException("info");
299 Contract
.EndContractBlock();
301 // All versions have a code page
302 this.m_codePage
= (int)info
.GetValue("m_codePage", typeof(int));
304 // We can get dataItem on the fly if needed, and the index is different between versions
305 // so ignore whatever dataItem data we get from Everett.
306 this.dataItem
= null;
308 // See if we have a code page
312 // Try Whidbey V2.0 Fields
315 this.m_isReadOnly
= (bool)info
.GetValue("m_isReadOnly", typeof(bool));
317 this.encoderFallback
= (EncoderFallback
)info
.GetValue("encoderFallback", typeof(EncoderFallback
));
318 this.decoderFallback
= (DecoderFallback
)info
.GetValue("decoderFallback", typeof(DecoderFallback
));
320 catch (SerializationException
)
323 // Didn't have Whidbey things, must be Everett
325 this.m_deserializedFromEverett
= true;
327 // May as well be read only
328 this.m_isReadOnly
= true;
329 SetDefaultFallbacks();
333 // Serialization Helper
334 internal void SerializeEncoding(SerializationInfo info
, StreamingContext context
)
337 if (info
==null) throw new ArgumentNullException("info");
338 Contract
.EndContractBlock();
340 // These are new V2.0 Whidbey stuff
341 info
.AddValue("m_isReadOnly", this.m_isReadOnly
);
342 info
.AddValue("encoderFallback", this.EncoderFallback
);
343 info
.AddValue("decoderFallback", this.DecoderFallback
);
345 // These were in Everett V1.1 as well
346 info
.AddValue("m_codePage", this.m_codePage
);
348 // This was unique to Everett V1.1
349 info
.AddValue("dataItem", null);
351 // Everett duplicated these fields, so these are needed for portability
352 info
.AddValue("Encoding+m_codePage", this.m_codePage
);
353 info
.AddValue("Encoding+dataItem", null);
356 #endregion Serialization
358 // Converts a byte array from one encoding to another. The bytes in the
359 // bytes array are converted from srcEncoding to
360 // dstEncoding, and the returned value is a new byte array
361 // containing the result of the conversion.
364 public static byte[] Convert(Encoding srcEncoding
, Encoding dstEncoding
,
367 throw new ArgumentNullException("bytes");
368 Contract
.Ensures(Contract
.Result
<byte[]>() != null);
370 return Convert(srcEncoding
, dstEncoding
, bytes
, 0, bytes
.Length
);
373 // Converts a range of bytes in a byte array from one encoding to another.
374 // This method converts count bytes from bytes starting at
375 // index index from srcEncoding to dstEncoding, and
376 // returns a new byte array containing the result of the conversion.
379 public static byte[] Convert(Encoding srcEncoding
, Encoding dstEncoding
,
380 byte[] bytes
, int index
, int count
) {
381 if (srcEncoding
== null || dstEncoding
== null) {
382 throw new ArgumentNullException((srcEncoding
== null ? "srcEncoding" : "dstEncoding"),
383 Environment
.GetResourceString("ArgumentNull_Array"));
386 throw new ArgumentNullException("bytes",
387 Environment
.GetResourceString("ArgumentNull_Array"));
389 Contract
.Ensures(Contract
.Result
<byte[]>() != null);
391 return dstEncoding
.GetBytes(srcEncoding
.GetChars(bytes
, index
, count
));
394 // Private object for locking instead of locking on a public type for SQL reliability work.
395 private static Object s_InternalSyncObject
;
396 private static Object InternalSyncObject
{
398 if (s_InternalSyncObject
== null) {
399 Object o
= new Object();
400 Interlocked
.CompareExchange
<Object
>(ref s_InternalSyncObject
, o
, null);
402 return s_InternalSyncObject
;
407 [System
.Security
.SecurityCritical
]
409 public static void RegisterProvider(EncodingProvider provider
)
411 // Parameters validated inside EncodingProvider
412 EncodingProvider
.AddProvider(provider
);
417 [System
.Security
.SecuritySafeCritical
] // auto-generated
419 public static Encoding
GetEncoding(int codepage
)
421 Encoding result
= EncodingProvider
.GetEncodingFromProvider(codepage
);
426 // NOTE: If you add a new encoding that can be get by codepage, be sure to
427 // add the corresponding item in EncodingTable.
428 // Otherwise, the code below will throw exception when trying to call
429 // EncodingTable.GetDataItem().
431 if (codepage
< 0 || codepage
> 65535) {
432 throw new ArgumentOutOfRangeException(
433 "codepage", Environment
.GetResourceString("ArgumentOutOfRange_Range",
437 Contract
.EndContractBlock();
441 // See if we have a hash table with our encoding in it already.
442 if (encodings
!= null)
443 encodings
.TryGetValue (codepage
, out result
);
447 // Don't conflict with ourselves
448 lock (InternalSyncObject
)
450 // Need a new hash table
451 // in case another thread beat us to creating the Dictionary
452 if (encodings
== null)
453 encodings
= new Dictionary
<int, Encoding
> ();
455 // Double check that we don't have one in the table (in case another thread beat us here)
456 if (encodings
.TryGetValue (codepage
, out result
))
459 // Special case the commonly used Encoding classes here, then call
460 // GetEncodingRare to avoid loading classes like MLangCodePageEncoding
461 // and ASCIIEncoding. ASP.NET uses UTF-8 & ISO-8859-1.
464 case CodePageDefault
: // 0, default code page
465 result
= Encoding
.Default
;
467 case CodePageUnicode
: // 1200, Unicode
470 case CodePageBigEndian
: // 1201, big endian unicode
471 result
= BigEndianUnicode
;
473 #if FEATURE_CODEPAGES_FILE
474 case CodePageWindows1252
: // 1252, Windows
475 result
= new SBCSCodePageEncoding(codepage
);
480 // on desktop, UTF7 is handled by GetEncodingRare.
481 // On Coreclr, we handle this directly without bringing GetEncodingRare, so that we get real UTF-7 encoding.
482 case CodePageUTF7
: // 65000, UTF7
488 case CodePageUTF32
: // 12000
491 case CodePageUTF32BE
: // 12001
492 result
= new UTF32Encoding(true, true);
497 case CodePageUTF8
: // 65001, UTF8
501 // These are (hopefully) not very common, but also shouldn't slow us down much and make default
502 // case able to handle more code pages by calling GetEncodingCodePage
503 case CodePageNoOEM
: // 1
504 case CodePageNoMac
: // 2
505 case CodePageNoThread
: // 3
506 case CodePageNoSymbol
: // 42
507 // Win32 also allows the following special code page values. We won't allow them except in the
509 // #define CP_ACP 0 // default to ANSI code page
510 // #define CP_OEMCP 1 // default to OEM code page
511 // #define CP_MACCP 2 // default to MAC code page
512 // #define CP_THREAD_ACP 3 // current thread's ANSI code page
513 // #define CP_SYMBOL 42 // SYMBOL translations
514 throw new ArgumentException(Environment
.GetResourceString(
515 "Argument_CodepageNotSupported", codepage
), "codepage");
517 // Have to do ASCII and Latin 1 first so they don't get loaded as code pages
518 case CodePageASCII
: // 20127
523 case ISO_8859_1
: // 28591
529 #if FEATURE_CODEPAGES_FILE
530 // 1st assume its a code page.
531 result
= GetEncodingCodePage(codepage
);
533 result
= GetEncodingRare(codepage
);
536 // Is it a valid code page?
537 if (EncodingTable
.GetCodePageDataItem(codepage
) == null)
539 throw new NotSupportedException(
540 Environment
.GetResourceString("NotSupported_NoCodepageData", codepage
));
542 #if MONO_HYBRID_ENCODING_SUPPORT
544 case CodePageUTF32
: // 12000
547 case CodePageUTF32BE
: // 12001
548 result
= new UTF32Encoding(true, true);
551 result
= (Encoding
)(EncodingHelper
.InvokeI18N ("GetEncoding", codepage
));
553 throw new NotSupportedException(string.Format("Encoding {0} data could not be found. Make sure you have correct international codeset assembly installed and enabled.", codepage
));
560 #endif // FEATURE_CODEPAGES_FILE
563 encodings
.Add(codepage
, result
);
571 public static Encoding
GetEncoding(int codepage
,
572 EncoderFallback encoderFallback
, DecoderFallback decoderFallback
)
574 Encoding baseEncoding
= EncodingProvider
.GetEncodingFromProvider(codepage
, encoderFallback
, decoderFallback
);
576 if (baseEncoding
!= null)
579 // Get the default encoding (which is cached and read only)
580 baseEncoding
= GetEncoding(codepage
);
582 // Clone it and set the fallback
583 Encoding fallbackEncoding
= (Encoding
)baseEncoding
.Clone();
584 fallbackEncoding
.EncoderFallback
= encoderFallback
;
585 fallbackEncoding
.DecoderFallback
= decoderFallback
;
587 return fallbackEncoding
;
589 #if FEATURE_CODEPAGES_FILE
590 [System
.Security
.SecurityCritical
] // auto-generated
591 private static Encoding
GetEncodingRare(int codepage
)
593 Contract
.Assert(codepage
!= 0 && codepage
!= 1200 && codepage
!= 1201 && codepage
!= 65001,
594 "[Encoding.GetEncodingRare]This code page (" + codepage
+ ") isn't supported by GetEncodingRare!");
598 case CodePageUTF7
: // 65000
601 case CodePageUTF32
: // 12000
604 case CodePageUTF32BE
: // 12001
605 result
= new UTF32Encoding(true, true);
609 case ISCIIDevanagari
:
617 result
= new ISCIIEncoding(codepage
);
619 // GB2312-80 uses same code page for 20936 and mac 10008
620 case CodePageMacGB2312
:
621 // case CodePageGB2312:
622 // result = new DBCSCodePageEncoding(codepage, EUCCN);
623 result
= new DBCSCodePageEncoding(CodePageMacGB2312
, CodePageGB2312
);
626 // Mac Korean 10003 and 20949 are the same
627 case CodePageMacKorean
:
628 result
= new DBCSCodePageEncoding(CodePageMacKorean
, CodePageDLLKorean
);
630 // GB18030 Code Pages
632 result
= new GB18030Encoding();
634 // ISO2022 Code Pages
636 // case ISOSimplifiedCN
638 case ISO2022JP
: // JIS JP, full-width Katakana mode (no half-width Katakana)
639 case ISO2022JPESC
: // JIS JP, esc sequence to do Katakana.
640 case ISO2022JPSISO
: // JIS JP with Shift In/ Shift Out Katakana support
641 result
= new ISO2022Encoding(codepage
);
643 // Duplicate EUC-CN (51936) just calls a base code page 936,
644 // so does ISOSimplifiedCN (50227), which's gotta be broken
646 case ISOSimplifiedCN
:
647 result
= new DBCSCodePageEncoding(codepage
, EUCCN
); // Just maps to 936
650 result
= new EUCJPEncoding();
653 result
= new DBCSCodePageEncoding(codepage
, CodePageDLLKorean
); // Maps to 20949
656 throw new NotSupportedException(Environment
.GetResourceString("NotSupported_CodePage50229"));
658 result
= new SBCSCodePageEncoding(codepage
, ISO_8859_8_Visual
); // Hebrew maps to a different code page
661 // Not found, already tried codepage table code pages in GetEncoding()
662 throw new NotSupportedException(
663 Environment
.GetResourceString("NotSupported_NoCodepageData", codepage
));
668 [System
.Security
.SecurityCritical
] // auto-generated
669 private static Encoding
GetEncodingCodePage(int CodePage
)
671 // Single Byte or Double Byte Code Page? (0 if not found)
672 int i
= BaseCodePageEncoding
.GetCodePageByteSize(CodePage
);
673 if (i
== 1) return new SBCSCodePageEncoding(CodePage
);
674 else if (i
== 2) return new DBCSCodePageEncoding(CodePage
);
676 // Return null if we didn't find one.
679 #endif // FEATURE_CODEPAGES_FILE
680 // Returns an Encoding object for a given name or a given code page value.
683 public static Encoding
GetEncoding(String name
)
685 Encoding baseEncoding
= EncodingProvider
.GetEncodingFromProvider(name
);
686 if (baseEncoding
!= null)
690 // NOTE: If you add a new encoding that can be requested by name, be sure to
691 // add the corresponding item in EncodingTable.
692 // Otherwise, the code below will throw exception when trying to call
693 // EncodingTable.GetCodePageFromName().
695 return (GetEncoding(EncodingTable
.GetCodePageFromName(name
)));
698 // Returns an Encoding object for a given name or a given code page value.
701 public static Encoding
GetEncoding(String name
,
702 EncoderFallback encoderFallback
, DecoderFallback decoderFallback
)
704 Encoding baseEncoding
= EncodingProvider
.GetEncodingFromProvider(name
, encoderFallback
, decoderFallback
);
705 if (baseEncoding
!= null)
709 // NOTE: If you add a new encoding that can be requested by name, be sure to
710 // add the corresponding item in EncodingTable.
711 // Otherwise, the code below will throw exception when trying to call
712 // EncodingTable.GetCodePageFromName().
714 return (GetEncoding(EncodingTable
.GetCodePageFromName(name
), encoderFallback
, decoderFallback
));
717 // Return a list of all EncodingInfo objects describing all of our encodings
719 public static EncodingInfo
[] GetEncodings()
721 return EncodingTable
.GetEncodings();
725 public virtual byte[] GetPreamble()
727 return EmptyArray
<Byte
>.Value
;
731 public virtual ReadOnlySpan
<byte> Preamble
=> GetPreamble();
734 private void GetDataItem() {
735 if (dataItem
==null) {
736 dataItem
= EncodingTable
.GetCodePageDataItem(m_codePage
);
738 throw new NotSupportedException(
739 Environment
.GetResourceString("NotSupported_NoCodepageData", m_codePage
));
744 // Returns the name for this encoding that can be used with mail agent body tags.
745 // If the encoding may not be used, the string is empty.
747 public virtual String BodyName
751 if (dataItem
==null) {
754 return (dataItem
.BodyName
);
758 // Returns the human-readable description of the encoding ( e.g. Hebrew (DOS)).
760 public virtual String EncodingName
765 return (Environment
.GetResourceStringEncodingName(m_codePage
));
767 return (Environment
.GetResourceString("Globalization.cp_" + m_codePage
));
772 // Returns the name for this encoding that can be used with mail agent header
773 // tags. If the encoding may not be used, the string is empty.
775 public virtual String HeaderName
779 if (dataItem
==null) {
782 return (dataItem
.HeaderName
);
786 // Returns the array of IANA-registered names for this encoding. If there is an
787 // IANA preferred name, it is the first name in the array.
789 public virtual String WebName
793 if (dataItem
==null) {
796 return (dataItem
.WebName
);
800 // Returns the windows code page that most closely corresponds to this encoding.
802 public virtual int WindowsCodePage
806 if (dataItem
==null) {
809 return (dataItem
.UIFamilyCodePage
);
814 // True if and only if the encoding is used for display by browsers clients.
816 public virtual bool IsBrowserDisplay
{
818 if (dataItem
==null) {
821 return ((dataItem
.Flags
& MIMECONTF_BROWSER
) != 0);
825 // True if and only if the encoding is used for saving by browsers clients.
827 public virtual bool IsBrowserSave
{
829 if (dataItem
==null) {
832 return ((dataItem
.Flags
& MIMECONTF_SAVABLE_BROWSER
) != 0);
836 // True if and only if the encoding is used for display by mail and news clients.
838 public virtual bool IsMailNewsDisplay
{
840 if (dataItem
==null) {
843 return ((dataItem
.Flags
& MIMECONTF_MAILNEWS
) != 0);
848 // True if and only if the encoding is used for saving documents by mail and
851 public virtual bool IsMailNewsSave
{
853 if (dataItem
==null) {
856 return ((dataItem
.Flags
& MIMECONTF_SAVABLE_MAILNEWS
) != 0);
860 // True if and only if the encoding only uses single byte code points. (Ie, ASCII, 1252, etc)
862 [System
.Runtime
.InteropServices
.ComVisible(false)]
863 public virtual bool IsSingleByte
872 [System
.Runtime
.InteropServices
.ComVisible(false)]
873 public EncoderFallback EncoderFallback
877 return encoderFallback
;
883 throw new InvalidOperationException(Environment
.GetResourceString("InvalidOperation_ReadOnly"));
886 throw new ArgumentNullException("value");
887 Contract
.EndContractBlock();
889 encoderFallback
= value;
894 [System
.Runtime
.InteropServices
.ComVisible(false)]
895 public DecoderFallback DecoderFallback
899 return decoderFallback
;
905 throw new InvalidOperationException(Environment
.GetResourceString("InvalidOperation_ReadOnly"));
908 throw new ArgumentNullException("value");
909 Contract
.EndContractBlock();
911 decoderFallback
= value;
916 [System
.Runtime
.InteropServices
.ComVisible(false)]
917 public virtual Object
Clone()
919 Encoding newEncoding
= (Encoding
)this.MemberwiseClone();
921 // New one should be readable
922 newEncoding
.m_isReadOnly
= false;
927 [System
.Runtime
.InteropServices
.ComVisible(false)]
928 public bool IsReadOnly
932 return (m_isReadOnly
);
938 // Returns an encoding for the ASCII character set. The returned encoding
939 // will be an instance of the ASCIIEncoding class.
942 public static Encoding ASCII
946 if (asciiEncoding
== null) asciiEncoding
= new ASCIIEncoding();
947 return asciiEncoding
;
953 // Returns an encoding for the Latin1 character set. The returned encoding
954 // will be an instance of the Latin1Encoding class.
956 // This is for our optimizations
957 private static Encoding Latin1
961 if (latin1Encoding
== null) latin1Encoding
= new Latin1Encoding();
962 return latin1Encoding
;
967 // Returns the number of bytes required to encode the given character
971 public virtual int GetByteCount(char[] chars
)
975 throw new ArgumentNullException("chars",
976 Environment
.GetResourceString("ArgumentNull_Array"));
978 Contract
.EndContractBlock();
980 return GetByteCount(chars
, 0, chars
.Length
);
984 public virtual int GetByteCount(String s
)
987 throw new ArgumentNullException("s");
988 Contract
.EndContractBlock();
990 char[] chars
= s
.ToCharArray();
991 return GetByteCount(chars
, 0, chars
.Length
);
995 // Returns the number of bytes required to encode a range of characters in
996 // a character array.
999 public abstract int GetByteCount(char[] chars
, int index
, int count
);
1002 public int GetByteCount(string str
, int index
, int count
) => GetByteCount(str
.ToCharArray(), index
, count
);
1005 // We expect this to be the workhorse for NLS encodings
1006 // unfortunately for existing overrides, it has to call the [] version,
1007 // which is really slow, so this method should be avoided if you're calling
1008 // a 3rd party encoding.
1010 [System
.Security
.SecurityCritical
] // auto-generated
1011 [CLSCompliant(false)]
1012 [System
.Runtime
.InteropServices
.ComVisible(false)]
1013 public virtual unsafe int GetByteCount(char* chars
, int count
)
1015 // Validate input parameters
1017 throw new ArgumentNullException("chars",
1018 Environment
.GetResourceString("ArgumentNull_Array"));
1021 throw new ArgumentOutOfRangeException("count",
1022 Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1023 Contract
.EndContractBlock();
1025 char[] arrChar
= new char[count
];
1028 for (index
= 0; index
< count
; index
++)
1029 arrChar
[index
] = chars
[index
];
1031 return GetByteCount(arrChar
, 0, count
);
1034 // For NLS Encodings, workhorse takes an encoder (may be null)
1035 // Always validate parameters before calling internal version, which will only assert.
1036 [System
.Security
.SecurityCritical
] // auto-generated
1037 internal virtual unsafe int GetByteCount(char* chars
, int count
, EncoderNLS encoder
)
1039 Contract
.Requires(chars
!= null);
1040 Contract
.Requires(count
>= 0);
1042 return GetByteCount(chars
, count
);
1045 // Returns a byte array containing the encoded representation of the given
1049 public virtual byte[] GetBytes(char[] chars
)
1053 throw new ArgumentNullException("chars",
1054 Environment
.GetResourceString("ArgumentNull_Array"));
1056 Contract
.EndContractBlock();
1057 return GetBytes(chars
, 0, chars
.Length
);
1060 // Returns a byte array containing the encoded representation of a range
1061 // of characters in a character array.
1064 public virtual byte[] GetBytes(char[] chars
, int index
, int count
)
1066 byte[] result
= new byte[GetByteCount(chars
, index
, count
)];
1067 GetBytes(chars
, index
, count
, result
, 0);
1071 // Encodes a range of characters in a character array into a range of bytes
1072 // in a byte array. An exception occurs if the byte array is not large
1073 // enough to hold the complete encoding of the characters. The
1074 // GetByteCount method can be used to determine the exact number of
1075 // bytes that will be produced for a given range of characters.
1076 // Alternatively, the GetMaxByteCount method can be used to
1077 // determine the maximum number of bytes that will be produced for a given
1078 // number of characters, regardless of the actual character values.
1080 public abstract int GetBytes(char[] chars
, int charIndex
, int charCount
,
1081 byte[] bytes
, int byteIndex
);
1083 // Returns a byte array containing the encoded representation of the given
1087 public virtual byte[] GetBytes(String s
)
1090 throw new ArgumentNullException("s",
1091 Environment
.GetResourceString("ArgumentNull_String"));
1092 Contract
.EndContractBlock();
1094 int byteCount
= GetByteCount(s
);
1095 byte[] bytes
= new byte[byteCount
];
1096 int bytesReceived
= GetBytes(s
, 0, s
.Length
, bytes
, 0);
1097 Contract
.Assert(byteCount
== bytesReceived
);
1101 public virtual int GetBytes(String s
, int charIndex
, int charCount
,
1102 byte[] bytes
, int byteIndex
)
1105 throw new ArgumentNullException("s");
1106 Contract
.EndContractBlock();
1107 return GetBytes(s
.ToCharArray(), charIndex
, charCount
, bytes
, byteIndex
);
1110 // This is our internal workhorse
1111 // Always validate parameters before calling internal version, which will only assert.
1112 [System
.Security
.SecurityCritical
] // auto-generated
1113 internal virtual unsafe int GetBytes(char* chars
, int charCount
,
1114 byte* bytes
, int byteCount
, EncoderNLS encoder
)
1116 return GetBytes(chars
, charCount
, bytes
, byteCount
);
1119 // We expect this to be the workhorse for NLS Encodings, but for existing
1120 // ones we need a working (if slow) default implimentation)
1122 // WARNING WARNING WARNING
1124 // WARNING: If this breaks it could be a security threat. Obviously we
1125 // call this internally, so you need to make sure that your pointers, counts
1126 // and indexes are correct when you call this method.
1128 // In addition, we have internal code, which will be marked as "safe" calling
1129 // this code. However this code is dependent upon the implimentation of an
1130 // external GetBytes() method, which could be overridden by a third party and
1131 // the results of which cannot be guaranteed. We use that result to copy
1132 // the byte[] to our byte* output buffer. If the result count was wrong, we
1133 // could easily overflow our output buffer. Therefore we do an extra test
1134 // when we copy the buffer so that we don't overflow byteCount either.
1136 [System
.Security
.SecurityCritical
] // auto-generated
1137 [CLSCompliant(false)]
1138 [System
.Runtime
.InteropServices
.ComVisible(false)]
1139 public virtual unsafe int GetBytes(char* chars
, int charCount
,
1140 byte* bytes
, int byteCount
)
1142 // Validate input parameters
1143 if (bytes
== null || chars
== null)
1144 throw new ArgumentNullException(bytes
== null ? "bytes" : "chars",
1145 Environment
.GetResourceString("ArgumentNull_Array"));
1147 if (charCount
< 0 || byteCount
< 0)
1148 throw new ArgumentOutOfRangeException((charCount
<0 ? "charCount" : "byteCount"),
1149 Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1150 Contract
.EndContractBlock();
1152 // Get the char array to convert
1153 char[] arrChar
= new char[charCount
];
1156 for (index
= 0; index
< charCount
; index
++)
1157 arrChar
[index
] = chars
[index
];
1159 // Get the byte array to fill
1160 byte[] arrByte
= new byte[byteCount
];
1163 int result
= GetBytes(arrChar
, 0, charCount
, arrByte
, 0);
1165 // The only way this could fail is a bug in GetBytes
1166 Contract
.Assert(result
<= byteCount
, "[Encoding.GetBytes]Returned more bytes than we have space for");
1168 // Copy the byte array
1169 // WARNING: We MUST make sure that we don't copy too many bytes. We can't
1170 // rely on result because it could be a 3rd party implimentation. We need
1171 // to make sure we never copy more than byteCount bytes no matter the value
1173 if (result
< byteCount
)
1176 // Copy the data, don't overrun our array!
1177 for (index
= 0; index
< byteCount
; index
++)
1178 bytes
[index
] = arrByte
[index
];
1183 // Returns the number of characters produced by decoding the given byte
1187 public virtual int GetCharCount(byte[] bytes
)
1191 throw new ArgumentNullException("bytes",
1192 Environment
.GetResourceString("ArgumentNull_Array"));
1194 Contract
.EndContractBlock();
1195 return GetCharCount(bytes
, 0, bytes
.Length
);
1198 // Returns the number of characters produced by decoding a range of bytes
1202 public abstract int GetCharCount(byte[] bytes
, int index
, int count
);
1204 // We expect this to be the workhorse for NLS Encodings, but for existing
1205 // ones we need a working (if slow) default implimentation)
1207 [System
.Security
.SecurityCritical
] // auto-generated
1208 [CLSCompliant(false)]
1209 [System
.Runtime
.InteropServices
.ComVisible(false)]
1210 public virtual unsafe int GetCharCount(byte* bytes
, int count
)
1212 // Validate input parameters
1214 throw new ArgumentNullException("bytes",
1215 Environment
.GetResourceString("ArgumentNull_Array"));
1218 throw new ArgumentOutOfRangeException("count",
1219 Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1220 Contract
.EndContractBlock();
1222 byte[] arrbyte
= new byte[count
];
1225 for (index
= 0; index
< count
; index
++)
1226 arrbyte
[index
] = bytes
[index
];
1228 return GetCharCount(arrbyte
, 0, count
);
1231 // This is our internal workhorse
1232 // Always validate parameters before calling internal version, which will only assert.
1233 [System
.Security
.SecurityCritical
] // auto-generated
1234 internal virtual unsafe int GetCharCount(byte* bytes
, int count
, DecoderNLS decoder
)
1236 return GetCharCount(bytes
, count
);
1239 // Returns a character array containing the decoded representation of a
1240 // given byte array.
1243 public virtual char[] GetChars(byte[] bytes
)
1247 throw new ArgumentNullException("bytes",
1248 Environment
.GetResourceString("ArgumentNull_Array"));
1250 Contract
.EndContractBlock();
1251 return GetChars(bytes
, 0, bytes
.Length
);
1254 // Returns a character array containing the decoded representation of a
1255 // range of bytes in a byte array.
1258 public virtual char[] GetChars(byte[] bytes
, int index
, int count
)
1260 char[] result
= new char[GetCharCount(bytes
, index
, count
)];
1261 GetChars(bytes
, index
, count
, result
, 0);
1265 // Decodes a range of bytes in a byte array into a range of characters in a
1266 // character array. An exception occurs if the character array is not large
1267 // enough to hold the complete decoding of the bytes. The
1268 // GetCharCount method can be used to determine the exact number of
1269 // characters that will be produced for a given range of bytes.
1270 // Alternatively, the GetMaxCharCount method can be used to
1271 // determine the maximum number of characterss that will be produced for a
1272 // given number of bytes, regardless of the actual byte values.
1275 public abstract int GetChars(byte[] bytes
, int byteIndex
, int byteCount
,
1276 char[] chars
, int charIndex
);
1279 // We expect this to be the workhorse for NLS Encodings, but for existing
1280 // ones we need a working (if slow) default implimentation)
1282 // WARNING WARNING WARNING
1284 // WARNING: If this breaks it could be a security threat. Obviously we
1285 // call this internally, so you need to make sure that your pointers, counts
1286 // and indexes are correct when you call this method.
1288 // In addition, we have internal code, which will be marked as "safe" calling
1289 // this code. However this code is dependent upon the implimentation of an
1290 // external GetChars() method, which could be overridden by a third party and
1291 // the results of which cannot be guaranteed. We use that result to copy
1292 // the char[] to our char* output buffer. If the result count was wrong, we
1293 // could easily overflow our output buffer. Therefore we do an extra test
1294 // when we copy the buffer so that we don't overflow charCount either.
1296 [System
.Security
.SecurityCritical
] // auto-generated
1297 [CLSCompliant(false)]
1298 [System
.Runtime
.InteropServices
.ComVisible(false)]
1299 public virtual unsafe int GetChars(byte* bytes
, int byteCount
,
1300 char* chars
, int charCount
)
1302 // Validate input parameters
1303 if (chars
== null || bytes
== null)
1304 throw new ArgumentNullException(chars
== null ? "chars" : "bytes",
1305 Environment
.GetResourceString("ArgumentNull_Array"));
1307 if (byteCount
< 0 || charCount
< 0)
1308 throw new ArgumentOutOfRangeException((byteCount
<0 ? "byteCount" : "charCount"),
1309 Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1310 Contract
.EndContractBlock();
1312 // Get the byte array to convert
1313 byte[] arrByte
= new byte[byteCount
];
1316 for (index
= 0; index
< byteCount
; index
++)
1317 arrByte
[index
] = bytes
[index
];
1319 // Get the char array to fill
1320 char[] arrChar
= new char[charCount
];
1323 int result
= GetChars(arrByte
, 0, byteCount
, arrChar
, 0);
1325 // The only way this could fail is a bug in GetChars
1326 Contract
.Assert(result
<= charCount
, "[Encoding.GetChars]Returned more chars than we have space for");
1328 // Copy the char array
1329 // WARNING: We MUST make sure that we don't copy too many chars. We can't
1330 // rely on result because it could be a 3rd party implimentation. We need
1331 // to make sure we never copy more than charCount chars no matter the value
1333 if (result
< charCount
)
1336 // Copy the data, don't overrun our array!
1337 for (index
= 0; index
< charCount
; index
++)
1338 chars
[index
] = arrChar
[index
];
1344 // This is our internal workhorse
1345 // Always validate parameters before calling internal version, which will only assert.
1346 [System
.Security
.SecurityCritical
] // auto-generated
1347 internal virtual unsafe int GetChars(byte* bytes
, int byteCount
,
1348 char* chars
, int charCount
, DecoderNLS decoder
)
1350 return GetChars(bytes
, byteCount
, chars
, charCount
);
1354 [System
.Security
.SecurityCritical
] // auto-generated
1355 [CLSCompliant(false)]
1356 [System
.Runtime
.InteropServices
.ComVisible(false)]
1357 public unsafe string GetString(byte* bytes
, int byteCount
)
1360 throw new ArgumentNullException("bytes", Environment
.GetResourceString("ArgumentNull_Array"));
1363 throw new ArgumentOutOfRangeException("byteCount", Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1364 Contract
.EndContractBlock();
1366 return String
.CreateStringFromEncoding(bytes
, byteCount
, this);
1370 public virtual unsafe int GetChars(ReadOnlySpan
<byte> bytes
, Span
<char> chars
)
1372 fixed (byte* bytesPtr
= &System
.Runtime
.InteropServices
.MemoryMarshal
.GetNonNullPinnableReference(bytes
))
1373 fixed (char* charsPtr
= &System
.Runtime
.InteropServices
.MemoryMarshal
.GetNonNullPinnableReference(chars
))
1375 return GetChars(bytesPtr
, bytes
.Length
, charsPtr
, chars
.Length
);
1379 public unsafe string GetString(ReadOnlySpan
<byte> bytes
)
1381 fixed (byte* bytesPtr
= &System
.Runtime
.InteropServices
.MemoryMarshal
.GetNonNullPinnableReference(bytes
))
1383 return GetString(bytesPtr
, bytes
.Length
);
1388 // Returns the code page identifier of this encoding. The returned value is
1389 // an integer between 0 and 65535 if the encoding has a code page
1390 // identifier, or -1 if the encoding does not represent a code page.
1393 public virtual int CodePage
1401 // IsAlwaysNormalized
1402 // Returns true if the encoding is always normalized for the specified encoding form
1404 [System
.Runtime
.InteropServices
.ComVisible(false)]
1405 public bool IsAlwaysNormalized()
1407 #if !FEATURE_NORM_IDNA_ONLY
1408 return this.IsAlwaysNormalized(NormalizationForm
.FormC
);
1410 return this.IsAlwaysNormalized((NormalizationForm
)ExtendedNormalizationForms
.FormIdna
);
1415 [System
.Runtime
.InteropServices
.ComVisible(false)]
1416 public virtual bool IsAlwaysNormalized(NormalizationForm form
)
1418 // Assume false unless the encoding knows otherwise
1422 // Returns a Decoder object for this encoding. The returned object
1423 // can be used to decode a sequence of bytes into a sequence of characters.
1424 // Contrary to the GetChars family of methods, a Decoder can
1425 // convert partial sequences of bytes into partial sequences of characters
1426 // by maintaining the appropriate state between the conversions.
1428 // This default implementation returns a Decoder that simply
1429 // forwards calls to the GetCharCount and GetChars methods to
1430 // the corresponding methods of this encoding. Encodings that require state
1431 // to be maintained between successive conversions should override this
1432 // method and return an instance of an appropriate Decoder
1436 public virtual Decoder
GetDecoder()
1438 return new DefaultDecoder(this);
1441 [System
.Security
.SecurityCritical
] // auto-generated
1442 private static Encoding
CreateDefaultEncoding()
1446 #if FEATURE_CODEPAGES_FILE
1447 int codePage
= Win32Native
.GetACP();
1449 // For US English, we can save some startup working set by not calling
1450 // GetEncoding(int codePage) since JITting GetEncoding will force us to load
1451 // all the Encoding classes for ASCII, UTF7 & UTF8, & UnicodeEncoding.
1453 if (codePage
== 1252)
1454 enc
= new SBCSCodePageEncoding(codePage
);
1456 enc
= GetEncoding(codePage
);
1457 #else // FEATURE_CODEPAGES_FILE
1459 #if MONO_HYBRID_ENCODING_SUPPORT
1460 enc
= EncodingHelper
.GetDefaultEncoding ();
1461 enc
.m_isReadOnly
= true;
1463 // For silverlight we use UTF8 since ANSI isn't available
1467 #endif //FEATURE_CODEPAGES_FILE
1472 #if MONO_HYBRID_ENCODING_SUPPORT
1473 internal void setReadOnly (bool value = true)
1475 m_isReadOnly
= value;
1479 // Returns an encoding for the system's current ANSI code page.
1482 public static Encoding Default
{
1483 [System
.Security
.SecuritySafeCritical
] // auto-generated
1485 if (defaultEncoding
== null) {
1486 defaultEncoding
= CreateDefaultEncoding();
1488 return defaultEncoding
;
1492 // Returns an Encoder object for this encoding. The returned object
1493 // can be used to encode a sequence of characters into a sequence of bytes.
1494 // Contrary to the GetBytes family of methods, an Encoder can
1495 // convert partial sequences of characters into partial sequences of bytes
1496 // by maintaining the appropriate state between the conversions.
1498 // This default implementation returns an Encoder that simply
1499 // forwards calls to the GetByteCount and GetBytes methods to
1500 // the corresponding methods of this encoding. Encodings that require state
1501 // to be maintained between successive conversions should override this
1502 // method and return an instance of an appropriate Encoder
1506 public virtual Encoder
GetEncoder()
1508 return new DefaultEncoder(this);
1511 // Returns the maximum number of bytes required to encode a given number of
1512 // characters. This method can be used to determine an appropriate buffer
1513 // size for byte arrays passed to the GetBytes method of this
1514 // encoding or the GetBytes method of an Encoder for this
1515 // encoding. All encodings must guarantee that no buffer overflow
1516 // exceptions will occur if buffers are sized according to the results of
1519 // WARNING: If you're using something besides the default replacement encoder fallback,
1520 // then you could have more bytes than this returned from an actual call to GetBytes().
1523 public abstract int GetMaxByteCount(int charCount
);
1525 // Returns the maximum number of characters produced by decoding a given
1526 // number of bytes. This method can be used to determine an appropriate
1527 // buffer size for character arrays passed to the GetChars method of
1528 // this encoding or the GetChars method of a Decoder for this
1529 // encoding. All encodings must guarantee that no buffer overflow
1530 // exceptions will occur if buffers are sized according to the results of
1534 public abstract int GetMaxCharCount(int byteCount
);
1536 // Returns a string containing the decoded representation of a given byte
1540 public virtual String
GetString(byte[] bytes
)
1543 throw new ArgumentNullException("bytes",
1544 Environment
.GetResourceString("ArgumentNull_Array"));
1545 Contract
.EndContractBlock();
1547 return GetString(bytes
, 0, bytes
.Length
);
1550 // Returns a string containing the decoded representation of a range of
1551 // bytes in a byte array.
1553 // Internally we override this for performance
1556 public virtual String
GetString(byte[] bytes
, int index
, int count
)
1558 return new String(GetChars(bytes
, index
, count
));
1561 // Returns an encoding for Unicode format. The returned encoding will be
1562 // an instance of the UnicodeEncoding class.
1564 // It will use little endian byte order, but will detect
1565 // input in big endian if it finds a byte order mark per Unicode 2.0.
1568 public static Encoding Unicode
{
1570 if (unicodeEncoding
== null) unicodeEncoding
= new UnicodeEncoding(false, true);
1571 return unicodeEncoding
;
1575 // Returns an encoding for Unicode format. The returned encoding will be
1576 // an instance of the UnicodeEncoding class.
1578 // It will use big endian byte order, but will detect
1579 // input in little endian if it finds a byte order mark per Unicode 2.0.
1582 public static Encoding BigEndianUnicode
{
1584 if (bigEndianUnicode
== null) bigEndianUnicode
= new UnicodeEncoding(true, true);
1585 return bigEndianUnicode
;
1590 // Returns an encoding for the UTF-7 format. The returned encoding will be
1591 // an instance of the UTF7Encoding class.
1593 public static Encoding UTF7
{
1595 if (utf7Encoding
== null) utf7Encoding
= new UTF7Encoding();
1596 return utf7Encoding
;
1600 // Returns an encoding for the UTF-8 format. The returned encoding will be
1601 // an instance of the UTF8Encoding class.
1604 public static Encoding UTF8
{
1606 if (utf8Encoding
== null) utf8Encoding
= new UTF8Encoding(true);
1607 return utf8Encoding
;
1611 // Returns an encoding for the UTF-32 format. The returned encoding will be
1612 // an instance of the UTF32Encoding class.
1615 public static Encoding UTF32
{
1617 if (utf32Encoding
== null) utf32Encoding
= new UTF32Encoding(false, true);
1618 return utf32Encoding
;
1624 public override bool Equals(Object
value) {
1625 Encoding that
= value as Encoding
;
1627 return (m_codePage
== that
.m_codePage
) &&
1628 (EncoderFallback
.Equals(that
.EncoderFallback
)) &&
1629 (DecoderFallback
.Equals(that
.DecoderFallback
));
1634 public override int GetHashCode() {
1635 return m_codePage
+ this.EncoderFallback
.GetHashCode() + this.DecoderFallback
.GetHashCode();
1638 internal virtual char[] GetBestFitUnicodeToBytesData()
1640 // Normally we don't have any best fit data.
1641 return EmptyArray
<Char
>.Value
;
1644 internal virtual char[] GetBestFitBytesToUnicodeData()
1646 // Normally we don't have any best fit data.
1647 return EmptyArray
<Char
>.Value
;
1650 internal void ThrowBytesOverflow()
1652 // Special message to include fallback type in case fallback's GetMaxCharCount is broken
1653 // This happens if user has implimented an encoder fallback with a broken GetMaxCharCount
1654 throw new ArgumentException(
1655 Environment
.GetResourceString("Argument_EncodingConversionOverflowBytes",
1656 EncodingName
, EncoderFallback
.GetType()), "bytes");
1659 [System
.Security
.SecurityCritical
] // auto-generated
1660 internal void ThrowBytesOverflow(EncoderNLS encoder
, bool nothingEncoded
)
1662 if (encoder
== null || encoder
._throwOnOverflow
|| nothingEncoded
)
1664 if (encoder
!= null && encoder
.InternalHasFallbackBuffer
)
1665 encoder
.FallbackBuffer
.InternalReset();
1666 // Special message to include fallback type in case fallback's GetMaxCharCount is broken
1667 // This happens if user has implimented an encoder fallback with a broken GetMaxCharCount
1668 ThrowBytesOverflow();
1671 // If we didn't throw, we are in convert and have to remember our flushing
1672 encoder
.ClearMustFlush();
1675 internal void ThrowCharsOverflow()
1677 // Special message to include fallback type in case fallback's GetMaxCharCount is broken
1678 // This happens if user has implimented a decoder fallback with a broken GetMaxCharCount
1679 throw new ArgumentException(
1680 Environment
.GetResourceString("Argument_EncodingConversionOverflowChars",
1681 EncodingName
, DecoderFallback
.GetType()), "chars");
1684 [System
.Security
.SecurityCritical
] // auto-generated
1685 internal void ThrowCharsOverflow(DecoderNLS decoder
, bool nothingDecoded
)
1687 if (decoder
== null || decoder
._throwOnOverflow
|| nothingDecoded
)
1689 if (decoder
!= null && decoder
.InternalHasFallbackBuffer
)
1690 decoder
.FallbackBuffer
.InternalReset();
1692 // Special message to include fallback type in case fallback's GetMaxCharCount is broken
1693 // This happens if user has implimented a decoder fallback with a broken GetMaxCharCount
1694 ThrowCharsOverflow();
1697 // If we didn't throw, we are in convert and have to remember our flushing
1698 decoder
.ClearMustFlush();
1702 public virtual unsafe int GetCharCount(ReadOnlySpan
<byte> bytes
)
1704 fixed (byte* bytesPtr
= &MemoryMarshal
.GetNonNullPinnableReference(bytes
))
1706 return GetCharCount(bytesPtr
, bytes
.Length
);
1710 public virtual unsafe int GetByteCount(ReadOnlySpan
<char> chars
)
1712 fixed (char* charsPtr
= &MemoryMarshal
.GetNonNullPinnableReference(chars
))
1714 return GetByteCount(charsPtr
, chars
.Length
);
1718 public virtual unsafe int GetBytes(ReadOnlySpan
<char> chars
, Span
<byte> bytes
)
1720 fixed (char* charsPtr
= &MemoryMarshal
.GetNonNullPinnableReference(chars
))
1721 fixed (byte* bytesPtr
= &MemoryMarshal
.GetNonNullPinnableReference(bytes
))
1723 return GetBytes(charsPtr
, chars
.Length
, bytesPtr
, bytes
.Length
);
1727 public byte[] GetBytes(string s
, int index
, int count
)
1730 throw new ArgumentNullException(nameof(s
),
1731 SR
.ArgumentNull_String
);
1733 throw new ArgumentOutOfRangeException(nameof(index
),
1734 SR
.ArgumentOutOfRange_NeedNonNegNum
);
1736 throw new ArgumentOutOfRangeException(nameof(count
),
1737 SR
.ArgumentOutOfRange_NeedNonNegNum
);
1738 if (index
> s
.Length
- count
)
1739 throw new ArgumentOutOfRangeException(nameof(index
),
1740 SR
.ArgumentOutOfRange_IndexCount
);
1744 fixed (char* pChar
= s
)
1746 int byteCount
= GetByteCount(pChar
+ index
, count
);
1748 return Array
.Empty
<byte>();
1750 byte[] bytes
= new byte[byteCount
];
1751 fixed (byte* pBytes
= &bytes
[0])
1753 int bytesReceived
= GetBytes(pChar
+ index
, count
, pBytes
, byteCount
);
1754 Debug
.Assert(byteCount
== bytesReceived
);
1763 internal class DefaultEncoder
: Encoder
, ISerializable
, IObjectReference
1765 private Encoding m_encoding
;
1766 [NonSerialized
] private bool m_hasInitializedEncoding
;
1768 [NonSerialized
] internal char charLeftOver
;
1770 public DefaultEncoder(Encoding encoding
)
1772 m_encoding
= encoding
;
1773 m_hasInitializedEncoding
= true;
1776 // Constructor called by serialization, have to handle deserializing from Everett
1777 internal DefaultEncoder(SerializationInfo info
, StreamingContext context
)
1779 if (info
==null) throw new ArgumentNullException("info");
1780 Contract
.EndContractBlock();
1782 // All we have is our encoding
1783 this.m_encoding
= (Encoding
)info
.GetValue("encoding", typeof(Encoding
));
1787 this._fallback
= (EncoderFallback
) info
.GetValue("_fallback", typeof(EncoderFallback
));
1788 this.charLeftOver
= (Char
) info
.GetValue("charLeftOver", typeof(Char
));
1790 catch (SerializationException
)
1795 // Just get it from GetEncoding
1796 [System
.Security
.SecurityCritical
] // auto-generated
1797 public Object
GetRealObject(StreamingContext context
)
1799 // upon deserialization since the DefaultEncoder implement IObjectReference the
1800 // serialization code tries to do the fixup. The fixup returns another
1801 // IObjectReference (the DefaultEncoder) class and hence so on and on.
1802 // Finally the deserialization logics fails after following maximum references
1803 // unless we short circuit with the following
1804 if (m_hasInitializedEncoding
)
1809 Encoder encoder
= m_encoding
.GetEncoder();
1810 if (_fallback
!= null)
1811 encoder
._fallback
= _fallback
;
1812 if (charLeftOver
!= (char) 0)
1814 EncoderNLS encoderNls
= encoder
as EncoderNLS
;
1815 if (encoderNls
!= null)
1816 encoderNls
._charLeftOver
= charLeftOver
;
1821 #if FEATURE_SERIALIZATION
1822 // ISerializable implementation, get data for this object
1823 [System
.Security
.SecurityCritical
] // auto-generated_required
1824 void ISerializable
.GetObjectData(SerializationInfo info
, StreamingContext context
)
1827 if (info
==null) throw new ArgumentNullException("info");
1828 Contract
.EndContractBlock();
1830 // All we have is our encoding
1831 info
.AddValue("encoding", this.m_encoding
);
1835 // Returns the number of bytes the next call to GetBytes will
1836 // produce if presented with the given range of characters and the given
1837 // value of the flush parameter. The returned value takes into
1838 // account the state in which the encoder was left following the last call
1839 // to GetBytes. The state of the encoder is not affected by a call
1843 public override int GetByteCount(char[] chars
, int index
, int count
, bool flush
)
1845 return m_encoding
.GetByteCount(chars
, index
, count
);
1848 [System
.Security
.SecurityCritical
] // auto-generated
1849 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
1850 public unsafe override int GetByteCount(char* chars
, int count
, bool flush
)
1852 return m_encoding
.GetByteCount(chars
, count
);
1855 // Encodes a range of characters in a character array into a range of bytes
1856 // in a byte array. The method encodes charCount characters from
1857 // chars starting at index charIndex, storing the resulting
1858 // bytes in bytes starting at index byteIndex. The encoding
1859 // takes into account the state in which the encoder was left following the
1860 // last call to this method. The flush parameter indicates whether
1861 // the encoder should flush any shift-states and partial characters at the
1862 // end of the conversion. To ensure correct termination of a sequence of
1863 // blocks of encoded bytes, the last call to GetBytes should specify
1864 // a value of true for the flush parameter.
1866 // An exception occurs if the byte array is not large enough to hold the
1867 // complete encoding of the characters. The GetByteCount method can
1868 // be used to determine the exact number of bytes that will be produced for
1869 // a given range of characters. Alternatively, the GetMaxByteCount
1870 // method of the Encoding that produced this encoder can be used to
1871 // determine the maximum number of bytes that will be produced for a given
1872 // number of characters, regardless of the actual character values.
1875 public override int GetBytes(char[] chars
, int charIndex
, int charCount
,
1876 byte[] bytes
, int byteIndex
, bool flush
)
1878 return m_encoding
.GetBytes(chars
, charIndex
, charCount
, bytes
, byteIndex
);
1881 [System
.Security
.SecurityCritical
] // auto-generated
1882 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
1883 public unsafe override int GetBytes(char* chars
, int charCount
,
1884 byte* bytes
, int byteCount
, bool flush
)
1886 return m_encoding
.GetBytes(chars
, charCount
, bytes
, byteCount
);
1891 internal class DefaultDecoder
: Decoder
, ISerializable
, IObjectReference
1893 private Encoding m_encoding
;
1895 private bool m_hasInitializedEncoding
;
1897 public DefaultDecoder(Encoding encoding
)
1899 m_encoding
= encoding
;
1900 m_hasInitializedEncoding
= true;
1903 // Constructor called by serialization, have to handle deserializing from Everett
1904 internal DefaultDecoder(SerializationInfo info
, StreamingContext context
)
1907 if (info
==null) throw new ArgumentNullException("info");
1908 Contract
.EndContractBlock();
1910 // All we have is our encoding
1911 this.m_encoding
= (Encoding
)info
.GetValue("encoding", typeof(Encoding
));
1915 this._fallback
= (DecoderFallback
) info
.GetValue("_fallback", typeof(DecoderFallback
));
1917 catch (SerializationException
)
1923 // Just get it from GetEncoding
1924 [System
.Security
.SecurityCritical
] // auto-generated
1925 public Object
GetRealObject(StreamingContext context
)
1927 // upon deserialization since the DefaultEncoder implement IObjectReference the
1928 // serialization code tries to do the fixup. The fixup returns another
1929 // IObjectReference (the DefaultEncoder) class and hence so on and on.
1930 // Finally the deserialization logics fails after following maximum references
1931 // unless we short circuit with the following
1932 if (m_hasInitializedEncoding
)
1937 Decoder decoder
= m_encoding
.GetDecoder();
1938 if (_fallback
!= null)
1939 decoder
._fallback
= _fallback
;
1944 #if FEATURE_SERIALIZATION
1945 // ISerializable implementation, get data for this object
1946 [System
.Security
.SecurityCritical
] // auto-generated_required
1947 void ISerializable
.GetObjectData(SerializationInfo info
, StreamingContext context
)
1950 if (info
==null) throw new ArgumentNullException("info");
1951 Contract
.EndContractBlock();
1953 // All we have is our encoding
1954 info
.AddValue("encoding", this.m_encoding
);
1958 // Returns the number of characters the next call to GetChars will
1959 // produce if presented with the given range of bytes. The returned value
1960 // takes into account the state in which the decoder was left following the
1961 // last call to GetChars. The state of the decoder is not affected
1962 // by a call to this method.
1965 public override int GetCharCount(byte[] bytes
, int index
, int count
)
1967 return GetCharCount(bytes
, index
, count
, false);
1970 public override int GetCharCount(byte[] bytes
, int index
, int count
, bool flush
)
1972 return m_encoding
.GetCharCount(bytes
, index
, count
);
1975 [System
.Security
.SecurityCritical
] // auto-generated
1976 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
1977 public unsafe override int GetCharCount(byte* bytes
, int count
, bool flush
)
1979 // By default just call the encoding version, no flush by default
1980 return m_encoding
.GetCharCount(bytes
, count
);
1983 // Decodes a range of bytes in a byte array into a range of characters
1984 // in a character array. The method decodes byteCount bytes from
1985 // bytes starting at index byteIndex, storing the resulting
1986 // characters in chars starting at index charIndex. The
1987 // decoding takes into account the state in which the decoder was left
1988 // following the last call to this method.
1990 // An exception occurs if the character array is not large enough to
1991 // hold the complete decoding of the bytes. The GetCharCount method
1992 // can be used to determine the exact number of characters that will be
1993 // produced for a given range of bytes. Alternatively, the
1994 // GetMaxCharCount method of the Encoding that produced this
1995 // decoder can be used to determine the maximum number of characters that
1996 // will be produced for a given number of bytes, regardless of the actual
2000 public override int GetChars(byte[] bytes
, int byteIndex
, int byteCount
,
2001 char[] chars
, int charIndex
)
2003 return GetChars(bytes
, byteIndex
, byteCount
, chars
, charIndex
, false);
2006 public override int GetChars(byte[] bytes
, int byteIndex
, int byteCount
,
2007 char[] chars
, int charIndex
, bool flush
)
2009 return m_encoding
.GetChars(bytes
, byteIndex
, byteCount
, chars
, charIndex
);
2012 [System
.Security
.SecurityCritical
] // auto-generated
2013 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
2014 public unsafe override int GetChars(byte* bytes
, int byteCount
,
2015 char* chars
, int charCount
, bool flush
)
2017 // By default just call the encoding's version
2018 return m_encoding
.GetChars(bytes
, byteCount
, chars
, charCount
);
2022 internal class EncodingCharBuffer
2027 unsafe char* charStart
;
2029 unsafe char* charEnd
;
2030 int charCountResult
= 0;
2034 unsafe byte* byteStart
;
2036 unsafe byte* byteEnd
;
2039 DecoderFallbackBuffer fallbackBuffer
;
2041 [System
.Security
.SecurityCritical
] // auto-generated
2042 internal unsafe EncodingCharBuffer(Encoding enc
, DecoderNLS decoder
, char* charStart
, int charCount
,
2043 byte* byteStart
, int byteCount
)
2046 this.decoder
= decoder
;
2048 this.chars
= charStart
;
2049 this.charStart
= charStart
;
2050 this.charEnd
= charStart
+ charCount
;
2052 this.byteStart
= byteStart
;
2053 this.bytes
= byteStart
;
2054 this.byteEnd
= byteStart
+ byteCount
;
2056 if (this.decoder
== null)
2057 this.fallbackBuffer
= enc
.DecoderFallback
.CreateFallbackBuffer();
2059 this.fallbackBuffer
= this.decoder
.FallbackBuffer
;
2061 // If we're getting chars or getting char count we don't expect to have
2062 // to remember fallbacks between calls (so it should be empty)
2063 Contract
.Assert(fallbackBuffer
.Remaining
== 0,
2064 "[Encoding.EncodingCharBuffer.EncodingCharBuffer]Expected empty fallback buffer for getchars/charcount");
2065 fallbackBuffer
.InternalInitialize(bytes
, charEnd
);
2068 [System
.Security
.SecurityCritical
] // auto-generated
2069 internal unsafe bool AddChar(char ch
, int numBytes
)
2073 if (chars
>= charEnd
)
2076 bytes
-=numBytes
; // Didn't encode these bytes
2077 enc
.ThrowCharsOverflow(decoder
, bytes
<= byteStart
); // Throw?
2078 return false; // No throw, but no store either
2087 [System
.Security
.SecurityCritical
] // auto-generated
2088 internal unsafe bool AddChar(char ch
)
2090 return AddChar(ch
,1);
2094 [System
.Security
.SecurityCritical
] // auto-generated
2095 internal unsafe bool AddChar(char ch1
, char ch2
, int numBytes
)
2097 // Need room for 2 chars
2098 if (chars
>= charEnd
- 1)
2101 bytes
-=numBytes
; // Didn't encode these bytes
2102 enc
.ThrowCharsOverflow(decoder
, bytes
<= byteStart
); // Throw?
2103 return false; // No throw, but no store either
2105 return AddChar(ch1
, numBytes
) && AddChar(ch2
, numBytes
);
2108 [System
.Security
.SecurityCritical
] // auto-generated
2109 internal unsafe void AdjustBytes(int count
)
2114 internal unsafe bool MoreData
2116 [System
.Security
.SecurityCritical
] // auto-generated
2119 return bytes
< byteEnd
;
2123 // Do we have count more bytes?
2124 [System
.Security
.SecurityCritical
] // auto-generated
2125 internal unsafe bool EvenMoreData(int count
)
2127 return (bytes
<= byteEnd
- count
);
2130 // GetNextByte shouldn't be called unless the caller's already checked more data or even more data,
2131 // but we'll double check just to make sure.
2132 [System
.Security
.SecurityCritical
] // auto-generated
2133 internal unsafe byte GetNextByte()
2135 Contract
.Assert(bytes
< byteEnd
, "[EncodingCharBuffer.GetNextByte]Expected more date");
2136 if (bytes
>= byteEnd
)
2141 internal unsafe int BytesUsed
2143 [System
.Security
.SecurityCritical
] // auto-generated
2146 return (int)(bytes
- byteStart
);
2150 [System
.Security
.SecurityCritical
] // auto-generated
2151 internal unsafe bool Fallback(byte fallbackByte
)
2154 byte[] byteBuffer
= new byte[] { fallbackByte }
;
2156 // Do the fallback and add the data.
2157 return Fallback(byteBuffer
);
2160 [System
.Security
.SecurityCritical
] // auto-generated
2161 internal unsafe bool Fallback(byte byte1
, byte byte2
)
2164 byte[] byteBuffer
= new byte[] { byte1, byte2 }
;
2166 // Do the fallback and add the data.
2167 return Fallback(byteBuffer
);
2170 [System
.Security
.SecurityCritical
] // auto-generated
2171 internal unsafe bool Fallback(byte byte1
, byte byte2
, byte byte3
, byte byte4
)
2174 byte[] byteBuffer
= new byte[] { byte1, byte2, byte3, byte4 }
;
2176 // Do the fallback and add the data.
2177 return Fallback(byteBuffer
);
2180 [System
.Security
.SecurityCritical
] // auto-generated
2181 internal unsafe bool Fallback(byte[] byteBuffer
)
2183 // Do the fallback and add the data.
2186 char* pTemp
= chars
;
2187 if (fallbackBuffer
.InternalFallback(byteBuffer
, bytes
, ref chars
) == false)
2190 bytes
-= byteBuffer
.Length
; // Didn't use how many ever bytes we're falling back
2191 fallbackBuffer
.InternalReset(); // We didn't use this fallback.
2192 enc
.ThrowCharsOverflow(decoder
, chars
== charStart
); // Throw?
2193 return false; // No throw, but no store either
2195 charCountResult
+= unchecked((int)(chars
- pTemp
));
2199 charCountResult
+= fallbackBuffer
.InternalFallback(byteBuffer
, bytes
);
2205 internal unsafe int Count
2209 return charCountResult
;
2214 internal class EncodingByteBuffer
2219 unsafe byte* byteStart
;
2221 unsafe byte* byteEnd
;
2225 unsafe char* charStart
;
2227 unsafe char* charEnd
;
2228 int byteCountResult
= 0;
2231 internal EncoderFallbackBuffer fallbackBuffer
;
2233 [System
.Security
.SecurityCritical
] // auto-generated
2234 internal unsafe EncodingByteBuffer(Encoding inEncoding
, EncoderNLS inEncoder
,
2235 byte* inByteStart
, int inByteCount
, char* inCharStart
, int inCharCount
)
2237 this.enc
= inEncoding
;
2238 this.encoder
= inEncoder
;
2240 this.charStart
= inCharStart
;
2241 this.chars
= inCharStart
;
2242 this.charEnd
= inCharStart
+ inCharCount
;
2244 this.bytes
= inByteStart
;
2245 this.byteStart
= inByteStart
;
2246 this.byteEnd
= inByteStart
+ inByteCount
;
2248 if (this.encoder
== null)
2249 this.fallbackBuffer
= enc
.EncoderFallback
.CreateFallbackBuffer();
2252 this.fallbackBuffer
= this.encoder
.FallbackBuffer
;
2253 // If we're not converting we must not have data in our fallback buffer
2254 if (encoder
._throwOnOverflow
&& encoder
.InternalHasFallbackBuffer
&&
2255 this.fallbackBuffer
.Remaining
> 0)
2256 throw new ArgumentException(Environment
.GetResourceString("Argument_EncoderFallbackNotEmpty",
2257 encoder
.Encoding
.EncodingName
, encoder
.Fallback
.GetType()));
2259 fallbackBuffer
.InternalInitialize(chars
, charEnd
, encoder
, bytes
!= null);
2262 [System
.Security
.SecurityCritical
] // auto-generated
2263 internal unsafe bool AddByte(byte b
, int moreBytesExpected
)
2265 Contract
.Assert(moreBytesExpected
>= 0, "[EncodingByteBuffer.AddByte]expected non-negative moreBytesExpected");
2268 if (bytes
>= byteEnd
- moreBytesExpected
)
2270 // Throw maybe. Check which buffer to back up (only matters if Converting)
2271 this.MovePrevious(true); // Throw if necessary
2272 return false; // No throw, but no store either
2281 [System
.Security
.SecurityCritical
] // auto-generated
2282 internal unsafe bool AddByte(byte b1
)
2284 return (AddByte(b1
, 0));
2287 [System
.Security
.SecurityCritical
] // auto-generated
2288 internal unsafe bool AddByte(byte b1
, byte b2
)
2290 return (AddByte(b1
, b2
, 0));
2293 [System
.Security
.SecurityCritical
] // auto-generated
2294 internal unsafe bool AddByte(byte b1
, byte b2
, int moreBytesExpected
)
2296 return (AddByte(b1
, 1 + moreBytesExpected
) && AddByte(b2
, moreBytesExpected
));
2299 [System
.Security
.SecurityCritical
] // auto-generated
2300 internal unsafe bool AddByte(byte b1
, byte b2
, byte b3
)
2302 return AddByte(b1
, b2
, b3
, (int)0);
2305 [System
.Security
.SecurityCritical
] // auto-generated
2306 internal unsafe bool AddByte(byte b1
, byte b2
, byte b3
, int moreBytesExpected
)
2308 return (AddByte(b1
, 2 + moreBytesExpected
) &&
2309 AddByte(b2
, 1 + moreBytesExpected
) &&
2310 AddByte(b3
, moreBytesExpected
));
2313 [System
.Security
.SecurityCritical
] // auto-generated
2314 internal unsafe bool AddByte(byte b1
, byte b2
, byte b3
, byte b4
)
2316 return (AddByte(b1
, 3) &&
2322 [System
.Security
.SecurityCritical
] // auto-generated
2323 internal unsafe void MovePrevious(bool bThrow
)
2325 if (fallbackBuffer
.bFallingBack
)
2326 fallbackBuffer
.MovePrevious(); // don't use last fallback
2329 Contract
.Assert(chars
> charStart
||
2330 ((bThrow
== true) && (bytes
== byteStart
)),
2331 "[EncodingByteBuffer.MovePrevious]expected previous data or throw");
2332 if (chars
> charStart
)
2333 chars
--; // don't use last char
2337 enc
.ThrowBytesOverflow(encoder
, bytes
== byteStart
); // Throw? (and reset fallback if not converting)
2340 [System
.Security
.SecurityCritical
] // auto-generated
2341 internal unsafe bool Fallback(char charFallback
)
2344 return fallbackBuffer
.InternalFallback(charFallback
, ref chars
);
2347 internal unsafe bool MoreData
2349 [System
.Security
.SecurityCritical
] // auto-generated
2352 // See if fallbackBuffer is not empty or if there's data left in chars buffer.
2353 return ((fallbackBuffer
.Remaining
> 0) || (chars
< charEnd
));
2357 [System
.Security
.SecurityCritical
] // auto-generated
2358 internal unsafe char GetNextChar()
2360 // See if there's something in our fallback buffer
2361 char cReturn
= fallbackBuffer
.InternalGetNextChar();
2363 // Nothing in the fallback buffer, return our normal data.
2366 if (chars
< charEnd
)
2367 cReturn
= *(chars
++);
2373 internal unsafe int CharsUsed
2375 [System
.Security
.SecurityCritical
] // auto-generated
2378 return (int)(chars
- charStart
);
2382 internal unsafe int Count
2386 return byteCountResult
;