Update S.T.Json sources with ifdefs so that a netstandard compatible source package...
authorAhson Khan <ahkha@microsoft.com>
Thu, 17 Jan 2019 20:50:48 +0000 (12:50 -0800)
committerGitHub <noreply@github.com>
Thu, 17 Jan 2019 20:50:48 +0000 (12:50 -0800)
* Test changes necessary to build S.T.Json sources targetting netstandard

* Revert unnecessary change from private to internal.

* Revert props and csproj changes to support netstandard along with test
changes.

* Address PR feedback.

* Revert "Revert props and csproj changes to support netstandard along with test"

This reverts commit dotnet/corefx@7a2f22e127c4ef0476f20bddd64796045f79ddb5.

* Fix code formatting/spacing.

* Invert the ifdef so it is false by default (for source package) and add
comments.

Commit migrated from https://github.com/dotnet/corefx/commit/36893daefdc114306efe86eca4170836bc02ff68

15 files changed:
src/libraries/System.Text.Json/ref/Configurations.props
src/libraries/System.Text.Json/ref/System.Text.Json.csproj
src/libraries/System.Text.Json/src/Configurations.props
src/libraries/System.Text.Json/src/System.Text.Json.csproj
src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs
src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs
src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs
src/libraries/System.Text.Json/tests/Configurations.props
src/libraries/System.Text.Json/tests/FixedSizedBufferWriter.cs
src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj
src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.MultiSegment.cs
src/libraries/System.Text.Json/tests/Utf8JsonReaderTests.cs
src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs

index c701755..ea8f3b8 100644 (file)
@@ -4,6 +4,9 @@
     <BuildConfigurations>
       netcoreapp;
       uap;
+      <!-- Only included for testing and validating that the sources are netstandard compatible. -->
+      <!-- This is meant to help with producing a source package and not to ship a netstandard compatible binary. -->
+      netstandard;
     </BuildConfigurations>
   </PropertyGroup>
 </Project>
\ No newline at end of file
index 27c5d7d..6c66717 100644 (file)
@@ -6,8 +6,11 @@
   <ItemGroup>
     <Compile Include="System.Text.Json.cs" />
   </ItemGroup>
-  <ItemGroup>
+  <ItemGroup Condition="'$(TargetGroup)' != 'netstandard'">
     <ProjectReference Include="..\..\System.Memory\ref\System.Memory.csproj" />
     <ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
   </ItemGroup>
+  <ItemGroup Condition="'$(TargetGroup)' == 'netstandard'">
+    <Reference Include="System.Memory" />
+  </ItemGroup>
 </Project>
index cf6f74d..719ac6f 100644 (file)
@@ -5,6 +5,9 @@
       netcoreapp-Unix;
       netcoreapp-Windows_NT;
       uap-Windows_NT;
+      <!-- Only included for testing and validating that the sources are netstandard compatible. -->
+      <!-- This is meant to help with producing a source package and not to ship a netstandard compatible binary. -->
+      netstandard;
     </BuildConfigurations>
   </PropertyGroup>
 </Project>
index 6d774c2..1d4fd88 100644 (file)
@@ -4,7 +4,11 @@
     <AssemblyName>System.Text.Json</AssemblyName>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile>
-    <Configurations>netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release</Configurations>
+    <Configurations>netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;netstandard-Debug;netstandard-Release</Configurations>
+    <!-- For the inbox library (that is shipping with the product), this should always be true. -->
+    <!-- BUILDING_INBOX_LIBRARY is only false when building for netstandard to validate that the sources are netstandard compatible. -->
+    <!-- This is meant to help with producing a source package and not to ship a netstandard compatible binary. -->
+    <DefineConstants Condition="'$(TargetGroup)' != 'netstandard'">$(DefineConstants);BUILDING_INBOX_LIBRARY</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="System\Text\Json\BitStack.cs" />
     <Compile Include="System\Text\Json\Writer\Utf8JsonWriter.WriteValues.String.cs" />
     <Compile Include="System\Text\Json\Writer\Utf8JsonWriter.WriteValues.UnsignedNumber.cs" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\System.Collections\src\System.Collections.csproj" />
-    <ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj" />
-    <ProjectReference Include="..\..\System.Diagnostics.Tools\src\System.Diagnostics.Tools.csproj" />
+  <ItemGroup Condition="'$(TargetGroup)' != 'netstandard'">
     <ProjectReference Include="..\..\System.Memory\src\System.Memory.csproj" />
