Encoding: Don't alloc for zero length array (#13794)
authorBen Adams <thundercat@illyriad.co.uk>
Tue, 2 Jan 2018 02:24:42 +0000 (02:24 +0000)
committerJan Kotas <jkotas@microsoft.com>
Tue, 2 Jan 2018 02:24:42 +0000 (18:24 -0800)
src/mscorlib/shared/System/Text/ASCIIEncoding.cs
src/mscorlib/shared/System/Text/DecoderNLS.cs
src/mscorlib/shared/System/Text/EncoderNLS.cs
src/mscorlib/shared/System/Text/EncodingNLS.cs
src/mscorlib/shared/System/Text/UTF32Encoding.cs
src/mscorlib/shared/System/Text/UTF7Encoding.cs
src/mscorlib/shared/System/Text/UTF8Encoding.cs
src/mscorlib/shared/System/Text/UnicodeEncoding.cs

index 2d2bf20..e89943a 100644 (file)
@@ -4,6 +4,7 @@
 
 using System;
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -130,11 +131,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -168,18 +165,14 @@ namespace System.Text
             if (byteIndex < 0 || byteIndex > bytes.Length)
                 throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
 
-            // If nothing to encode return 0, avoid fixed problem
+            // If nothing to encode return 0
             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[0])
+            fixed (char* pChars = chars)  fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
@@ -275,11 +268,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }
index 098730e..ee88c22 100644 (file)
@@ -5,6 +5,7 @@
 using System.Runtime.Serialization;
 using System.Text;
 using System;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -66,13 +67,8 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(bytes),
                     SR.ArgumentOutOfRange_IndexCountBuffer);
 
-
-            // Avoid null fixed problem
-            if (bytes.Length == 0)
-                bytes = new byte[1];
-
             // Just call pointer version
-            fixed (byte* pBytes = &bytes[0])
+            fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetCharCount(pBytes + index, count, flush);
         }
 
@@ -121,18 +117,11 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(charIndex),
                     SR.ArgumentOutOfRange_Index);
 
-
-            // Avoid empty input fixed problem
-            if (bytes.Length == 0)
-                bytes = new byte[1];
-
             int charCount = chars.Length - charIndex;
-            if (chars.Length == 0)
-                chars = new char[1];
 
             // Just call pointer version
-            fixed (byte* pBytes = &bytes[0])
-            fixed (char* pChars = &chars[0])
+            fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
+            fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount,
                                 pChars + charIndex, charCount, flush);
@@ -185,17 +174,10 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(chars),
                       SR.ArgumentOutOfRange_IndexCountBuffer);
 
-
-            // Avoid empty input problem
-            if (bytes.Length == 0)
-                bytes = new byte[1];
-            if (chars.Length == 0)
-                chars = new char[1];
-
             // Just call the pointer version (public overrides can't do this)
-            fixed (byte* pBytes = &bytes[0])
+            fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
             {
-                fixed (char* pChars = &chars[0])
+                fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 {
                     Convert(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, flush,
                         out bytesUsed, out charsUsed, out completed);
index f8ff86d..e83666f 100644 (file)
@@ -4,6 +4,7 @@
 
 using System.Text;
 using System;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -63,13 +64,9 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(chars),
                       SR.ArgumentOutOfRange_IndexCountBuffer);
 
-            // Avoid empty input problem
-            if (chars.Length == 0)
-                chars = new char[1];
-
             // Just call the pointer version
             int result = -1;
-            fixed (char* pChars = &chars[0])
+            fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
             {
                 result = GetByteCount(pChars + index, count, flush);
             }
@@ -112,16 +109,11 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(byteIndex),
                      SR.ArgumentOutOfRange_Index);
 
-            if (chars.Length == 0)
-                chars = new char[1];
-
             int byteCount = bytes.Length - byteIndex;
-            if (bytes.Length == 0)
-                bytes = new byte[1];
 
             // Just call pointer version
-            fixed (char* pChars = &chars[0])
-            fixed (byte* pBytes = &bytes[0])
+            fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
+            fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
 
                 // Remember that charCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount,
@@ -171,17 +163,10 @@ namespace System.Text
                 throw new ArgumentOutOfRangeException(nameof(bytes),
                       SR.ArgumentOutOfRange_IndexCountBuffer);
 
-
-            // Avoid empty input problem
-            if (chars.Length == 0)
-                chars = new char[1];
-            if (bytes.Length == 0)
-                bytes = new byte[1];
-
             // Just call the pointer version (can't do this for non-msft encoders)
-            fixed (char* pChars = &chars[0])
+            fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
             {
-                fixed (byte* pBytes = &bytes[0])
+                fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 {
                     Convert(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, flush,
                         out charsUsed, out bytesUsed, out completed);
index 5059407..d5de9e5 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using System.Collections;
 using System.Globalization;
+using System.Runtime.InteropServices;
 using System.Threading;
 
 namespace System.Text
@@ -107,11 +108,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = s) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -151,13 +148,9 @@ namespace System.Text
             // 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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
-                return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);            
+                return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
         // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
@@ -245,11 +238,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }
index a666c25..7828775 100644 (file)
@@ -9,6 +9,7 @@
 using System;
 using System.Diagnostics;
 using System.Globalization;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -174,11 +175,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = s) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -219,11 +216,7 @@ namespace System.Text
             // 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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
@@ -319,11 +312,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }
index 7881364..0246c28 100644 (file)
@@ -8,6 +8,7 @@
 
 using System;
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -204,11 +205,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = s) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -249,11 +246,7 @@ namespace System.Text
             // 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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
@@ -349,11 +342,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }
index e5544c5..a89af8e 100644 (file)
@@ -17,6 +17,7 @@
 using System;
 using System.Diagnostics;
 using System.Globalization;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -201,11 +202,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = s) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -246,11 +243,7 @@ namespace System.Text
             // 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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
@@ -346,11 +339,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }
index a5b89a6..342bf53 100644 (file)
@@ -9,6 +9,7 @@
 using System;
 using System.Globalization;
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 
 namespace System.Text
 {
@@ -160,11 +161,7 @@ namespace System.Text
 
             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[0])
+            fixed (char* pChars = s) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
 
@@ -205,11 +202,7 @@ namespace System.Text
             // 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[0])
+            fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
                 // Remember that byteCount is # to decode, not size of array.
                 return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
         }
@@ -305,11 +298,7 @@ namespace System.Text
             // 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[0])
+            fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
                 // Remember that charCount is # to decode, not size of array
                 return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
         }