| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.Text
- {
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.Serialization; //For SR
- using System.Security;
- class Base64Encoding : Encoding
- {
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.SpacingRules", "SA1025:CodeMustNotContainMultipleWhitespaceInARow", Justification = "This alignment is optimal.")]
- static byte[] char2val = new byte[128]
- {
- /* 0-15 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- /* 16-31 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- /* 32-47 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 62, 0xFF, 0xFF, 0xFF, 63,
- /* 48-63 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xFF, 0xFF, 0xFF, 64, 0xFF, 0xFF,
- /* 64-79 */ 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- /* 80-95 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- /* 96-111 */ 0xFF, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- /* 112-127 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- };
- static string val2char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- static byte[] val2byte = new byte[]
- {
- (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P',
- (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f',
- (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v',
- (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
- };
- public override int GetMaxByteCount(int charCount)
- {
- if (charCount < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charCount", SR.GetString(SR.ValueMustBeNonNegative)));
- if ((charCount % 4) != 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
- return charCount / 4 * 3;
- }
- bool IsValidLeadBytes(int v1, int v2, int v3, int v4)
- {
- // First two chars of a four char base64 sequence can't be ==, and must be valid
- return ((v1 | v2) < 64) && ((v3 | v4) != 0xFF);
- }
- bool IsValidTailBytes(int v3, int v4)
- {
- // If the third char is = then the fourth char must be =
- return !(v3 == 64 && v4 != 64);
- }
- [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
- Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
- [SecuritySafeCritical]
- unsafe public override int GetByteCount(char[] chars, int index, int count)
- {
- if (chars == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- if (index < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.ValueMustBeNonNegative)));
- if (index > chars.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
- if (count < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
- if (count > chars.Length - index)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - index)));
- if (count == 0)
- return 0;
- if ((count % 4) != 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Length, count.ToString(NumberFormatInfo.CurrentInfo))));
- fixed (byte* _char2val = char2val)
- {
- fixed (char* _chars = &chars[index])
- {
- int totalCount = 0;
- char* pch = _chars;
- char* pchMax = _chars + count;
- while (pch < pchMax)
- {
- Fx.Assert(pch + 4 <= pchMax, "");
- char pch0 = pch[0];
- char pch1 = pch[1];
- char pch2 = pch[2];
- char pch3 = pch[3];
- if ((pch0 | pch1 | pch2 | pch3) >= 128)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), index + (int)(pch - _chars))));
- // xx765432 xx107654 xx321076 xx543210
- // 76543210 76543210 76543210
- int v1 = _char2val[pch0];
- int v2 = _char2val[pch1];
- int v3 = _char2val[pch2];
- int v4 = _char2val[pch3];
- if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), index + (int)(pch - _chars))));
- int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
- totalCount += byteCount;
- pch += 4;
- }
- return totalCount;
- }
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
- Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
- [SecuritySafeCritical]
- unsafe public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
- {
- if (chars == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- if (charIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charIndex > chars.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
- if (charCount < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charCount", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charCount > chars.Length - charIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charCount", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - charIndex)));
- if (bytes == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bytes"));
- if (byteIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteIndex > bytes.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.OffsetExceedsBufferSize, bytes.Length)));
- if (charCount == 0)
- return 0;
- if ((charCount % 4) != 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
- fixed (byte* _char2val = char2val)
- {
- fixed (char* _chars = &chars[charIndex])
- {
- fixed (byte* _bytes = &bytes[byteIndex])
- {
- char* pch = _chars;
- char* pchMax = _chars + charCount;
- byte* pb = _bytes;
- byte* pbMax = _bytes + bytes.Length - byteIndex;
- while (pch < pchMax)
- {
- Fx.Assert(pch + 4 <= pchMax, "");
- char pch0 = pch[0];
- char pch1 = pch[1];
- char pch2 = pch[2];
- char pch3 = pch[3];
- if ((pch0 | pch1 | pch2 | pch3) >= 128)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), charIndex + (int)(pch - _chars))));
- // xx765432 xx107654 xx321076 xx543210
- // 76543210 76543210 76543210
- int v1 = _char2val[pch0];
- int v2 = _char2val[pch1];
- int v3 = _char2val[pch2];
- int v4 = _char2val[pch3];
- if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), charIndex + (int)(pch - _chars))));
- int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
- if (pb + byteCount > pbMax)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.XmlArrayTooSmall), "bytes"));
- pb[0] = (byte)((v1 << 2) | ((v2 >> 4) & 0x03));
- if (byteCount > 1)
- {
- pb[1] = (byte)((v2 << 4) | ((v3 >> 2) & 0x0F));
- if (byteCount > 2)
- {
- pb[2] = (byte)((v3 << 6) | ((v4 >> 0) & 0x3F));
- }
- }
- pb += byteCount;
- pch += 4;
- }
- return (int)(pb - _bytes);
- }
- }
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
- Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
- [SecuritySafeCritical]
- unsafe public virtual int GetBytes(byte[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
- {
- if (chars == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- if (charIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charIndex > chars.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
- if (charCount < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charCount", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charCount > chars.Length - charIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charCount", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - charIndex)));
- if (bytes == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bytes"));
- if (byteIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteIndex > bytes.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.OffsetExceedsBufferSize, bytes.Length)));
- if (charCount == 0)
- return 0;
- if ((charCount % 4) != 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
- fixed (byte* _char2val = char2val)
- {
- fixed (byte* _chars = &chars[charIndex])
- {
- fixed (byte* _bytes = &bytes[byteIndex])
- {
- byte* pch = _chars;
- byte* pchMax = _chars + charCount;
- byte* pb = _bytes;
- byte* pbMax = _bytes + bytes.Length - byteIndex;
- while (pch < pchMax)
- {
- Fx.Assert(pch + 4 <= pchMax, "");
- byte pch0 = pch[0];
- byte pch1 = pch[1];
- byte pch2 = pch[2];
- byte pch3 = pch[3];
- if ((pch0 | pch1 | pch2 | pch3) >= 128)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string((sbyte*)pch, 0, 4), charIndex + (int)(pch - _chars))));
- // xx765432 xx107654 xx321076 xx543210
- // 76543210 76543210 76543210
- int v1 = _char2val[pch0];
- int v2 = _char2val[pch1];
- int v3 = _char2val[pch2];
- int v4 = _char2val[pch3];
- if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.XmlInvalidBase64Sequence, new string((sbyte*)pch, 0, 4), charIndex + (int)(pch - _chars))));
- int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
- if (pb + byteCount > pbMax)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.XmlArrayTooSmall), "bytes"));
- pb[0] = (byte)((v1 << 2) | ((v2 >> 4) & 0x03));
- if (byteCount > 1)
- {
- pb[1] = (byte)((v2 << 4) | ((v3 >> 2) & 0x0F));
- if (byteCount > 2)
- {
- pb[2] = (byte)((v3 << 6) | ((v4 >> 0) & 0x3F));
- }
- }
- pb += byteCount;
- pch += 4;
- }
- return (int)(pb - _bytes);
- }
- }
- }
- }
- #if NO
- public override Encoder GetEncoder()
- {
- return new BufferedEncoder(this, 4);
- }
- public override Decoder GetDecoder()
- {
- return new BufferedDecoder(this, 3);
- }
- #endif
- public override int GetMaxCharCount(int byteCount)
- {
- if (byteCount < 0 || byteCount > int.MaxValue / 4 * 3 - 2)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteCount", SR.GetString(SR.ValueMustBeInRange, 0, int.MaxValue / 4 * 3 - 2)));
- return ((byteCount + 2) / 3) * 4;
- }
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return GetMaxCharCount(count);
- }
- [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
- Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
- [SecuritySafeCritical]
- unsafe public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
- {
- if (bytes == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bytes"));
- if (byteIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteIndex > bytes.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.OffsetExceedsBufferSize, bytes.Length)));
- if (byteCount < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteCount", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteCount > bytes.Length - byteIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteCount", SR.GetString(SR.SizeExceedsRemainingBufferSpace, bytes.Length - byteIndex)));
- int charCount = GetCharCount(bytes, byteIndex, byteCount);
- if (chars == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- if (charIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charIndex > chars.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
- if (charCount < 0 || charCount > chars.Length - charIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.XmlArrayTooSmall), "chars"));
- // We've computed exactly how many chars there are and verified that
- // there's enough space in the char buffer, so we can proceed without
- // checking the charCount.
- if (byteCount > 0)
- {
- fixed (char* _val2char = val2char)
- {
- fixed (byte* _bytes = &bytes[byteIndex])
- {
- fixed (char* _chars = &chars[charIndex])
- {
- byte* pb = _bytes;
- byte* pbMax = pb + byteCount - 3;
- char* pch = _chars;
- // Convert chunks of 3 bytes to 4 chars
- while (pb <= pbMax)
- {
- // 76543210 76543210 76543210
- // xx765432 xx107654 xx321076 xx543210
- // Inspect the code carefully before you change this
- pch[0] = _val2char[(pb[0] >> 2)];
- pch[1] = _val2char[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
- pch[2] = _val2char[((pb[1] & 0x0F) << 2) | (pb[2] >> 6)];
- pch[3] = _val2char[pb[2] & 0x3F];
- pb += 3;
- pch += 4;
- }
- // Handle 1 or 2 trailing bytes
- if (pb - pbMax == 2)
- {
- // 1 trailing byte
- // 76543210 xxxxxxxx xxxxxxxx
- // xx765432 xx10xxxx xxxxxxxx xxxxxxxx
- pch[0] = _val2char[(pb[0] >> 2)];
- pch[1] = _val2char[((pb[0] & 0x03) << 4)];
- pch[2] = '=';
- pch[3] = '=';
- }
- else if (pb - pbMax == 1)
- {
- // 2 trailing bytes
- // 76543210 76543210 xxxxxxxx
- // xx765432 xx107654 xx3210xx xxxxxxxx
- pch[0] = _val2char[(pb[0] >> 2)];
- pch[1] = _val2char[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
- pch[2] = _val2char[((pb[1] & 0x0F) << 2)];
- pch[3] = '=';
- }
- else
- {
- // 0 trailing bytes
- Fx.Assert(pb - pbMax == 3, "");
- }
- }
- }
- }
- }
- return charCount;
- }
- [Fx.Tag.SecurityNote(Critical = "Contains unsafe code.",
- Safe = "Unsafe code is effectively encapsulated, all inputs are validated.")]
- [SecuritySafeCritical]
- unsafe public int GetChars(byte[] bytes, int byteIndex, int byteCount, byte[] chars, int charIndex)
- {
- if (bytes == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bytes"));
- if (byteIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteIndex > bytes.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteIndex", SR.GetString(SR.OffsetExceedsBufferSize, bytes.Length)));
- if (byteCount < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteCount", SR.GetString(SR.ValueMustBeNonNegative)));
- if (byteCount > bytes.Length - byteIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("byteCount", SR.GetString(SR.SizeExceedsRemainingBufferSpace, bytes.Length - byteIndex)));
- int charCount = GetCharCount(bytes, byteIndex, byteCount);
- if (chars == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- if (charIndex < 0)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.ValueMustBeNonNegative)));
- if (charIndex > chars.Length)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("charIndex", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
- if (charCount < 0 || charCount > chars.Length - charIndex)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.XmlArrayTooSmall), "chars"));
- // We've computed exactly how many chars there are and verified that
- // there's enough space in the char buffer, so we can proceed without
- // checking the charCount.
- if (byteCount > 0)
- {
- fixed (byte* _val2byte = val2byte)
- {
- fixed (byte* _bytes = &bytes[byteIndex])
- {
- fixed (byte* _chars = &chars[charIndex])
- {
- byte* pb = _bytes;
- byte* pbMax = pb + byteCount - 3;
- byte* pch = _chars;
- // Convert chunks of 3 bytes to 4 chars
- while (pb <= pbMax)
- {
- // 76543210 76543210 76543210
- // xx765432 xx107654 xx321076 xx543210
- // Inspect the code carefully before you change this
- pch[0] = _val2byte[(pb[0] >> 2)];
- pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
- pch[2] = _val2byte[((pb[1] & 0x0F) << 2) | (pb[2] >> 6)];
- pch[3] = _val2byte[pb[2] & 0x3F];
- pb += 3;
- pch += 4;
- }
- // Handle 1 or 2 trailing bytes
- if (pb - pbMax == 2)
- {
- // 1 trailing byte
- // 76543210 xxxxxxxx xxxxxxxx
- // xx765432 xx10xxxx xxxxxxxx xxxxxxxx
- pch[0] = _val2byte[(pb[0] >> 2)];
- pch[1] = _val2byte[((pb[0] & 0x03) << 4)];
- pch[2] = (byte)'=';
- pch[3] = (byte)'=';
- }
- else if (pb - pbMax == 1)
- {
- // 2 trailing bytes
- // 76543210 76543210 xxxxxxxx
- // xx765432 xx107654 xx3210xx xxxxxxxx
- pch[0] = _val2byte[(pb[0] >> 2)];
- pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
- pch[2] = _val2byte[((pb[1] & 0x0F) << 2)];
- pch[3] = (byte)'=';
- }
- else
- {
- // 0 trailing bytes
- Fx.Assert(pb - pbMax == 3, "");
- }
- }
- }
- }
- }
- return charCount;
- }
- }
- }
|