-    <ProjectReference Include="..\..\System.Numerics.Vectors\src\System.Numerics.Vectors.csproj" />
-    <ProjectReference Include="..\..\System.Resources.ResourceManager\src\System.Resources.ResourceManager.csproj" />
-    <ProjectReference Include="..\..\System.Runtime\src\System.Runtime.csproj" />
     <ProjectReference Include="..\..\System.Runtime.Extensions\src\System.Runtime.Extensions.csproj" />
-    <ProjectReference Include="..\..\System.Text.Encoding.Extensions\src\System.Text.Encoding.Extensions.csproj" />
   </ItemGroup>
-  <ItemGroup>
+  <ItemGroup Condition="'$(TargetGroup)' != 'netstandard'">
     <ReferenceFromRuntime Include="System.Private.CoreLib" />
   </ItemGroup>
+  <ItemGroup Condition="'$(TargetGroup)' == 'netstandard'">
+    <Reference Include="System.Buffers" />
+    <Reference Include="System.Memory" />
+    <Reference Include="System.Numerics.Vectors" />
+    <Reference Include="System.Runtime.CompilerServices.Unsafe" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
index d8a0ea6..56d2d4e 100644 (file)
@@ -7,7 +7,9 @@ using System.Numerics;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
+#if BUILDING_INBOX_LIBRARY
 using Internal.Runtime.CompilerServices;
+#endif
 
 namespace System.Text.Json
 {
index 4fee0c9..066757c 100644 (file)
@@ -33,8 +33,23 @@ namespace System.Text.Json
 
             ReadOnlySpan<byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;
 
+#if BUILDING_INBOX_LIBRARY
             // TODO: https://github.com/dotnet/corefx/issues/33292
             return s_utf8Encoding.GetString(span);
+#else
+            if (span.IsEmpty)
+            {
+                return string.Empty;
+            }
+            unsafe
+            {
+                fixed (byte* bytePtr = span)
+                {
+                    // TODO: https://github.com/dotnet/corefx/issues/33292
+                    return s_utf8Encoding.GetString(bytePtr, span.Length);
+                }
+            }
+#endif
         }
 
         /// <summary>
index 18e9462..1537cab 100644 (file)
@@ -36,7 +36,7 @@ namespace System.Text.Json
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         };
 
-        private static readonly char[] s_hexFormat = { 'x', '4' };
+        private const string HexFormatString = "x4";
         private static readonly StandardFormat s_hexStandardFormat = new StandardFormat('x', 4);
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -112,12 +112,11 @@ namespace System.Text.Json
 
         private static int EscapeNextBytes(ReadOnlySpan<byte> value, Span<byte> destination, ref int written)
         {
-            SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out Rune rune);
+            SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out int scalar);
             if (status != SequenceValidity.WellFormed)
                 ThrowHelper.ThrowArgumentException_InvalidUTF8(value);
 
             destination[written++] = (byte)'\\';
