Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Text / Base64Encoding.cs / 1305376 / Base64Encoding.cs
//------------------------------------------------------------------------------ // 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 { 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; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // 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 { 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; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ClientSideQueueItem.cs
- Viewport3DAutomationPeer.cs
- PropertyGroupDescription.cs
- SqlDataSource.cs
- CustomErrorsSection.cs
- PartBasedPackageProperties.cs
- XmlEncodedRawTextWriter.cs
- DrawTreeNodeEventArgs.cs
- IItemContainerGenerator.cs
- RepeatButton.cs
- DynamicObjectAccessor.cs
- NativeMethods.cs
- MouseEventArgs.cs
- TreeViewItemAutomationPeer.cs
- SystemIcmpV4Statistics.cs
- MarginsConverter.cs
- SyndicationDeserializer.cs
- ProvideValueServiceProvider.cs
- FormViewUpdateEventArgs.cs
- StaticDataManager.cs
- DetailsViewRow.cs
- RoleService.cs
- SystemGatewayIPAddressInformation.cs
- LOSFormatter.cs
- DateRangeEvent.cs
- ValidatorCollection.cs
- LicFileLicenseProvider.cs
- XPathSelfQuery.cs
- CodeRegionDirective.cs
- Helpers.cs
- log.cs
- ConfigXmlWhitespace.cs
- XmlSerializerOperationBehavior.cs
- X509Chain.cs
- WebServiceParameterData.cs
- ReservationCollection.cs
- COAUTHINFO.cs
- NetCodeGroup.cs
- IncrementalReadDecoders.cs
- StylusOverProperty.cs
- CategoryGridEntry.cs
- FormViewInsertEventArgs.cs
- MarginCollapsingState.cs
- EncryptedPackageFilter.cs
- DeclaredTypeElementCollection.cs
- LockCookie.cs
- OperationInfo.cs
- SizeIndependentAnimationStorage.cs
- FormViewRow.cs
- SQLInt16Storage.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- EditorZoneDesigner.cs
- SqlSelectClauseBuilder.cs
- _StreamFramer.cs
- TableChangeProcessor.cs
- OutputCacheModule.cs
- CodeNamespaceImport.cs
- ReachFixedDocumentSerializerAsync.cs
- PeerReferralPolicy.cs
- BitmapDecoder.cs
- ObjectDisposedException.cs
- WebPartTransformerCollection.cs
- PointCollectionValueSerializer.cs
- XhtmlTextWriter.cs
- ControlAdapter.cs
- EditingContext.cs
- CurrentChangingEventArgs.cs
- MemberPathMap.cs
- AnimationException.cs
- TextBlock.cs
- SqlProvider.cs
- OleDbSchemaGuid.cs
- DataRelation.cs
- SchemaImporterExtensionElement.cs
- DelegatingTypeDescriptionProvider.cs
- InkPresenterAutomationPeer.cs
- PropertyGrid.cs
- Storyboard.cs
- SafeTimerHandle.cs
- SecurityContextTokenCache.cs
- CancellationTokenSource.cs
- MsmqAppDomainProtocolHandler.cs
- SerializationSectionGroup.cs
- StateManagedCollection.cs
- ShaperBuffers.cs
- EntityContainerEmitter.cs
- EntryPointNotFoundException.cs
- ImageBrush.cs
- OutputCacheProfile.cs
- ExpressionBuilderContext.cs
- UnsafeNativeMethods.cs
- VectorValueSerializer.cs
- XamlFilter.cs
- C14NUtil.cs
- DNS.cs
- ClientSettingsStore.cs
- ToolBarOverflowPanel.cs
- HttpHandlerAction.cs
- WorkflowInlining.cs
- UntrustedRecipientException.cs