Switch Hashtables to Dictionary in the encoding classes so Hashtable can be linked...
[mono-project.git] / mcs / class / referencesource / mscorlib / system / text / encoding.cs
blobefa74587c906622201da2c9d910d4b5db3d38226
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 namespace System.Text
8 using System;
9 using System.Collections.Generic;
10 using System.Runtime;
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;
17 using System.Text;
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;
24 #endif
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
33 // and 0x7F.
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)]
90 [Serializable]
91 public abstract class Encoding : ICloneable
93 private static volatile Encoding defaultEncoding;
94 private static volatile Encoding unicodeEncoding;
95 private static volatile Encoding bigEndianUnicode;
96 #if FEATURE_UTF7
97 private static volatile Encoding utf7Encoding;
98 #endif
99 private static volatile Encoding utf8Encoding;
100 #if FEATURE_UTF32
101 private static volatile Encoding utf32Encoding;
102 #endif
103 #if FEATURE_ASCII
104 private static volatile Encoding asciiEncoding;
105 #endif
106 #if FEATURE_LATIN1
107 private static volatile Encoding latin1Encoding;
108 #endif
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
155 // ISCII
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;
167 // GB18030
168 private const int GB18030 = 54936;
170 // Other
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;
189 [NonSerialized]
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
210 if (codePage < 0)
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
229 if (codePage < 0)
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;
258 m_isReadOnly = true;
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 #
270 dataItem = null;
273 [OnDeserializing]
274 private void OnDeserializing(StreamingContext ctx)
276 OnDeserializing();
280 [OnDeserialized]
281 private void OnDeserialized(StreamingContext ctx)
283 OnDeserialized();
286 [OnSerializing]
287 private void OnSerializing(StreamingContext ctx)
289 // to be consistent with SerializeEncoding
290 dataItem = null;
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)
297 // Any info?
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)
336 // Any Info?
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.
363 [Pure]
364 public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
365 byte[] bytes) {
366 if (bytes==null)
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.
378 [Pure]
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"));
385 if (bytes == null) {
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 {
397 get {
398 if (s_InternalSyncObject == null) {
399 Object o = new Object();
400 Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
402 return s_InternalSyncObject;
406 #if !FEATURE_CORECLR
407 [System.Security.SecurityCritical]
408 #endif
409 public static void RegisterProvider(EncodingProvider provider)
411 // Parameters validated inside EncodingProvider
412 EncodingProvider.AddProvider(provider);
415 [Pure]
416 #if !FEATURE_CORECLR
417 [System.Security.SecuritySafeCritical] // auto-generated
418 #endif
419 public static Encoding GetEncoding(int codepage)
421 Encoding result = EncodingProvider.GetEncodingFromProvider(codepage);
422 if (result != null)
423 return result;
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",
434 0, 65535));
437 Contract.EndContractBlock();
439 // Our Encoding
441 // See if we have a hash table with our encoding in it already.
442 if (encodings != null)
443 encodings.TryGetValue (codepage, out result);
445 if (result == null)
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))
457 return 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.
462 switch (codepage)
464 case CodePageDefault: // 0, default code page
465 result = Encoding.Default;
466 break;
467 case CodePageUnicode: // 1200, Unicode
468 result = Unicode;
469 break;
470 case CodePageBigEndian: // 1201, big endian unicode
471 result = BigEndianUnicode;
472 break;
473 #if FEATURE_CODEPAGES_FILE
474 case CodePageWindows1252: // 1252, Windows
475 result = new SBCSCodePageEncoding(codepage);
476 break;
477 #else
479 #if FEATURE_UTF7
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
483 result = UTF7;
484 break;
485 #endif
487 #if FEATURE_UTF32
488 case CodePageUTF32: // 12000
489 result = UTF32;
490 break;
491 case CodePageUTF32BE: // 12001
492 result = new UTF32Encoding(true, true);
493 break;
494 #endif
496 #endif
497 case CodePageUTF8: // 65001, UTF8
498 result = UTF8;
499 break;
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
508 // CP_ACP case.
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");
516 #if FEATURE_ASCII
517 // Have to do ASCII and Latin 1 first so they don't get loaded as code pages
518 case CodePageASCII: // 20127
519 result = ASCII;
520 break;
521 #endif
522 #if FEATURE_LATIN1
523 case ISO_8859_1: // 28591
524 result = Latin1;
525 break;
526 #endif
527 default:
529 #if FEATURE_CODEPAGES_FILE
530 // 1st assume its a code page.
531 result = GetEncodingCodePage(codepage);
532 if (result == null)
533 result = GetEncodingRare(codepage);
534 break;
535 #else
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
543 switch (codepage) {
544 case CodePageUTF32: // 12000
545 result = UTF32;
546 break;
547 case CodePageUTF32BE: // 12001
548 result = new UTF32Encoding(true, true);
549 break;
550 default:
551 result = (Encoding)(EncodingHelper.InvokeI18N ("GetEncoding", codepage));
552 if (result == null)
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));
554 break;
556 #else
557 result = UTF8;
558 #endif
559 break;
560 #endif // FEATURE_CODEPAGES_FILE
563 encodings.Add(codepage, result);
567 return result;
570 [Pure]
571 public static Encoding GetEncoding(int codepage,
572 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
574 Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(codepage, encoderFallback, decoderFallback);
576 if (baseEncoding != null)
577 return baseEncoding;
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!");
595 Encoding result;
596 switch (codepage)
598 case CodePageUTF7: // 65000
599 result = UTF7;
600 break;
601 case CodePageUTF32: // 12000
602 result = UTF32;
603 break;
604 case CodePageUTF32BE: // 12001
605 result = new UTF32Encoding(true, true);
606 break;
607 case ISCIIAssemese:
608 case ISCIIBengali:
609 case ISCIIDevanagari:
610 case ISCIIGujarathi:
611 case ISCIIKannada:
612 case ISCIIMalayalam:
613 case ISCIIOriya:
614 case ISCIIPanjabi:
615 case ISCIITamil:
616 case ISCIITelugu:
617 result = new ISCIIEncoding(codepage);
618 break;
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);
624 break;
626 // Mac Korean 10003 and 20949 are the same
627 case CodePageMacKorean:
628 result = new DBCSCodePageEncoding(CodePageMacKorean, CodePageDLLKorean);
629 break;
630 // GB18030 Code Pages
631 case GB18030:
632 result = new GB18030Encoding();
633 break;
634 // ISO2022 Code Pages
635 case ISOKorean:
636 // case ISOSimplifiedCN
637 case ChineseHZ:
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);
642 break;
643 // Duplicate EUC-CN (51936) just calls a base code page 936,
644 // so does ISOSimplifiedCN (50227), which's gotta be broken
645 case DuplicateEUCCN:
646 case ISOSimplifiedCN:
647 result = new DBCSCodePageEncoding(codepage, EUCCN); // Just maps to 936
648 break;
649 case EUCJP:
650 result = new EUCJPEncoding();
651 break;
652 case EUCKR:
653 result = new DBCSCodePageEncoding(codepage, CodePageDLLKorean); // Maps to 20949
654 break;
655 case ENC50229:
656 throw new NotSupportedException(Environment.GetResourceString("NotSupported_CodePage50229"));
657 case ISO_8859_8I:
658 result = new SBCSCodePageEncoding(codepage, ISO_8859_8_Visual); // Hebrew maps to a different code page
659 break;
660 default:
661 // Not found, already tried codepage table code pages in GetEncoding()
662 throw new NotSupportedException(
663 Environment.GetResourceString("NotSupported_NoCodepageData", codepage));
665 return result;
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.
677 return null;
679 #endif // FEATURE_CODEPAGES_FILE
680 // Returns an Encoding object for a given name or a given code page value.
682 [Pure]
683 public static Encoding GetEncoding(String name)
685 Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(name);
686 if (baseEncoding != null)
687 return baseEncoding;
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.
700 [Pure]
701 public static Encoding GetEncoding(String name,
702 EncoderFallback encoderFallback, DecoderFallback decoderFallback)
704 Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(name, encoderFallback, decoderFallback);
705 if (baseEncoding != null)
706 return baseEncoding;
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
718 [Pure]
719 public static EncodingInfo[] GetEncodings()
721 return EncodingTable.GetEncodings();
724 [Pure]
725 public virtual byte[] GetPreamble()
727 return EmptyArray<Byte>.Value;
730 #if MONO
731 public virtual ReadOnlySpan<byte> Preamble => GetPreamble();
732 #endif
734 private void GetDataItem() {
735 if (dataItem==null) {
736 dataItem = EncodingTable.GetCodePageDataItem(m_codePage);
737 if(dataItem==null) {
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) {
752 GetDataItem();
754 return (dataItem.BodyName);
758 // Returns the human-readable description of the encoding ( e.g. Hebrew (DOS)).
760 public virtual String EncodingName
764 #if MONO
765 return (Environment.GetResourceStringEncodingName(m_codePage));
766 #else
767 return (Environment.GetResourceString("Globalization.cp_" + m_codePage));
768 #endif
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) {
780 GetDataItem();
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) {
794 GetDataItem();
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) {
807 GetDataItem();
809 return (dataItem.UIFamilyCodePage);
814 // True if and only if the encoding is used for display by browsers clients.
816 public virtual bool IsBrowserDisplay {
817 get {
818 if (dataItem==null) {
819 GetDataItem();
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 {
828 get {
829 if (dataItem==null) {
830 GetDataItem();
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 {
839 get {
840 if (dataItem==null) {
841 GetDataItem();
843 return ((dataItem.Flags & MIMECONTF_MAILNEWS) != 0);
848 // True if and only if the encoding is used for saving documents by mail and
849 // news clients
851 public virtual bool IsMailNewsSave {
852 get {
853 if (dataItem==null) {
854 GetDataItem();
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
867 return false;
872 [System.Runtime.InteropServices.ComVisible(false)]
873 public EncoderFallback EncoderFallback
877 return encoderFallback;
882 if (this.IsReadOnly)
883 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
885 if (value == null)
886 throw new ArgumentNullException("value");
887 Contract.EndContractBlock();
889 encoderFallback = value;
894 [System.Runtime.InteropServices.ComVisible(false)]
895 public DecoderFallback DecoderFallback
899 return decoderFallback;
904 if (this.IsReadOnly)
905 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
907 if (value == null)
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;
923 return newEncoding;
927 [System.Runtime.InteropServices.ComVisible(false)]
928 public bool IsReadOnly
932 return (m_isReadOnly);
936 #if FEATURE_ASCII
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;
950 #endif
952 #if FEATURE_LATIN1
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;
965 #endif
967 // Returns the number of bytes required to encode the given character
968 // array.
970 [Pure]
971 public virtual int GetByteCount(char[] chars)
973 if (chars == null)
975 throw new ArgumentNullException("chars",
976 Environment.GetResourceString("ArgumentNull_Array"));
978 Contract.EndContractBlock();
980 return GetByteCount(chars, 0, chars.Length);
983 [Pure]
984 public virtual int GetByteCount(String s)
986 if (s==null)
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.
998 [Pure]
999 public abstract int GetByteCount(char[] chars, int index, int count);
1001 #if MONO
1002 public int GetByteCount(string str, int index, int count) => GetByteCount(str.ToCharArray(), index, count);
1003 #endif
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.
1009 [Pure]
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
1016 if (chars == null)
1017 throw new ArgumentNullException("chars",
1018 Environment.GetResourceString("ArgumentNull_Array"));
1020 if (count < 0)
1021 throw new ArgumentOutOfRangeException("count",
1022 Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1023 Contract.EndContractBlock();
1025 char[] arrChar = new char[count];
1026 int index;
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
1046 // character array.
1048 [Pure]
1049 public virtual byte[] GetBytes(char[] chars)
1051 if (chars == null)
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.
1063 [Pure]
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);
1068 return result;
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
1084 // string.
1086 [Pure]
1087 public virtual byte[] GetBytes(String s)
1089 if (s == null)
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);
1098 return bytes;
1101 public virtual int GetBytes(String s, int charIndex, int charCount,
1102 byte[] bytes, int byteIndex)
1104 if (s==null)
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];
1155 int index;
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];
1162 // Do the work
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
1172 // of result
1173 if (result < byteCount)
1174 byteCount = result;
1176 // Copy the data, don't overrun our array!
1177 for (index = 0; index < byteCount; index++)
1178 bytes[index] = arrByte[index];
1180 return byteCount;
1183 // Returns the number of characters produced by decoding the given byte
1184 // array.
1186 [Pure]
1187 public virtual int GetCharCount(byte[] bytes)
1189 if (bytes == null)
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
1199 // in a byte array.
1201 [Pure]
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)
1206 [Pure]
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
1213 if (bytes == null)
1214 throw new ArgumentNullException("bytes",
1215 Environment.GetResourceString("ArgumentNull_Array"));
1217 if (count < 0)
1218 throw new ArgumentOutOfRangeException("count",
1219 Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1220 Contract.EndContractBlock();
1222 byte[] arrbyte = new byte[count];
1223 int index;
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.
1242 [Pure]
1243 public virtual char[] GetChars(byte[] bytes)
1245 if (bytes == null)
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.
1257 [Pure]
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);
1262 return result;
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];
1315 int index;
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];
1322 // Do the work
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
1332 // of result
1333 if (result < charCount)
1334 charCount = result;
1336 // Copy the data, don't overrun our array!
1337 for (index = 0; index < charCount; index++)
1338 chars[index] = arrChar[index];
1340 return charCount;
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)
1359 if (bytes == null)
1360 throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
1362 if (byteCount < 0)
1363 throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1364 Contract.EndContractBlock();
1366 return String.CreateStringFromEncoding(bytes, byteCount, this);
1369 #if MONO
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);
1386 #endif
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
1397 return m_codePage;
1401 // IsAlwaysNormalized
1402 // Returns true if the encoding is always normalized for the specified encoding form
1403 [Pure]
1404 [System.Runtime.InteropServices.ComVisible(false)]
1405 public bool IsAlwaysNormalized()
1407 #if !FEATURE_NORM_IDNA_ONLY
1408 return this.IsAlwaysNormalized(NormalizationForm.FormC);
1409 #else
1410 return this.IsAlwaysNormalized((NormalizationForm)ExtendedNormalizationForms.FormIdna);
1411 #endif
1414 [Pure]
1415 [System.Runtime.InteropServices.ComVisible(false)]
1416 public virtual bool IsAlwaysNormalized(NormalizationForm form)
1418 // Assume false unless the encoding knows otherwise
1419 return false;
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
1433 // implementation.
1436 public virtual Decoder GetDecoder()
1438 return new DefaultDecoder(this);
1441 [System.Security.SecurityCritical] // auto-generated
1442 private static Encoding CreateDefaultEncoding()
1444 Encoding enc;
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);
1455 else
1456 enc = GetEncoding(codePage);
1457 #else // FEATURE_CODEPAGES_FILE
1459 #if MONO_HYBRID_ENCODING_SUPPORT
1460 enc = EncodingHelper.GetDefaultEncoding ();
1461 enc.m_isReadOnly = true;
1462 #else
1463 // For silverlight we use UTF8 since ANSI isn't available
1464 enc = UTF8;
1465 #endif
1467 #endif //FEATURE_CODEPAGES_FILE
1469 return (enc);
1472 #if MONO_HYBRID_ENCODING_SUPPORT
1473 internal void setReadOnly (bool value = true)
1475 m_isReadOnly = value;
1477 #endif
1479 // Returns an encoding for the system's current ANSI code page.
1482 public static Encoding Default {
1483 [System.Security.SecuritySafeCritical] // auto-generated
1484 get {
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
1503 // implementation.
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
1517 // this method.
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().
1522 [Pure]
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
1531 // this method.
1533 [Pure]
1534 public abstract int GetMaxCharCount(int byteCount);
1536 // Returns a string containing the decoded representation of a given byte
1537 // array.
1539 [Pure]
1540 public virtual String GetString(byte[] bytes)
1542 if (bytes == null)
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
1555 [Pure]
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 {
1569 get {
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 {
1583 get {
1584 if (bigEndianUnicode == null) bigEndianUnicode = new UnicodeEncoding(true, true);
1585 return bigEndianUnicode;
1589 #if FEATURE_UTF7
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 {
1594 get {
1595 if (utf7Encoding == null) utf7Encoding = new UTF7Encoding();
1596 return utf7Encoding;
1599 #endif
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 {
1605 get {
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.
1614 #if FEATURE_UTF32
1615 public static Encoding UTF32 {
1616 get {
1617 if (utf32Encoding == null) utf32Encoding = new UTF32Encoding(false, true);
1618 return utf32Encoding;
1621 #endif
1624 public override bool Equals(Object value) {
1625 Encoding that = value as Encoding;
1626 if (that != null)
1627 return (m_codePage == that.m_codePage) &&
1628 (EncoderFallback.Equals(that.EncoderFallback)) &&
1629 (DecoderFallback.Equals(that.DecoderFallback));
1630 return (false);
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();
1701 #if MONO
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)
1729 if (s == null)
1730 throw new ArgumentNullException(nameof(s),
1731 SR.ArgumentNull_String);
1732 if (index < 0)
1733 throw new ArgumentOutOfRangeException(nameof(index),
1734 SR.ArgumentOutOfRange_NeedNonNegNum);
1735 if (count < 0)
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);
1742 unsafe
1744 fixed (char* pChar = s)
1746 int byteCount = GetByteCount(pChar + index, count);
1747 if (byteCount == 0)
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);
1756 return bytes;
1760 #endif
1762 [Serializable]
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));
1785 try
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)
1806 return this;
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;
1818 return encoder;
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)
1826 // Any info?
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);
1833 #endif
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
1840 // to this method.
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);
1890 [Serializable]
1891 internal class DefaultDecoder : Decoder, ISerializable, IObjectReference
1893 private Encoding m_encoding;
1894 [NonSerialized]
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)
1906 // Any info?
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));
1913 try
1915 this._fallback = (DecoderFallback) info.GetValue("_fallback", typeof(DecoderFallback));
1917 catch (SerializationException)
1919 _fallback = null;
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)
1934 return this;
1937 Decoder decoder = m_encoding.GetDecoder();
1938 if (_fallback != null)
1939 decoder._fallback = _fallback;
1941 return decoder;
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)
1949 // Any info?
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);
1956 #endif
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
1997 // byte values.
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
2024 [SecurityCritical]
2025 unsafe char* chars;
2026 [SecurityCritical]
2027 unsafe char* charStart;
2028 [SecurityCritical]
2029 unsafe char* charEnd;
2030 int charCountResult = 0;
2031 Encoding enc;
2032 DecoderNLS decoder;
2033 [SecurityCritical]
2034 unsafe byte* byteStart;
2035 [SecurityCritical]
2036 unsafe byte* byteEnd;
2037 [SecurityCritical]
2038 unsafe byte* bytes;
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)
2045 this.enc = enc;
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();
2058 else
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)
2071 if (chars != null)
2073 if (chars >= charEnd)
2075 // Throw maybe
2076 bytes-=numBytes; // Didn't encode these bytes
2077 enc.ThrowCharsOverflow(decoder, bytes <= byteStart); // Throw?
2078 return false; // No throw, but no store either
2081 *(chars++) = ch;
2083 charCountResult++;
2084 return true;
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)
2100 // Throw maybe
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)
2111 bytes += 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)
2137 return 0;
2138 return *(bytes++);
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)
2153 // Build our buffer
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)
2163 // Build our buffer
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)
2173 // Build our buffer
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.
2184 if (chars != null)
2186 char* pTemp = chars;
2187 if (fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars) == false)
2189 // Throw maybe
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));
2197 else
2199 charCountResult += fallbackBuffer.InternalFallback(byteBuffer, bytes);
2202 return true;
2205 internal unsafe int Count
2209 return charCountResult;
2214 internal class EncodingByteBuffer
2216 [SecurityCritical]
2217 unsafe byte* bytes;
2218 [SecurityCritical]
2219 unsafe byte* byteStart;
2220 [SecurityCritical]
2221 unsafe byte* byteEnd;
2222 [SecurityCritical]
2223 unsafe char* chars;
2224 [SecurityCritical]
2225 unsafe char* charStart;
2226 [SecurityCritical]
2227 unsafe char* charEnd;
2228 int byteCountResult = 0;
2229 Encoding enc;
2230 EncoderNLS encoder;
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();
2250 else
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");
2266 if (bytes != null)
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
2275 *(bytes++) = b;
2277 byteCountResult++;
2278 return true;
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) &&
2317 AddByte(b2, 2) &&
2318 AddByte(b3, 1) &&
2319 AddByte(b4, 0));
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
2327 else
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
2336 if (bThrow)
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)
2343 // Do the fallback
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.
2364 if (cReturn == 0)
2366 if (chars < charEnd)
2367 cReturn = *(chars++);
2370 return cReturn;
2373 internal unsafe int CharsUsed
2375 [System.Security.SecurityCritical] // auto-generated
2378 return (int)(chars - charStart);
2382 internal unsafe int Count
2386 return byteCountResult;