-            int scalar = rune.Value;
             switch (scalar)
             {
                 case JsonConstants.LineFeed:
@@ -202,7 +201,9 @@ namespace System.Text.Json
         private static bool IsLowWordSurrogate(uint @char)
             => (@char & 0xF800U) == 0xD800U;
 
-        public static SequenceValidity PeekFirstSequence(ReadOnlySpan<byte> data, out int numBytesConsumed, out Rune rune)
+        // We can't use the type Rune since it is not available on netstandard2.0
+        // To avoid extensive ifdefs and for simplicity, just using an int to reprepsent the scalar value, instead.
+        public static SequenceValidity PeekFirstSequence(ReadOnlySpan<byte> data, out int numBytesConsumed, out int rune)
         {
             // This method is implemented to match the behavior of System.Text.Encoding.UTF8 in terms of
             // how many bytes it consumes when reporting invalid sequences. The behavior is as follows:
@@ -217,7 +218,8 @@ namespace System.Text.Json
             // - Multi-byte sequences which are improperly terminated (no continuation byte when one is
             //   expected) are reported as invalid sequences up to and including the last seen continuation byte.
 
-            rune = Rune.ReplacementChar;
+            Debug.Assert(IsValidUnicodeScalar(ReplacementChar));
+            rune = ReplacementChar;
 
             if (data.IsEmpty)
             {
@@ -231,7 +233,8 @@ namespace System.Text.Json
             if (IsAsciiValue(firstByte))
             {
                 // ASCII byte = well-formed one-byte sequence.
-                rune = new Rune(firstByte);
+                Debug.Assert(IsValidUnicodeScalar(firstByte));
+                rune = firstByte;
                 numBytesConsumed = 1;
                 return SequenceValidity.WellFormed;
             }
@@ -262,7 +265,9 @@ namespace System.Text.Json
             if (firstByte < (byte)0xE0U)
             {
                 // Well-formed two-byte sequence.
-                rune = new Rune((((uint)firstByte & 0x1FU) << 6) | ((uint)secondByte & 0x3FU));
+                uint scalar = (((uint)firstByte & 0x1FU) << 6) | ((uint)secondByte & 0x3FU);
+                Debug.Assert(IsValidUnicodeScalar(scalar));
+                rune = (int)scalar;
                 numBytesConsumed = 2;
                 return SequenceValidity.WellFormed;
             }
@@ -292,7 +297,8 @@ namespace System.Text.Json
                     {
                         // Well-formed three-byte sequence.
                         scalar |= (uint)thirdByte & 0x3FU;
-                        rune = new Rune(scalar);
+                        Debug.Assert(IsValidUnicodeScalar(scalar));
+                        rune = (int)scalar;
                         numBytesConsumed = 3;
                         return SequenceValidity.WellFormed;
                     }
@@ -309,6 +315,7 @@ namespace System.Text.Json
                 // Need to check for overlong or out-of-range sequences.
 
                 uint scalar = (((uint)firstByte & 0x07U) << 18) | (((uint)secondByte & 0x3FU) << 12);
+                Debug.Assert(IsValidUnicodeScalar(scalar));
                 if (!IsInRangeInclusive(scalar, 0x10000U, 0x10FFFFU))
                 {
                     goto OverlongOutOfRangeOrSurrogateSequence;
@@ -340,7 +347,8 @@ namespace System.Text.Json
                             {
                                 // Well-formed four-byte sequence.
                                 scalar |= (((uint)thirdByte & 0x3FU) << 6) | ((uint)fourthByte & 0x3FU);
-                                rune = new Rune(scalar);
+                                Debug.Assert(IsValidUnicodeScalar(scalar));
+                                rune = (int)scalar;
                                 numBytesConsumed = 4;
                                 return SequenceValidity.WellFormed;
                             }
@@ -451,16 +459,24 @@ namespace System.Text.Json
                     break;
                 default:
                     destination[written++] = 'u';
-                    firstChar.TryFormat(destination.Slice(written), out int charsWritten, s_hexFormat);
+#if BUILDING_INBOX_LIBRARY
+                    firstChar.TryFormat(destination.Slice(written), out int charsWritten, HexFormatString);
                     Debug.Assert(charsWritten == 4);
                     written += charsWritten;
+#else
+                    written = WriteHex(firstChar, destination, written);
+#endif
                     if (nextChar != -1)
                     {
                         destination[written++] = '\\';
                         destination[written++] = 'u';
-                        nextChar.TryFormat(destination.Slice(written), out charsWritten, s_hexFormat);
+#if BUILDING_INBOX_LIBRARY
+                        nextChar.TryFormat(destination.Slice(written), out charsWritten, HexFormatString);
                         Debug.Assert(charsWritten == 4);
                         written += charsWritten;
+#else
+                        written = WriteHex(nextChar, destination, written);
+#endif
                     }
                     break;
             }
@@ -471,5 +487,46 @@ namespace System.Text.Json
         {
             return (uint)(ch - start) <= (uint)(end - start);
         }
+
+        /// <summary>
+        /// A scalar that represents the Unicode replacement character U+FFFD.
+        /// </summary>
+        private const int ReplacementChar = 0xFFFD;
+
+        /// <summary>
+        /// Returns <see langword="true"/> iff <paramref name="value"/> is a valid Unicode scalar
+        /// value, i.e., is in [ U+0000..U+D7FF ], inclusive; or [ U+E000..U+10FFFF ], inclusive.
+        /// </summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private static bool IsValidUnicodeScalar(uint value)
+        {
+            // By XORing the incoming value with 0xD800, surrogate code points
+            // are moved to the range [ U+0000..U+07FF ], and all valid scalar
+            // values are clustered into the single range [ U+0800..U+10FFFF ],
+            // which allows performing a single fast range check.
+
+            return IsInRangeInclusive(value ^ 0xD800U, 0x800U, 0x10FFFFU);
+        }
+
+#if !BUILDING_INBOX_LIBRARY
+        private static int WriteHex(int value, Span<char> destination, int written)
+        {
+            destination[written++] = (char)Int32LsbToHexDigit(value >> 12);
+            destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 8) & 0xFU));
+            destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 4) & 0xFU));
+            destination[written++] = (char)Int32LsbToHexDigit((int)(value & 0xFU));
+            return written;
+        }
+
+        /// <summary>
+        /// Converts a number 0 - 15 to its associated hex character '0' - 'f' as byte.
+        /// </summary>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private static byte Int32LsbToHexDigit(int value)
+        {
+            Debug.Assert(value < 16);
+            return (byte)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
+        }
+#endif
     }
 }
