public static void TestTextEqualsLargeMatch()
        {
            var jsonChars = new char[320];  // Some value larger than 256 (stack threshold)

            jsonChars.AsSpan().Fill('a');
            byte[] lookup = Encoding.UTF8.GetBytes(jsonChars);

            ReadOnlySpan <char> escapedA = new char[6] {
                '\\', 'u', '0', '0', '6', '1'
            };

            ReadOnlySpan <byte> lookupSpan  = lookup.AsSpan(0, lookup.Length - escapedA.Length + 1); // remove extra characters that were replaced by escaped bytes
            Span <char>         lookupChars = new char[jsonChars.Length];

            jsonChars.CopyTo(lookupChars);
            lookupChars = lookupChars.Slice(0, lookupChars.Length - escapedA.Length + 1);

            // Replacing 'a' with '\u0061', so a net change of 5.
            // escapedA.Length - 1 = 6 - 1 = 5
            for (int i = 0; i < jsonChars.Length - escapedA.Length + 1; i++)
            {
                jsonChars.AsSpan().Fill('a');
                escapedA.CopyTo(jsonChars.AsSpan(i));
                string jsonString = "\"" + new string(jsonChars) + "\"";
                byte[] utf8Data   = Encoding.UTF8.GetBytes(jsonString);

                bool found = false;

                var json = new Utf8JsonReader(utf8Data, isFinalBlock: true, state: default);
                while (json.Read())
                {
                    if (json.TokenType == JsonTokenType.String)
                    {
                        if (json.ValueTextEquals(lookupSpan) &&
                            json.ValueTextEquals(lookupChars) &&
                            json.ValueTextEquals(new string(lookupChars.ToArray())))
                        {
                            found = true;
                            break;
                        }
                    }
                }

                Assert.True(found, $"Json String: {jsonString}");

                ReadOnlySequence <byte> sequence = JsonTestHelper.GetSequence(utf8Data, 1);
                found = false;

                json = new Utf8JsonReader(sequence, isFinalBlock: true, state: default);
                while (json.Read())
                {
                    if (json.TokenType == JsonTokenType.String)
                    {
                        if (json.ValueTextEquals(lookupSpan) &&
                            json.ValueTextEquals(lookupChars) &&
                            json.ValueTextEquals(new string(lookupChars.ToArray())))
                        {
                            found = true;
                            break;
                        }
                    }
                }

                Assert.True(found, $"Json String: {jsonString}  | Look up: {Encoding.UTF8.GetString(lookupSpan.ToArray())}");
            }
        }
        public static void CheckOnlyOneOfValueSpanOrSequenceIsSet(int testCase, string jsonString)
        {
            byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);

            bool[] expectedHasValueSequence      = null;
            bool[] expectedHasValueSequenceSkip  = null;
            bool[] expectedHasValueSequenceAllow = null;

            ReadOnlySequence <byte> sequence;

            switch (testCase)
            {
            case 0:
                Debug.Assert(dataUtf8.Length == 95);
                byte[][] buffers = new byte[6][];
                buffers[0] = dataUtf8.AsSpan(0, 10).ToArray();
                buffers[1] = dataUtf8.AsSpan(10, 28).ToArray();
                buffers[2] = dataUtf8.AsSpan(38, 32).ToArray();
                buffers[3] = dataUtf8.AsSpan(70, 23).ToArray();
                buffers[4] = dataUtf8.AsSpan(93, 1).ToArray();
                buffers[5] = dataUtf8.AsSpan(94, 1).ToArray();
                sequence   = BufferFactory.Create(buffers);
                expectedHasValueSequence = new bool [] { false, true, false, false, true, false, true, false, false, false, false, false };
                break;

            case 1:
                Debug.Assert(dataUtf8.Length == 97);
                buffers    = new byte[7][];
                buffers[0] = dataUtf8.AsSpan(0, 39).ToArray();
                buffers[1] = dataUtf8.AsSpan(39, 22).ToArray();
                buffers[2] = dataUtf8.AsSpan(61, 18).ToArray();
                buffers[3] = dataUtf8.AsSpan(79, 7).ToArray();
                buffers[4] = dataUtf8.AsSpan(86, 7).ToArray();
                buffers[5] = dataUtf8.AsSpan(93, 3).ToArray();
                buffers[6] = dataUtf8.AsSpan(96, 1).ToArray();
                sequence   = BufferFactory.Create(buffers);
                expectedHasValueSequence = new bool[] { false, false, false, false, false, true, true, false, true, true, true, false, false, false };
                break;

            case 2:
                Debug.Assert(dataUtf8.Length == 90);
                buffers    = new byte[5][];
                buffers[0] = dataUtf8.AsSpan(0, 36).ToArray();
                buffers[1] = dataUtf8.AsSpan(36, 13).ToArray();
                buffers[2] = dataUtf8.AsSpan(49, 30).ToArray();
                buffers[3] = dataUtf8.AsSpan(79, 9).ToArray();
                buffers[4] = dataUtf8.AsSpan(88, 2).ToArray();
                sequence   = BufferFactory.Create(buffers);
                expectedHasValueSequenceSkip  = new bool[] { false, false, false, true, false, false };
                expectedHasValueSequenceAllow = new bool[] { false, false, false, true, true, true, false, false };
                break;

            default:
                return;
            }

            foreach (JsonCommentHandling commentHandling in Enum.GetValues(typeof(JsonCommentHandling)))
            {
                if (commentHandling == JsonCommentHandling.Disallow && testCase == 2)
                {
                    continue;
                }
                var state = new JsonReaderState(options: new JsonReaderOptions {
                    CommentHandling = commentHandling
                });
                var json = new Utf8JsonReader(sequence, isFinalBlock: true, state);

                int index = 0;

                while (json.Read())
                {
                    if (testCase == 0 || testCase == 1)
                    {
                        Assert.True(expectedHasValueSequence[index] == json.HasValueSequence, $"{commentHandling}, {testCase}, {index}, {json.HasValueSequence}");
                    }
                    else
                    {
                        if (commentHandling == JsonCommentHandling.Skip)
                        {
                            Assert.True(expectedHasValueSequenceSkip[index] == json.HasValueSequence, $"{commentHandling}, {testCase}, {index}, {json.HasValueSequence}");
                        }
                        else
                        {
                            Assert.True(expectedHasValueSequenceAllow[index] == json.HasValueSequence, $"{commentHandling}, {testCase}, {index}, {json.HasValueSequence}");
                        }
                    }
                    if (json.HasValueSequence)
                    {
                        Assert.True(json.ValueSpan == default, $"Escaped ValueSpan to be empty when HasValueSequence is true. Test case: {testCase}");
                        Assert.False(json.ValueSequence.IsEmpty, $"Escaped ValueSequence to not be empty when HasValueSequence is true. Test case: {testCase}");
                    }
                    else
                    {
                        Assert.True(json.ValueSequence.IsEmpty, $"Escaped ValueSequence to be empty when HasValueSequence is false. Test case: {testCase}");
                        Assert.False(json.ValueSpan == default, $"Escaped ValueSpan to not be empty when HasValueSequence is false. Test case: {testCase}");
                    }

                    index++;
                }
            }
        }
Ejemplo n.º 3
0
 public Span <byte> GetSpan(int minimumLength = 0) => _buffer.AsSpan(_count);