diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props index f530a31358ca..78983c0639c8 100644 --- a/src/mscorlib/mscorlib.shared.sources.props +++ b/src/mscorlib/mscorlib.shared.sources.props @@ -982,6 +982,7 @@ + diff --git a/src/mscorlib/src/System/Text/ASCIIEncoding.cs b/src/mscorlib/src/System/Text/ASCIIEncoding.cs index 178ade55156f..cc9f6aa96266 100644 --- a/src/mscorlib/src/System/Text/ASCIIEncoding.cs +++ b/src/mscorlib/src/System/Text/ASCIIEncoding.cs @@ -56,29 +56,9 @@ internal override void SetDefaultFallbacks() // parent method is safe [System.Security.SecuritySafeCritical] // auto-generated - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) diff --git a/src/mscorlib/src/System/Text/EncodingForwarder.cs b/src/mscorlib/src/System/Text/EncodingForwarder.cs new file mode 100644 index 000000000000..75f8343607f2 --- /dev/null +++ b/src/mscorlib/src/System/Text/EncodingForwarder.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.Contracts; + +namespace System.Text +{ + // Shared implementations for commonly overriden Encoding methods + + internal static class EncodingForwarder + { + // We normally have to duplicate a lot of code between UTF8Encoding, + // UTF7Encoding, EncodingNLS, etc. because we want to override many + // of the methods in all of those classes to just forward to the unsafe + // version. (e.g. GetBytes(char[])) + // Ideally, everything would just derive from EncodingNLS, but that's + // not exposed in the public API, and C# prohibits a public class from + // inheriting from an internal one. So, we have to override each of the + // methods in question and repeat the argument validation/logic. + + // These set of methods exist so instead of duplicating code, we can + // simply have those overriden methods call here to do the actual work. + + public unsafe static int GetByteCount(Encoding encoding, char[] chars, int index, int count) + { + // Validate parameters + + Contract.Assert(encoding != null); // this parameter should only be affected internally, so just do a debug check here + if (chars == null) + { + throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array")); + } + if (index < 0 || count < 0) + { + throw new ArgumentOutOfRangeException(index < 0 ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + if (chars.Length - index < count) + { + throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); + } + Contract.EndContractBlock(); + + // If no input, return 0, avoid fixed empty array problem + if (count == 0) + return 0; + + // Just call the pointer version + fixed (char* pChars = chars) + return encoding.GetByteCount(pChars + index, count, null); + } + } +} diff --git a/src/mscorlib/src/System/Text/EncodingNLS.cs b/src/mscorlib/src/System/Text/EncodingNLS.cs index 73aba3df9533..91625ae36793 100644 --- a/src/mscorlib/src/System/Text/EncodingNLS.cs +++ b/src/mscorlib/src/System/Text/EncodingNLS.cs @@ -42,29 +42,9 @@ protected EncodingNLS(int codePage) : base(codePage) // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding // parent method is safe [System.Security.SecuritySafeCritical] // overrides public transparent member - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) diff --git a/src/mscorlib/src/System/Text/UTF32Encoding.cs b/src/mscorlib/src/System/Text/UTF32Encoding.cs index 02a32328095b..7a4cb58dbbdb 100644 --- a/src/mscorlib/src/System/Text/UTF32Encoding.cs +++ b/src/mscorlib/src/System/Text/UTF32Encoding.cs @@ -95,29 +95,9 @@ internal override void SetDefaultFallbacks() // parent method is safe [System.Security.SecuritySafeCritical] // auto-generated - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) diff --git a/src/mscorlib/src/System/Text/UTF7Encoding.cs b/src/mscorlib/src/System/Text/UTF7Encoding.cs index 727a43bc33ad..edf5c9516d3f 100644 --- a/src/mscorlib/src/System/Text/UTF7Encoding.cs +++ b/src/mscorlib/src/System/Text/UTF7Encoding.cs @@ -161,29 +161,9 @@ public override int GetHashCode() // parent method is safe [System.Security.SecuritySafeCritical] // auto-generated - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) diff --git a/src/mscorlib/src/System/Text/UTF8Encoding.cs b/src/mscorlib/src/System/Text/UTF8Encoding.cs index 874f7f3b5697..84ca87b687f0 100644 --- a/src/mscorlib/src/System/Text/UTF8Encoding.cs +++ b/src/mscorlib/src/System/Text/UTF8Encoding.cs @@ -119,29 +119,9 @@ internal override void SetDefaultFallbacks() // parent method is safe [System.Security.SecuritySafeCritical] // auto-generated - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) diff --git a/src/mscorlib/src/System/Text/UnicodeEncoding.cs b/src/mscorlib/src/System/Text/UnicodeEncoding.cs index 6f0b6efc582a..5fb2ad6309d7 100644 --- a/src/mscorlib/src/System/Text/UnicodeEncoding.cs +++ b/src/mscorlib/src/System/Text/UnicodeEncoding.cs @@ -93,29 +93,9 @@ internal override void SetDefaultFallbacks() // parent method is safe [System.Security.SecuritySafeCritical] // auto-generated - public override unsafe int GetByteCount(char[] chars, int index, int count) + public override int GetByteCount(char[] chars, int index, int count) { - // Validate input parameters - if (chars == null) - throw new ArgumentNullException("chars", - Environment.GetResourceString("ArgumentNull_Array")); - - if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), - Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - - if (chars.Length - index < count) - throw new ArgumentOutOfRangeException("chars", - Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); - Contract.EndContractBlock(); - - // If no input, return 0, avoid fixed empty array problem - if (count == 0) - return 0; - - // Just call the pointer version - fixed (char* pChars = chars) - return GetByteCount(pChars + index, count, null); + return EncodingForwarder.GetByteCount(this, chars, index, count); } // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)