index 962731e..7ca5e47 100644 (file)
@@ -63,15 +63,27 @@ namespace System.Text.Json
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static void ValidateDouble(double value)
         {
+#if BUILDING_INBOX_LIBRARY
             if (!double.IsFinite(value))
+#else
+            if (double.IsNaN(value) || double.IsInfinity(value))
+#endif
+            {
                 ThrowHelper.ThrowArgumentException_ValueNotSupported();
+            }
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static void ValidateSingle(float value)
         {
+#if BUILDING_INBOX_LIBRARY
             if (!float.IsFinite(value))
+#else
+            if (float.IsNaN(value) || float.IsInfinity(value))
+#endif
+            {
                 ThrowHelper.ThrowArgumentException_ValueNotSupported();
+            }
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
index 65763c8..6e3fa56 100644 (file)
@@ -75,7 +75,7 @@ namespace System.Text.Json
         /// be captured by the caller and passed back in to the <see cref="Utf8JsonWriter"/> ctor with more data.
         /// </summary>
         /// <exception cref="InvalidOperationException">
-        /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the <see cref="IBufferWriter{T}" />.      
+        /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the <see cref="IBufferWriter{Byte}" />.   
         /// Getting the state for creating a new <see cref="Utf8JsonWriter"/> without first committing the data that has been written  
         /// would result in an inconsistent state. Call Flush before getting the current state.        
         /// </exception>
@@ -106,11 +106,11 @@ namespace System.Text.Json
         /// <summary>
         /// Constructs a new <see cref="Utf8JsonWriter"/> instance with a specified <paramref name="bufferWriter"/>.
         /// </summary>
-        /// <param name="bufferWriter">An instance of <see cref="IBufferWriter{T}" /> used as a destination for writing JSON text into.</param>
+        /// <param name="bufferWriter">An instance of <see cref="IBufferWriter{Byte}" /> used as a destination for writing JSON text into.</param>
         /// <param name="state">If this is the first call to the ctor, pass in a default state. Otherwise,
         /// capture the state from the previous instance of the <see cref="Utf8JsonWriter"/> and pass that back.</param>
         /// <exception cref="ArgumentNullException">
-        /// Thrown when the instance of <see cref="IBufferWriter{T}" /> that is passed in is null.
+        /// Thrown when the instance of <see cref="IBufferWriter{Byte}" /> that is passed in is null.
         /// </exception>
         /// <remarks>
         /// Since this type is a ref struct, it is a stack-only type and all the limitations of ref structs apply to it.
@@ -142,7 +142,7 @@ namespace System.Text.Json
         }
 
         /// <summary>
-        /// Advances the underlying <see cref="IBufferWriter{T}" /> based on what has been written so far.
+        /// Advances the underlying <see cref="IBufferWriter{Byte}" /> based on what has been written so far.
         /// </summary>
         /// <param name="isFinalBlock">Let's the writer know whether more data will be written. This is used to validate
         /// that the JSON written so far is structurally valid if no more data is to follow.</param>
index d8cfd38..f338d07 100644 (file)
@@ -4,6 +4,9 @@
     <BuildConfigurations>
       netcoreapp;
       uap-Windows_NT;
+      <!-- Only included for testing and validating that the sources are netstandard compatible. -->
+      <!-- This is meant to help with producing a source package and not to ship a netstandard compatible binary. -->
+      netstandard;
     </BuildConfigurations>
   </PropertyGroup>
 </Project>
index 22f29ad..79e7c34 100644 (file)
@@ -24,7 +24,7 @@ namespace System.Text.Json.Tests
 
         public Span<byte> Free => _buffer.AsSpan(_count);
 
-        public Span<byte> Formatted => _buffer.AsSpan(0, _count);
+        public byte[] Formatted => _buffer.AsSpan(0, _count).ToArray();
 
         public Memory<byte> GetMemory(int minimumLength = 0) => _buffer.AsMemory(_count);
 
index 7ca7174..4ff7c09 100644 (file)
@@ -1,7 +1,7 @@
 ï»¿<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <ProjectGuid>{5F553243-042C-45C0-8E49-C739131E11C3}</ProjectGuid>
-    <Configurations>netcoreapp-Debug;netcoreapp-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release</Configurations>
+    <Configurations>netcoreapp-Debug;netcoreapp-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;netstandard-Debug;netstandard-Release</Configurations>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="ArrayBufferWriter.cs" />
     <Compile Include="..\src\System\Text\Json\BitStack.cs" Link="BitStack.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="System.Collections" />
-    <Reference Include="System.Diagnostics.Tools" />
-    <Reference Include="System.Resources.ResourceManager" />
-  </ItemGroup>
-  <ItemGroup>
     <ReferenceFromRuntime Include="Newtonsoft.Json" />
   </ItemGroup>
 </Project>
\ No newline at end of file
index b05eaab..c036b76 100644 (file)
@@ -47,7 +47,7 @@ namespace System.Text.Json.Tests
             {
                 var utf8JsonReader = new Utf8JsonReader(sequence, isFinalBlock: true, default);
                 byte[] resultSequence = JsonTestHelper.ReaderLoop(dataUtf8.Length, out int length, ref utf8JsonReader);
-                string actualStrSequence = Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+                string actualStrSequence = Encoding.UTF8.GetString(resultSequence, 0, length);
                 Assert.Equal(expectedStr, actualStrSequence);
                 return;
             }
@@ -56,13 +56,13 @@ namespace System.Text.Json.Tests
             {
                 var utf8JsonReader = new Utf8JsonReader(sequence.Slice(0, j), isFinalBlock: false, default);
                 byte[] resultSequence = JsonTestHelper.ReaderLoop(dataUtf8.Length, out int length, ref utf8JsonReader);
-                string actualStrSequence = Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+                string actualStrSequence = Encoding.UTF8.GetString(resultSequence, 0, length);
 
                 long consumed = utf8JsonReader.BytesConsumed;
                 Assert.Equal(consumed, utf8JsonReader.CurrentState.BytesConsumed);
                 utf8JsonReader = new Utf8JsonReader(sequence.Slice(consumed), isFinalBlock: true, utf8JsonReader.CurrentState);
                 resultSequence = JsonTestHelper.ReaderLoop(dataUtf8.Length, out length, ref utf8JsonReader);
-                actualStrSequence += Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+                actualStrSequence += Encoding.UTF8.GetString(resultSequence, 0, length);
                 string message = $"Expected consumed: {dataUtf8.Length - consumed}, Actual consumed: {utf8JsonReader.BytesConsumed}, Index: {j}";
                 Assert.Equal(utf8JsonReader.BytesConsumed, utf8JsonReader.CurrentState.BytesConsumed);
                 Assert.True(dataUtf8.Length - consumed == utf8JsonReader.BytesConsumed, message);
@@ -292,7 +292,7 @@ namespace System.Text.Json.Tests
             while (json.Read())
             {
                 if (json.TokenType == JsonTokenType.Number || json.TokenType == JsonTokenType.Comment || json.TokenType == JsonTokenType.PropertyName)
-                    builder.Append(Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan));
+                    builder.Append(Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan.ToArray()));
             }
 
             Assert.Equal(expectedWithComments, builder.ToString());
