summaryrefslogtreecommitdiff
path: root/src/mscorlib
diff options
context:
space:
mode:
authorTarek Mahmoud Sayed <tarekms@microsoft.com>2016-07-07 11:35:03 -0700
committerGitHub <noreply@github.com>2016-07-07 11:35:03 -0700
commit00eca9ab295420873a551d3a9e0acde0da20338a (patch)
tree36487bc9e8ed255bd37213a55b09abd4f1a2476f /src/mscorlib
parent840a6ca79d4643cd0cfed9444e5658933d901618 (diff)
parent467f06d6f01deb4905a901a9d337a8dfdef817e1 (diff)
downloadcoreclr-00eca9ab295420873a551d3a9e0acde0da20338a.tar.gz
coreclr-00eca9ab295420873a551d3a9e0acde0da20338a.tar.bz2
coreclr-00eca9ab295420873a551d3a9e0acde0da20338a.zip
Merge pull request #6114 from jamesqo/encodingforwarder
Consolidate much of the duplicated code across Encoding implementations
Diffstat (limited to 'src/mscorlib')
-rw-r--r--src/mscorlib/mscorlib.shared.sources.props1
-rw-r--r--src/mscorlib/src/System/Text/ASCIIEncoding.cs328
-rw-r--r--src/mscorlib/src/System/Text/EncodingForwarder.cs339
-rw-r--r--src/mscorlib/src/System/Text/EncodingNLS.cs320
-rw-r--r--src/mscorlib/src/System/Text/UTF32Encoding.cs318
-rw-r--r--src/mscorlib/src/System/Text/UTF7Encoding.cs323
-rw-r--r--src/mscorlib/src/System/Text/UTF8Encoding.cs322
-rw-r--r--src/mscorlib/src/System/Text/UnicodeEncoding.cs323
8 files changed, 555 insertions, 1719 deletions
diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props
index f530a31358..78983c0639 100644
--- a/src/mscorlib/mscorlib.shared.sources.props
+++ b/src/mscorlib/mscorlib.shared.sources.props
@@ -982,6 +982,7 @@
<TextSources Include="$(BclSourcesRoot)\System\Text\EncoderFallback.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\EncoderReplacementFallback.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\Encoding.cs" />
+ <TextSources Include="$(BclSourcesRoot)\System\Text\EncodingForwarder.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\EncodingInfo.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\EncodingNLS.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\EncodingProvider.cs" />
diff --git a/src/mscorlib/src/System/Text/ASCIIEncoding.cs b/src/mscorlib/src/System/Text/ASCIIEncoding.cs
index 178ade5515..ab5fa77145 100644
--- a/src/mscorlib/src/System/Text/ASCIIEncoding.cs
+++ b/src/mscorlib/src/System/Text/ASCIIEncoding.cs
@@ -36,127 +36,49 @@ namespace System.Text
this.decoderFallback = DecoderFallback.ReplacementFallback;
}
- //
// WARNING: GetByteCount(string chars), GetBytes(string chars,...), and GetString(byte[] byteIndex...)
// WARNING: have different variable names than EncodingNLS.cs, so this can't just be cut & pasted,
// WARNING: or it'll break VB's way of calling these.
- //
- // The following methods are copied from EncodingNLS.cs.
- // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
- // These should be kept in sync for the following classes:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- //
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
+
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe 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);
+ public override int GetByteCount(char[] chars, int index, int count)
+ {
+ return EncodingForwarder.GetByteCount(this, chars, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetByteCount(String chars)
+ public override int GetByteCount(String chars)
{
- // Validate input
- if (chars==null)
- throw new ArgumentNullException("chars");
- Contract.EndContractBlock();
-
- fixed (char* pChars = chars)
- return GetByteCount(pChars, chars.Length, null);
+ return EncodingForwarder.GetByteCount(this, chars);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(String chars, int charIndex, int charCount,
+ public override int GetBytes(String chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty byte arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -167,234 +89,60 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty byte arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
- {
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ public override int GetCharCount(byte[] bytes, int index, int count)
+ {
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like empty char arrays
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe String GetString(byte[] bytes, int byteIndex, int byteCount)
- {
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
-
- if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (byteCount == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + byteIndex, byteCount, this);
+ public override String GetString(byte[] bytes, int byteIndex, int byteCount)
+ {
+ return EncodingForwarder.GetString(this, bytes, byteIndex, byteCount);
}
-
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+
+ // End of overridden methods which use EncodingForwarder
// GetByteCount
// Note: We start by assuming that the output will be the same as count. Having
diff --git a/src/mscorlib/src/System/Text/EncodingForwarder.cs b/src/mscorlib/src/System/Text/EncodingForwarder.cs
new file mode 100644
index 0000000000..d4bcf800e3
--- /dev/null
+++ b/src/mscorlib/src/System/Text/EncodingForwarder.cs
@@ -0,0 +1,339 @@
+// 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;
+using System.Security;
+
+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.
+
+ // NOTE: This class should ONLY be called from Encodings that override
+ // the internal methods which accept an Encoder/DecoderNLS. The reason
+ // for this is that by default, those methods just call the same overload
+ // except without the encoder/decoder parameter. If an overriden method
+ // without that parameter calls this class, which calls the overload with
+ // the parameter, it will call the same method again, which will eventually
+ // lead to a StackOverflowException.
+
+ [SecuritySafeCritical]
+ 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 (internal) pointer version
+ fixed (char* pChars = chars)
+ return encoding.GetByteCount(pChars + index, count, encoder: null);
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static int GetByteCount(Encoding encoding, string s)
+ {
+ Contract.Assert(encoding != null);
+ if (s == null)
+ {
+ string paramName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the string chars
+ // UTF8Encoding does this as well, but it originally threw an ArgumentNull for "s" so don't check for that
+ throw new ArgumentNullException(paramName);
+ }
+ Contract.EndContractBlock();
+
+ // NOTE: The behavior of fixed *is* defined by
+ // the spec for empty strings, although not for
+ // null strings/empty char arrays. See
+ // http://stackoverflow.com/q/37757751/4077294
+ // Regardless, we may still want to check
+ // for if (s.Length == 0) in the future
+ // and short-circuit as an optimization (TODO).
+
+ fixed (char* pChars = s)
+ return encoding.GetByteCount(pChars, s.Length, encoder: null);
+ }
+
+ [SecurityCritical]
+ public unsafe static int GetByteCount(Encoding encoding, char* chars, int count)
+ {
+ Contract.Assert(encoding != null);
+ if (chars == null)
+ {
+ throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ Contract.EndContractBlock();
+
+ // Call the internal version, with an empty encoder
+ return encoding.GetByteCount(chars, count, encoder: null);
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static int GetBytes(Encoding encoding, string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
+ {
+ Contract.Assert(encoding != null);
+ if (s == null || bytes == null)
+ {
+ string stringName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the first parameter chars
+ throw new ArgumentNullException(s == null ? stringName : "bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (charIndex < 0 || charCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(charIndex < 0 ? "charIndex" : "charCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ if (s.Length - charIndex < charCount)
+ {
+ string stringName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the first parameter chars
+ // Duplicate the above check since we don't want the overhead of a type check on the general path
+ throw new ArgumentOutOfRangeException(stringName, Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ {
+ throw new ArgumentOutOfRangeException("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ }
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = bytes)
+ {
+ return encoding.GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, encoder: null);
+ }
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static int GetBytes(Encoding encoding, char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
+ {
+ Contract.Assert(encoding != null);
+ if (chars == null || bytes == null)
+ {
+ throw new ArgumentNullException(chars == null ? "chars" : "bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (charIndex < 0 || charCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(charIndex < 0 ? "charIndex" : "charCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ if (chars.Length - charIndex < charCount)
+ {
+ throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ {
+ throw new ArgumentOutOfRangeException("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ }
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Note that this is the # of bytes to decode,
+ // not the size of the array
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ // Just call the (internal) pointer version
+ fixed (char* pChars = chars) fixed (byte* pBytes = bytes)
+ {
+ return encoding.GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, encoder: null);
+ }
+ }
+
+ [SecurityCritical]
+ public unsafe static int GetBytes(Encoding encoding, char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null || chars == null)
+ {
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (charCount < 0 || byteCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(charCount < 0 ? "charCount" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ Contract.EndContractBlock();
+
+ return encoding.GetBytes(chars, charCount, bytes, byteCount, encoder: null);
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static int GetCharCount(Encoding encoding, byte[] bytes, int index, int count)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (index < 0 || count < 0)
+ {
+ throw new ArgumentOutOfRangeException(index < 0 ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ if (bytes.Length - index < count)
+ {
+ throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ }
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays.
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return encoding.GetCharCount(pBytes + index, count, decoder: null);
+ }
+
+ [SecurityCritical]
+ public unsafe static int GetCharCount(Encoding encoding, byte* bytes, int count)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ Contract.EndContractBlock();
+
+ return encoding.GetCharCount(bytes, count, decoder: null);
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static int GetChars(Encoding encoding, byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null || chars == null)
+ {
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (byteIndex < 0 || byteCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(byteIndex < 0 ? "byteIndex" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ if (bytes.Length - byteIndex < byteCount)
+ {
+ throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ }
+ if (charIndex < 0 || charIndex > chars.Length)
+ {
+ throw new ArgumentOutOfRangeException("charIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ }
+ Contract.EndContractBlock();
+
+ if (byteCount == 0)
+ return 0;
+
+ // NOTE: This is the # of chars we can decode,
+ // not the size of the array
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = chars)
+ {
+ return encoding.GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, decoder: null);
+ }
+ }
+
+ [SecurityCritical]
+ public unsafe static int GetChars(Encoding encoding, byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null || chars == null)
+ {
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (charCount < 0 || byteCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(charCount < 0 ? "charCount" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ Contract.EndContractBlock();
+
+ return encoding.GetChars(bytes, byteCount, chars, charCount, decoder: null);
+ }
+
+ [SecuritySafeCritical]
+ public unsafe static string GetString(Encoding encoding, byte[] bytes, int index, int count)
+ {
+ Contract.Assert(encoding != null);
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ }
+ if (index < 0 || count < 0)
+ {
+ // ASCIIEncoding has different names for its parameters here (byteIndex, byteCount)
+ bool ascii = encoding is ASCIIEncoding;
+ string indexName = ascii ? "byteIndex" : "index";
+ string countName = ascii ? "byteCount" : "count";
+ throw new ArgumentOutOfRangeException(index < 0 ? indexName : countName, Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+ if (bytes.Length - index < count)
+ {
+ throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ }
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0)
+ return string.Empty;
+
+ // Call string.CreateStringFromEncoding here, which
+ // allocates a string and lets the Encoding modify
+ // it in place. This way, we don't have to allocate
+ // an intermediary char[] to decode into and then
+ // call the string constructor; instead we decode
+ // directly into the string.
+
+ fixed (byte* pBytes = bytes)
+ {
+ return string.CreateStringFromEncoding(pBytes + index, count, encoding);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Text/EncodingNLS.cs b/src/mscorlib/src/System/Text/EncodingNLS.cs
index 73aba3df95..d670d6daa7 100644
--- a/src/mscorlib/src/System/Text/EncodingNLS.cs
+++ b/src/mscorlib/src/System/Text/EncodingNLS.cs
@@ -14,18 +14,7 @@ namespace System.Text
using Win32Native = Microsoft.Win32.Win32Native;
// This class overrides Encoding with the things we need for our NLS Encodings
- //
- // All of the GetBytes/Chars GetByte/CharCount methods are just wrappers for the pointer
- // plus decoder/encoder method that is our real workhorse. Note that this is an internal
- // class, so our public classes cannot derive from this class. Because of this, all of the
- // GetBytes/Chars GetByte/CharCount wrapper methods are duplicated in all of our public
- // encodings, which currently include:
- //
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, & UnicodeEncoding
- //
- // So if you change the wrappers in this class, you must change the wrappers in the other classes
- // as well because they should have the same behavior.
- //
+
[System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
internal abstract class EncodingNLS : Encoding
@@ -34,110 +23,43 @@ namespace System.Text
{
}
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
+
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // 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)
- {
- // 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);
+ public override int GetByteCount(char[] chars, int index, int count)
+ {
+ return EncodingForwarder.GetByteCount(this, chars, index, count);
}
-
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe int GetByteCount(String s)
+
+ public override int GetByteCount(String s)
{
- // Validate input
- if (s==null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
-
- fixed (char* pChars = s)
- return GetByteCount(pChars, s.Length, null);
- }
+ return EncodingForwarder.GetByteCount(this, s);
+ }
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
[System.Security.SecurityCritical] // auto-generated
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s == null || bytes == null)
- throw new ArgumentNullException((s == null ? "s" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (s.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("s",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -148,215 +70,51 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
[System.Security.SecurityCritical] // auto-generated
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+
+ public override int GetCharCount(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
[System.Security.SecurityCritical] // auto-generated
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like empty arrays
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
[System.Security.SecurityCritical] // auto-generated
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- public override unsafe String GetString(byte[] bytes, int index, int count)
+
+ public override String GetString(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + index, count, this);
+ return EncodingForwarder.GetString(this, bytes, index, count);
}
public override Decoder GetDecoder()
diff --git a/src/mscorlib/src/System/Text/UTF32Encoding.cs b/src/mscorlib/src/System/Text/UTF32Encoding.cs
index 02a3232809..cd7d0a9088 100644
--- a/src/mscorlib/src/System/Text/UTF32Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF32Encoding.cs
@@ -78,123 +78,44 @@ namespace System.Text
}
}
-
- //
- // The following methods are copied from EncodingNLS.cs.
- // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
- // These should be kept in sync for the following classes:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- //
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // 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)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetByteCount(String s)
+ public override int GetByteCount(String s)
{
- // Validate input
- if (s==null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
-
- fixed (char* pChars = s)
- return GetByteCount(pChars, s.Length, null);
+ return EncodingForwarder.GetByteCount(this, s);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s == null || bytes == null)
- throw new ArgumentNullException((s == null ? "s" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (s.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("s",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fix our input array if 0 length because fixed doesn't like 0 length arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -205,230 +126,57 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fix our input array if 0 length because fixed doesn't like 0 length arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ public override int GetCharCount(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays.
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fix our input array if 0 length because fixed doesn't like 0 length arrays
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe String GetString(byte[] bytes, int index, int count)
+ public override String GetString(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + index, count, this);
+ return EncodingForwarder.GetString(this, bytes, index, count);
}
-
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+
+ // End of overridden methods which use EncodingForwarder
[System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS encoder)
diff --git a/src/mscorlib/src/System/Text/UTF7Encoding.cs b/src/mscorlib/src/System/Text/UTF7Encoding.cs
index 727a43bc33..7c4f773cb4 100644
--- a/src/mscorlib/src/System/Text/UTF7Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF7Encoding.cs
@@ -145,125 +145,47 @@ namespace System.Text
return this.CodePage + this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode();
}
- //
- // The following methods are copied from EncodingNLS.cs.
- // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
- // These should be kept in sync for the following classes:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- //
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe 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);
+ public override int GetByteCount(char[] chars, int index, int count)
+ {
+ return EncodingForwarder.GetByteCount(this, chars, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
- public override unsafe int GetByteCount(String s)
+ public override int GetByteCount(String s)
{
- // Validate input
- if (s==null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
-
- fixed (char* pChars = s)
- return GetByteCount(pChars, s.Length, null);
+ return EncodingForwarder.GetByteCount(this, s);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
- public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s == null || bytes == null)
- throw new ArgumentNullException((s == null ? "s" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (s.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("s",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -274,234 +196,61 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
- {
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays.
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ public override int GetCharCount(byte[] bytes, int index, int count)
+ {
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like empty arrays
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
- public override unsafe String GetString(byte[] bytes, int index, int count)
+ public override String GetString(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + index, count, this);
+ return EncodingForwarder.GetString(this, bytes, index, count);
}
-
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+
+ // End of overridden methods which use EncodingForwarder
[System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
diff --git a/src/mscorlib/src/System/Text/UTF8Encoding.cs b/src/mscorlib/src/System/Text/UTF8Encoding.cs
index 874f7f3b56..87637992a5 100644
--- a/src/mscorlib/src/System/Text/UTF8Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF8Encoding.cs
@@ -98,128 +98,45 @@ namespace System.Text
}
}
-
- //
- // WARNING: GetByteCount(string chars)
- // WARNING: has different variable names than EncodingNLS.cs, so this can't just be cut & pasted,
- // WARNING: otherwise it'll break VB's way of declaring these.
- //
- // The following methods are copied from EncodingNLS.cs.
- // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
- // These should be kept in sync for the following classes:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- //
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // 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)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetByteCount(String chars)
+ public override int GetByteCount(String chars)
{
- // Validate input
- if (chars==null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
-
- fixed (char* pChars = chars)
- return GetByteCount(pChars, chars.Length, null);
+ return EncodingForwarder.GetByteCount(this, chars);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s == null || bytes == null)
- throw new ArgumentNullException((s == null ? "s" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (s.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("s",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -230,234 +147,61 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ public override int GetCharCount(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays.
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
- public override unsafe String GetString(byte[] bytes, int index, int count)
+ public override String GetString(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + index, count, this);
+ return EncodingForwarder.GetString(this, bytes, index, count);
}
-
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+
+ // End of overridden methods which use EncodingForwarder
// To simplify maintenance, the structure of GetByteCount and GetBytes should be
// kept the same as much as possible
diff --git a/src/mscorlib/src/System/Text/UnicodeEncoding.cs b/src/mscorlib/src/System/Text/UnicodeEncoding.cs
index 6f0b6efc58..7a6244af95 100644
--- a/src/mscorlib/src/System/Text/UnicodeEncoding.cs
+++ b/src/mscorlib/src/System/Text/UnicodeEncoding.cs
@@ -77,123 +77,45 @@ namespace System.Text
}
}
- //
- // The following methods are copied from EncodingNLS.cs.
- // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
- // These should be kept in sync for the following classes:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- //
+ // NOTE: Many methods in this class forward to EncodingForwarder for
+ // validating arguments/wrapping the unsafe methods in this class
+ // which do the actual work. That class contains
+ // shared logic for doing this which is used by
+ // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
+ // UTF7Encoding, and UTF8Encoding.
+ // The reason the code is separated out into a static class, rather
+ // than a base class which overrides all of these methods for us
+ // (which is what EncodingNLS is for internal Encodings) is because
+ // that's really more of an implementation detail so it's internal.
+ // At the same time, C# doesn't allow a public class subclassing an
+ // internal/private one, so we end up having to re-override these
+ // methods in all of the public Encodings + EncodingNLS.
// Returns the number of bytes required to encode a range of characters in
// a character array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe 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);
+ public override int GetByteCount(char[] chars, int index, int count)
+ {
+ return EncodingForwarder.GetByteCount(this, chars, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetByteCount(String s)
+ public override int GetByteCount(String s)
{
- // Validate input
- if (s==null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
-
- fixed (char* pChars = s)
- return GetByteCount(pChars, s.Length, null);
+ return EncodingForwarder.GetByteCount(this, s);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- // Validate Parameters
- if (chars == null)
- throw new ArgumentNullException("chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return EncodingForwarder.GetByteCount(this, chars, count);
}
- // Parent method is safe.
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ public override int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s == null || bytes == null)
- throw new ArgumentNullException((s == null ? "s" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (s.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("s",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s)
- fixed ( byte* pBytes = bytes)
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -204,234 +126,61 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = chars)
- fixed (byte* pBytes = bytes)
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetCharCount(byte[] bytes, int index, int count)
- {
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
- // If no input just return 0, fixed doesn't like 0 length arrays
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ public override int GetCharCount(byte[] bytes, int index, int count)
+ {
+ return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetCharCount(bytes, count, null);
+ return EncodingForwarder.GetCharCount(this, bytes, count);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
-
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
-
- // Just call pointer version
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes)
- fixed (char* pChars = chars)
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
[System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- return GetChars(bytes, byteCount, chars, charCount, null);
+ return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
- //
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
- public override unsafe String GetString(byte[] bytes, int index, int count)
+ public override String GetString(byte[] bytes, int index, int count)
{
- // Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException("bytes",
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0) return String.Empty;
-
- fixed (byte* pBytes = bytes)
- return String.CreateStringFromEncoding(
- pBytes + index, count, this);
+ return EncodingForwarder.GetString(this, bytes, index, count);
}
-
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+
+ // End of overridden methods which use EncodingForwarder
[System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)