@@ -304,7 +304,7 @@ namespace System.Text.Json.Tests
             while (json.Read())
             {
                 if (json.TokenType == JsonTokenType.Number || json.TokenType == JsonTokenType.Comment || json.TokenType == JsonTokenType.PropertyName)
-                    builder.Append(Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan));
+                    builder.Append(Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan.ToArray()));
             }
 
             Assert.Equal(expectedWithoutComments, builder.ToString());
@@ -338,7 +338,7 @@ namespace System.Text.Json.Tests
                 {
                     // Check if the TokenType is a primitive "value", i.e. String, Number, True, False, and Null
                     Assert.True(json.TokenType >= JsonTokenType.String && json.TokenType <= JsonTokenType.Null);
-                    Assert.Equal(expectedString, Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan));
+                    Assert.Equal(expectedString, Encoding.UTF8.GetString(json.HasValueSequence ? json.ValueSequence.ToArray() : json.ValueSpan.ToArray()));
                 }
 
                 Assert.Equal(json.BytesConsumed, json.CurrentState.BytesConsumed);
index b77faa2..fc51641 100644 (file)
@@ -39,10 +39,10 @@ namespace System.Text.Json.Tests
             SpanSequenceStatesAreEqual(dataUtf8);
 
             byte[] result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out int length);
-            string actualStr = Encoding.UTF8.GetString(result.AsSpan(0, length));
+            string actualStr = Encoding.UTF8.GetString(result, 0, length);
 
             byte[] resultSequence = JsonTestHelper.SequenceReturnBytesHelper(dataUtf8, out length);
-            string actualStrSequence = Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+            string actualStrSequence = Encoding.UTF8.GetString(resultSequence, 0, length);
 
             Stream stream = new MemoryStream(dataUtf8);
             TextReader reader = new StreamReader(stream, Encoding.UTF8, false, 1024, true);
@@ -62,17 +62,17 @@ namespace System.Text.Json.Tests
             }
 
             result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out length, JsonCommentHandling.Skip);
-            actualStr = Encoding.UTF8.GetString(result.AsSpan(0, length));
+            actualStr = Encoding.UTF8.GetString(result, 0, length);
             resultSequence = JsonTestHelper.SequenceReturnBytesHelper(dataUtf8, out length, JsonCommentHandling.Skip);
-            actualStrSequence = Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+            actualStrSequence = Encoding.UTF8.GetString(resultSequence, 0, length);
 
             Assert.Equal(expectedStr, actualStr);
             Assert.Equal(expectedStr, actualStrSequence);
 
             result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out length, JsonCommentHandling.Allow);
-            actualStr = Encoding.UTF8.GetString(result.AsSpan(0, length));
+            actualStr = Encoding.UTF8.GetString(result, 0, length);
             resultSequence = JsonTestHelper.SequenceReturnBytesHelper(dataUtf8, out length, JsonCommentHandling.Allow);
-            actualStrSequence = Encoding.UTF8.GetString(resultSequence.AsSpan(0, length));
+            actualStrSequence = Encoding.UTF8.GetString(resultSequence, 0, length);
 
             Assert.Equal(expectedStr, actualStr);
             Assert.Equal(expectedStr, actualStrSequence);
@@ -107,7 +107,8 @@ namespace System.Text.Json.Tests
             byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
 
             byte[] result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out int outputLength);
-            Span<byte> outputSpan = new byte[outputLength];
+            var outputArray = new byte[outputLength];
+            Span<byte> outputSpan = outputArray;
 
             Stream stream = new MemoryStream(dataUtf8);
             TextReader reader = new StreamReader(stream, Encoding.UTF8, false, 1024, true);
@@ -136,7 +137,7 @@ namespace System.Text.Json.Tests
                     Assert.Equal(json.BytesConsumed, json.CurrentState.BytesConsumed);
 
                     Assert.Equal(outputSpan.Length, written);
-                    string actualStr = Encoding.UTF8.GetString(outputSpan);
+                    string actualStr = Encoding.UTF8.GetString(outputArray);
                     Assert.Equal(expectedStr, actualStr);
                 }
                 else
@@ -167,7 +168,7 @@ namespace System.Text.Json.Tests
                         Assert.Equal(json.BytesConsumed, json.CurrentState.BytesConsumed);
 
                         Assert.Equal(outputSpan.Length, written);
-                        string actualStr = Encoding.UTF8.GetString(outputSpan);
+                        string actualStr = Encoding.UTF8.GetString(outputArray);
                         Assert.Equal(expectedStr, actualStr);
                     }
                 }
@@ -295,7 +296,7 @@ namespace System.Text.Json.Tests
             // Set the max depth sufficiently large to account for the depth padding.
             byte[] result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out int outputLength, maxDepth: 256);
             Span<byte> outputSpan = new byte[outputLength];
-            string actualStr = Encoding.UTF8.GetString(result.AsSpan(0, outputLength));
+            string actualStr = Encoding.UTF8.GetString(result, 0, outputLength);
 
             Stream stream = new MemoryStream(dataUtf8);
             TextReader reader = new StreamReader(stream, Encoding.UTF8, false, 1024, true);
@@ -485,7 +486,7 @@ namespace System.Text.Json.Tests
                     while (json.Read())
                     {
                         if (json.TokenType == JsonTokenType.Number || json.TokenType == JsonTokenType.Comment || json.TokenType == JsonTokenType.PropertyName)
-                            builder.Append(Encoding.UTF8.GetString(json.ValueSpan));
+                            builder.Append(Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                     }
 
                     long consumed = json.BytesConsumed;
@@ -494,7 +495,7 @@ namespace System.Text.Json.Tests
                     while (json.Read())
                     {
                         if (json.TokenType == JsonTokenType.Number || json.TokenType == JsonTokenType.Comment || json.TokenType == JsonTokenType.PropertyName)
-                            builder.Append(Encoding.UTF8.GetString(json.ValueSpan));
+                            builder.Append(Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                     }
                     Assert.Equal(data.Length - consumed, json.BytesConsumed);
                     Assert.Equal(json.BytesConsumed, json.CurrentState.BytesConsumed);
@@ -578,12 +579,12 @@ namespace System.Text.Json.Tests
         {
             byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
             byte[] result = JsonTestHelper.ReturnBytesHelper(dataUtf8, out int length, commentHandling);
-            string actualStr = Encoding.UTF8.GetString(result.AsSpan(0, length));
+            string actualStr = Encoding.UTF8.GetString(result, 0, length);
 
             Assert.Equal(expectedStr, actualStr);
 
             result = JsonTestHelper.SequenceReturnBytesHelper(dataUtf8, out length, commentHandling);
-            actualStr = Encoding.UTF8.GetString(result.AsSpan(0, length));
+            actualStr = Encoding.UTF8.GetString(result, 0, length);
 
             Assert.Equal(expectedStr, actualStr);
 
@@ -610,7 +611,7 @@ namespace System.Text.Json.Tests
                     {
                         // Check if the TokenType is a primitive "value", i.e. String, Number, True, False, and Null
                         Assert.True(json.TokenType >= JsonTokenType.String && json.TokenType <= JsonTokenType.Null);
-                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan));
+                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                     }
 
                     long consumed = json.BytesConsumed;
@@ -620,7 +621,7 @@ namespace System.Text.Json.Tests
                     {
                         // Check if the TokenType is a primitive "value", i.e. String, Number, True, False, and Null
                         Assert.True(json.TokenType >= JsonTokenType.String && json.TokenType <= JsonTokenType.Null);
-                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan));
+                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                     }
                     Assert.Equal(dataUtf8.Length - consumed, json.BytesConsumed);
                     Assert.Equal(json.BytesConsumed, json.CurrentState.BytesConsumed);
@@ -850,8 +851,8 @@ namespace System.Text.Json.Tests
                     catch (JsonReaderException ex)
                     {
                         string errorMessage = $"expectedLineNumber: {expectedlineNumber} | actual: {ex.LineNumber} | index: {i} | option: {commentHandling}";
-                        string firstSegmentString = Encoding.UTF8.GetString(dataUtf8.AsSpan(0, i));
-                        string secondSegmentString = Encoding.UTF8.GetString(dataUtf8.AsSpan(i));
+                        string firstSegmentString = Encoding.UTF8.GetString(dataUtf8, 0, i);
+                        string secondSegmentString = Encoding.UTF8.GetString(dataUtf8, i, dataUtf8.Length - i);
                         errorMessage += " | " + firstSegmentString + " | " + secondSegmentString;
                         Assert.True(expectedlineNumber == ex.LineNumber, errorMessage);
                         errorMessage = $"expectedBytePosition: {expectedBytePosition} | actual: {ex.BytePositionInLine} | index: {i} | option: {commentHandling}";
@@ -915,7 +916,7 @@ namespace System.Text.Json.Tests
                         foundComment = true;
                         indexAfterFirstComment = json.BytesConsumed;
                         Assert.Equal(indexAfterFirstComment, json.CurrentState.BytesConsumed);
-                        string actualComment = Encoding.UTF8.GetString(json.ValueSpan); // TODO: https://github.com/dotnet/corefx/issues/33347
+                        string actualComment = Encoding.UTF8.GetString(json.ValueSpan.ToArray()); // TODO: https://github.com/dotnet/corefx/issues/33347
                         Assert.Equal(expectedComment, actualComment);
                         break;
                 }
@@ -981,7 +982,7 @@ namespace System.Text.Json.Tests
                         foundComment = true;
                         indexAfterFirstComment = json.BytesConsumed;
                         Assert.Equal(indexAfterFirstComment, json.CurrentState.BytesConsumed);
-                        string actualComment = Encoding.UTF8.GetString(json.ValueSpan);
+                        string actualComment = Encoding.UTF8.GetString(json.ValueSpan.ToArray());
                         Assert.Equal(expectedComment, actualComment);
                         break;
                 }
@@ -1007,7 +1008,7 @@ namespace System.Text.Json.Tests
                             foundComment = true;
                             indexAfterFirstComment = jsonSlice.BytesConsumed;
                             Assert.Equal(indexAfterFirstComment, jsonSlice.CurrentState.BytesConsumed);
-                            string actualComment = Encoding.UTF8.GetString(jsonSlice.ValueSpan);
+                            string actualComment = Encoding.UTF8.GetString(jsonSlice.ValueSpan.ToArray());
                             Assert.Equal(expectedComment, actualComment);
                             break;
                     }
@@ -1030,7 +1031,7 @@ namespace System.Text.Json.Tests
                                 foundComment = true;
                                 indexAfterFirstComment = jsonSlice.BytesConsumed;
                                 Assert.Equal(indexAfterFirstComment, jsonSlice.CurrentState.BytesConsumed);
-                                string actualComment = Encoding.UTF8.GetString(jsonSlice.ValueSpan);
+                                string actualComment = Encoding.UTF8.GetString(jsonSlice.ValueSpan.ToArray());
                                 Assert.Equal(expectedComment, actualComment);
                                 break;
                         }
@@ -1549,10 +1550,10 @@ namespace System.Text.Json.Tests
                 switch (json.TokenType)
                 {
                     case JsonTokenType.Null:
-                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan));
+                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                         break;
                     case JsonTokenType.Number:
-                        if (json.ValueSpan.Contains((byte)'.'))
+                        if (json.ValueSpan.IndexOf((byte)'.') != -1)
                         {
                             Assert.True(json.TryGetDoubleValue(out double numberValue));
                             // Use InvariantCulture to format the numbers to make sure they retain the decimal point '.'
@@ -1627,11 +1628,11 @@ namespace System.Text.Json.Tests
                 switch (json.TokenType)
                 {
                     case JsonTokenType.Null:
-                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan));
+                        Assert.Equal(expectedString, Encoding.UTF8.GetString(json.ValueSpan.ToArray()));
                         foundPrimitiveValue = true;
                         break;
                     case JsonTokenType.Number:
-                        if (json.ValueSpan.Contains((byte)'.'))
+                        if (json.ValueSpan.IndexOf((byte)'.') != -1)
                         {
                             Assert.True(json.TryGetDoubleValue(out double numberValue));
                             Assert.Equal(expectedString, numberValue.ToString(CultureInfo.InvariantCulture));
index 43e78ea..1f05b84 100644 (file)
@@ -2490,7 +2490,7 @@ namespace System.Text.Json.Tests
                 var output = new ArrayBufferWriter(1024);
                 var jsonUtf8 = new Utf8JsonWriter(output, state);
 
-                ReadOnlySpan<char> keyUtf16 = keyString;
+                ReadOnlySpan<char> keyUtf16 = keyString.AsSpan();
                 ReadOnlySpan<byte> keyUtf8 = Encoding.UTF8.GetBytes(keyString);
 
                 jsonUtf8.WriteStartObject();
@@ -2652,7 +2652,7 @@ namespace System.Text.Json.Tests
 
             var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation });
 
-            ReadOnlySpan<char> keyUtf16 = keyString;
+            ReadOnlySpan<char> keyUtf16 = keyString.AsSpan();
             ReadOnlySpan<byte> keyUtf8 = Encoding.UTF8.GetBytes(keyString);
 
             for (int i = 0; i < 6; i++)
@@ -2745,7 +2745,7 @@ namespace System.Text.Json.Tests
 
             var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation });
 
-            ReadOnlySpan<char> keyUtf16 = keyString;
+            ReadOnlySpan<char> keyUtf16 = keyString.AsSpan();
             ReadOnlySpan<byte> keyUtf8 = Encoding.UTF8.GetBytes(keyString);
 
             for (int i = 0; i < 6; i++)
@@ -2838,7 +2838,7 @@ namespace System.Text.Json.Tests
 
             var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation });
 
-            ReadOnlySpan<char> keyUtf16 = keyString;
+            ReadOnlySpan<char> keyUtf16 = keyString.AsSpan();
             ReadOnlySpan<byte> keyUtf8 = Encoding.UTF8.GetBytes(keyString);
 
             for (int i = 0; i < 6; i++)