예제 #1
0
 public static bool TryWrite(Span <byte> output, Sha256 hash, Utf8Span verb, Utf8Span canonicalizedResource, DateTime utc, out int bytesWritten)
 {
     try
     {
         var writer = BufferWriter.Create(output);
         writer.WriteLine(verb);
         writer.Write(s_emptyHeaders);
         writer.WriteLine(utc, 'R');
         writer.Write(canonicalizedResource);
         hash.Append(writer.Written);
         writer.WrittenCount = 0;
         writer.WriteBytes(hash, s_toBase64);
         bytesWritten = writer.WrittenCount;
         return(true);
     }
     catch (BufferWriter.BufferTooSmallException)
     {
         bytesWritten = 0;
         return(false);
     }
 }
        /// <summary>
        /// Tries to get the <see cref="ImmutableKeyValue"/> with the specified key
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool TryGet(Utf8Span propertyName, out ImmutableKeyValue value)
        {
            var record = Record;

            if (record.Type != KeyValueType.None)
            {
                throw new InvalidOperationException();
            }

            foreach (ImmutableKeyValue keyValue in this)
            {
                if (keyValue.Utf8Key == propertyName)
                {
                    value = keyValue;
                    return(true);
                }
            }

            value = default;
            return(false);
        }
예제 #3
0
        public static void Trim(string input)
        {
            // Arrange

            using BoundedUtf8Span boundedSpan = new BoundedUtf8Span(input);
            Utf8Span span = boundedSpan.Span;

            // Act

            Utf8Span trimmed = span.Trim();

            // Assert
            // Compute the trim manually and ensure it matches the trimmed span's characteristics.

            ReadOnlySpan <byte> utf8Bytes = span.Bytes;

            while (!utf8Bytes.IsEmpty)
            {
                OperationStatus status = Rune.DecodeFromUtf8(utf8Bytes, out Rune decodedRune, out int bytesConsumed);
                Assert.Equal(OperationStatus.Done, status);

                if (!Rune.IsWhiteSpace(decodedRune))
                {
                    break;
                }

                utf8Bytes = utf8Bytes.Slice(bytesConsumed);
            }
            while (!utf8Bytes.IsEmpty)
            {
                OperationStatus status = Rune.DecodeLastFromUtf8(utf8Bytes, out Rune decodedRune, out int bytesConsumed);
                Assert.Equal(OperationStatus.Done, status);

                if (!Rune.IsWhiteSpace(decodedRune))
                {
                    break;
                }

                utf8Bytes = utf8Bytes[..^ bytesConsumed];
예제 #4
0
        public void CopmareTo(string left, string right, int expected)
        {
            Utf8Span   leftSpan    = new Utf8Span(left);
            Utf8Span   rightSpan   = new Utf8Span(right);
            Utf8String leftString  = new Utf8String(left);
            Utf8String rightString = new Utf8String(right);

            Assert.Equal(expected, leftSpan.CompareTo(rightSpan));
            Assert.Equal(expected, leftSpan.CompareTo(rightString));
            Assert.Equal(expected, leftSpan.CompareTo(right));

            Assert.Equal(expected, leftString.CompareTo(rightSpan));
            Assert.Equal(expected, leftString.CompareTo(rightString));
            Assert.Equal(expected, leftString.CompareTo(right));

            Assert.Equal(-expected, rightSpan.CompareTo(leftSpan));
            Assert.Equal(-expected, rightSpan.CompareTo(leftString));
            Assert.Equal(-expected, rightSpan.CompareTo(left));

            Assert.Equal(-expected, rightString.CompareTo(leftSpan));
            Assert.Equal(-expected, rightString.CompareTo(leftString));
            Assert.Equal(-expected, rightString.CompareTo(left));

            Assert.Equal(0, rightString.CompareTo(rightString));
            Assert.Equal(0, rightString.CompareTo(rightSpan));
            Assert.Equal(0, rightString.CompareTo(right));

            Assert.Equal(0, rightSpan.CompareTo(rightString));
            Assert.Equal(0, rightSpan.CompareTo(rightSpan));
            Assert.Equal(0, rightSpan.CompareTo(right));

            Assert.Equal(0, leftString.CompareTo(leftString));
            Assert.Equal(0, leftString.CompareTo(leftSpan));
            Assert.Equal(0, leftString.CompareTo(left));

            Assert.Equal(0, leftSpan.CompareTo(leftString));
            Assert.Equal(0, leftSpan.CompareTo(leftSpan));
            Assert.Equal(0, leftSpan.CompareTo(left));
        }
        public bool TryAddString(Utf8Span value, out int index)
        {
            // If the string already exists, then just return that index.
            if (this.utf8StringToIndex.TryGetValue(value.Span, out index))
            {
                return(true);
            }

            // If we are at capacity just return false.
            if (this.size == this.strings.Length)
            {
                index = default;
                return(false);
            }

            index = this.size;
            this.strings[this.size] = UtfAllString.Create(value.ToString());
            this.utf8StringToIndex.AddOrUpdate(value.Span, index);
            this.size++;

            return(true);
        }
예제 #6
0
        internal HttpVersion ReadHttpVersion()
        {
            ReadOnlySpan <byte> oldBuffer = Buffer;
            Utf8Span            version   = ReadHttpVersionAsUtf8Span();

            if (version.Equals(s_Http1_1))
            {
                return(HttpVersion.V1_1);
            }
            else if (version.Equals(s_Http2_0))
            {
                return(HttpVersion.V2_0);
            }
            else if (version.Equals(s_Http1_0))
            {
                return(HttpVersion.V1_0);
            }
            else
            {
                Buffer = oldBuffer;
                return(HttpVersion.Unknown);
            }
        }
예제 #7
0
        public static void Split_Deconstruct_WithOptions()
        {
            using BoundedUtf8Span boundedSpan = new BoundedUtf8Span("a, , b, c,, d, e");
            Utf8Span span = boundedSpan.Span;

            // Note referential equality checks below (since we want to know exact slices
            // into the original buffer), not deep (textual) equality checks.

            {
                (Utf8Span a, Utf8Span b) = span.Split(',', Utf8StringSplitOptions.RemoveEmptyEntries);
                Assert.True(a.Bytes == span.Bytes[..1]); // "a"
                Assert.True(b.Bytes == span.Bytes[2..]); // " , b, c,, d, e"
            }

            {
                (Utf8Span a, Utf8Span x, Utf8Span b, Utf8Span c, Utf8Span d, Utf8Span e) = span.Split(',', Utf8StringSplitOptions.RemoveEmptyEntries);
                Assert.True(a.Bytes == span.Bytes[0..1]);   // "a"
                Assert.True(x.Bytes == span.Bytes[2..3]);   // " "
                Assert.True(b.Bytes == span.Bytes[4..6]);   // " b"
                Assert.True(c.Bytes == span.Bytes[7..9]);   // " c"
                Assert.True(d.Bytes == span.Bytes[11..13]); // " d"
                Assert.True(e.Bytes == span.Bytes[14..]);   // " e"
            }

            {
                (Utf8Span a, Utf8Span b, Utf8Span c, Utf8Span d, Utf8Span e, Utf8Span f, Utf8Span g, Utf8Span h) = span.Split(',', Utf8StringSplitOptions.RemoveEmptyEntries | Utf8StringSplitOptions.TrimEntries);
                Assert.True(a.Bytes == span.Bytes[0..1]);   // "a"
                Assert.True(b.Bytes == span.Bytes[5..6]);   // "b"
                Assert.True(c.Bytes == span.Bytes[8..9]);   // "c"
                Assert.True(d.Bytes == span.Bytes[12..13]); // "d"
                Assert.True(e.Bytes == span.Bytes[15..]);   // "e"
                Assert.True(f.Bytes == default);
                Assert.True(g.Bytes == default);
                Assert.True(h.Bytes == default);
            }
        }
예제 #8
0
        public static void Equals_Ordinal()
        {
            // First make sure referential equality passes

            Utf8Span span1 = u8("Hello!");
            Utf8Span span2 = span1;

            AssertEqualOrdinal(span1, span2);

            // Now make sure deep equality passes

            span2 = Utf8Span.UnsafeCreateWithoutValidation(Encoding.UTF8.GetBytes("Hello!"));
            AssertEqualOrdinal(span1, span2);

            // Now mutate one of the inputs and make sure they're inequal

            span2 = u8("Bello!");
            AssertNotEqualOrdinal(span1, span2);

            // Finally, make sure null / null and null / empty are treated as the same

            AssertEqualOrdinal(Utf8Span.Empty, Utf8Span.Empty);
            AssertEqualOrdinal(Utf8Span.Empty, u8(""));
        }
예제 #9
0
        public static void Equals_NonOrdinal(string str1, string str2, StringComparison comparison, string culture, bool shouldCompareAsEqual)
        {
            Func <string, string, string, string, string, int> action = (str1, str2, comparison, culture, shouldCompareAsEqual) =>
            {
                if (culture != null)
                {
                    CultureInfo.CurrentCulture = new CultureInfo(culture);
                }

                using BoundedUtf8Span boundedSpan1 = new BoundedUtf8Span(str1);
                using BoundedUtf8Span boundedSpan2 = new BoundedUtf8Span(str2);

                Utf8Span span1 = boundedSpan1.Span;
                Utf8Span span2 = boundedSpan2.Span;

                StringComparison comparisonType = Enum.Parse <StringComparison>(comparison);
                bool             expected       = bool.Parse(shouldCompareAsEqual);

                Assert.Equal(expected, span1.Equals(span2, comparisonType));
                Assert.Equal(expected, span2.Equals(span1, comparisonType));
                Assert.Equal(expected, Utf8Span.Equals(span1, span2, comparisonType));
                Assert.Equal(expected, Utf8Span.Equals(span2, span1, comparisonType));

                return(RemoteExecutor.SuccessExitCode);
            };

            if (culture != null)
            {
                // need to apply a culture to the current thread
                RemoteExecutor.Invoke(action, str1, str2, comparison.ToString(), culture, shouldCompareAsEqual.ToString()).Dispose();
            }
            else
            {
                action(str1, str2, comparison.ToString(), culture, shouldCompareAsEqual.ToString());
            }
        }
예제 #10
0
        internal static bool TryParseMethod(ReadOnlySpan <byte> buffer, out HttpMethod method, out int parsedBytes)
        {
            var bufferString = new Utf8Span(buffer);

            if (bufferString.StartsWith(s_Get))
            {
                method      = HttpMethod.Get;
                parsedBytes = s_Get.Bytes.Length;
                return(true);
            }

            if (bufferString.StartsWith(s_Post))
            {
                method      = HttpMethod.Post;
                parsedBytes = s_Post.Bytes.Length;
                return(true);
            }

            if (bufferString.StartsWith(s_Put))
            {
                method      = HttpMethod.Put;
                parsedBytes = s_Put.Bytes.Length;
                return(true);
            }

            if (bufferString.StartsWith(s_Delete))
            {
                method      = HttpMethod.Delete;
                parsedBytes = s_Delete.Bytes.Length;
                return(true);
            }

            method      = HttpMethod.Unknown;
            parsedBytes = 0;
            return(false);
        }
예제 #11
0
        public void ParseSystemTextJsonLab()
        {
            var        parser = new JsonParser(_dataUtf8);
            JsonObject obj    = parser.Parse();

            if (TestCase == TestCaseType.Json400KB)
            {
                var lookup = new Utf8Span("email");

                for (int i = 0; i < 10_000; i++)
                {
                    Utf8Span email = (Utf8Span)obj[5][lookup];
                }
            }
            else if (TestCase == TestCaseType.HelloWorld)
            {
                var lookup = new Utf8Span("message");

                for (int i = 0; i < 10; i++)
                {
                    Utf8Span message = (Utf8Span)obj[lookup];
                }
            }
        }
예제 #12
0
        public void ChangeEntryPointLibraryName()
        {
            string depsJson = TestJson.DepsJsonSignalR;

            byte[]     dataUtf8 = Encoding.UTF8.GetBytes(depsJson);
            JsonObject obj      = JsonObject.Parse(dataUtf8);

            var targetsString   = new Utf8Span("targets");
            var librariesString = new Utf8Span("libraries");

            JsonObject targets = obj[targetsString];

            foreach (JsonObject target in targets)
            {
                Assert.True(target.TryGetChild(out JsonObject firstChild));
                obj.Remove(firstChild);
            }

            JsonObject libraries = obj[librariesString];

            Assert.True(libraries.TryGetChild(out JsonObject child));
            obj.Remove(child);

            string expected = ChangeEntryPointLibraryNameExpected();

            var output   = new ArrayFormatterWrapper(1024, SymbolTable.InvariantUtf8);
            var jsonUtf8 = new Utf8JsonWriter <ArrayFormatterWrapper>(output);

            jsonUtf8.Write(obj);
            jsonUtf8.Flush();

            ArraySegment <byte> formatted = output.Formatted;
            string actualStr = Encoding.UTF8.GetString(formatted.Array, formatted.Offset, formatted.Count);

            Assert.Equal(expected, actualStr);
        }
        private static bool TryGetUserStringId(Utf8Span stringToken, out int userStringId)
        {
            byte typeMarker = stringToken.Span[0];

            if (!JsonBinaryEncoding.TypeMarker.IsUserString(typeMarker))
            {
                userStringId = default;
                return(false);
            }

            if (JsonBinaryEncoding.TypeMarker.IsOneByteEncodedUserString(typeMarker))
            {
                if (stringToken.Length < 1)
                {
                    userStringId = default;
                    return(false);
                }

                userStringId = stringToken.Span[0] - JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin;
            }
            else //// JsonBinaryEncoding.TypeMarker.IsTwoByteEncodedUserString(typeMarker)
            {
                if (stringToken.Length < 2)
                {
                    userStringId = default;
                    return(false);
                }

                const byte OneByteCount = JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMax - JsonBinaryEncoding.TypeMarker.UserString1ByteLengthMin;
                userStringId = OneByteCount
                               + stringToken.Span[1]
                               + ((stringToken.Span[0] - JsonBinaryEncoding.TypeMarker.UserString2ByteLengthMin) * 0xFF);
            }

            return(true);
        }
예제 #14
0
            public override bool Equals(Utf8Span x, Utf8Span y)
            {
                // TODO_UTF8STRING: Avoid the allocations below.

                return(StringComparer.OrdinalIgnoreCase.Equals(x.ToString(), y.ToString()));
            }
예제 #15
0
 public override int GetHashCode(Utf8Span obj) => obj.GetHashCode();
예제 #16
0
 public override bool Equals(Utf8Span x, Utf8Span y) => Utf8Span.Equals(x, y);
예제 #17
0
            public override int Compare(Utf8Span x, Utf8Span y)
            {
                // TODO_UTF8STRING: Avoid the allocations below.

                return(string.CompareOrdinal(x.ToString(), y.ToString()));
            }
예제 #18
0
            public override int GetHashCode(Utf8Span obj)
            {
                // TODO_UTF8STRING: Avoid the allocations below.

                return(_compareInfo.GetHashCode(obj.ToString(), _options));
            }
예제 #19
0
 public static void BytesProperty_FromCustomBytes()
 {
     byte[] bytes = Encoding.UTF8.GetBytes("Hello!");
     Assert.True(bytes.AsSpan() == Utf8Span.UnsafeCreateWithoutValidation(bytes).Bytes);
 }
예제 #20
0
 public static void Validate(Utf8Span str1, Utf8Span str2)
 {
     Assert.Equal(str1.Bytes.Length, str2.Bytes.Length);
     Assert.True(str1.Bytes.SequenceEqual(str2.Bytes));
 }
예제 #21
0
 public static bool TryFormat(this Utf8Span str, Span <byte> buffer, out int written, StandardFormat format, SymbolTable symbolTable)
 {
     return(symbolTable.TryEncode(str.Bytes, buffer, out var consumed, out written));
 }
예제 #22
0
 public override void WriteStringValue(Utf8Span utf8StringValue)
 {
     this.WriteStringValue(Encoding.UTF8.GetString(utf8StringValue.Span));
 }
예제 #23
0
 public override bool Equals(Utf8Span x, Utf8Span y) => Compare(x, y) == 0;
예제 #24
0
            public override int GetHashCode(Utf8Span obj)
            {
                // TODO_UTF8STRING: Avoid the allocations below.

                return(StringComparer.OrdinalIgnoreCase.GetHashCode(obj.ToString()));
            }
예제 #25
0
        private static string ReadJson400KB(JsonObject obj)
        {
            Utf8Span _id           = (Utf8Span)"_id";
            Utf8Span index         = (Utf8Span)"index";
            Utf8Span guid          = (Utf8Span)"guid";
            Utf8Span isActive      = (Utf8Span)"isActive";
            Utf8Span balance       = (Utf8Span)"balance";
            Utf8Span picture       = (Utf8Span)"picture";
            Utf8Span age           = (Utf8Span)"age";
            Utf8Span eyeColor      = (Utf8Span)"eyeColor";
            Utf8Span name          = (Utf8Span)"name";
            Utf8Span gender        = (Utf8Span)"gender";
            Utf8Span company       = (Utf8Span)"company";
            Utf8Span email         = (Utf8Span)"email";
            Utf8Span phone         = (Utf8Span)"phone";
            Utf8Span address       = (Utf8Span)"address";
            Utf8Span about         = (Utf8Span)"about";
            Utf8Span registered    = (Utf8Span)"registered";
            Utf8Span latitude      = (Utf8Span)"latitude";
            Utf8Span longitude     = (Utf8Span)"longitude";
            Utf8Span tags          = (Utf8Span)"tags";
            Utf8Span friends       = (Utf8Span)"friends";
            Utf8Span id            = (Utf8Span)"id";
            Utf8Span greeting      = (Utf8Span)"greeting";
            Utf8Span favoriteFruit = (Utf8Span)"favoriteFruit";

            var sb = new StringBuilder();

            for (int i = 0; i < obj.ArrayLength; i++)
            {
                sb.Append((string)obj[i][_id]);
                sb.Append((int)obj[i][index]);
                sb.Append((string)obj[i][guid]);
                sb.Append((bool)obj[i][isActive]);
                sb.Append((string)obj[i][balance]);
                sb.Append((string)obj[i][picture]);
                sb.Append((int)obj[i][age]);
                sb.Append((string)obj[i][eyeColor]);
                sb.Append((string)obj[i][name]);
                sb.Append((string)obj[i][gender]);
                sb.Append((string)obj[i][company]);
                sb.Append((string)obj[i][email]);
                sb.Append((string)obj[i][phone]);
                sb.Append((string)obj[i][address]);
                sb.Append((string)obj[i][about]);
                sb.Append((string)obj[i][registered]);
                sb.Append((double)obj[i][latitude]);
                sb.Append((double)obj[i][longitude]);

                JsonObject tagsObject = obj[i][tags];
                for (int j = 0; j < tagsObject.ArrayLength; j++)
                {
                    sb.Append((string)tagsObject[j]);
                }
                JsonObject friendsObject = obj[i][friends];
                for (int j = 0; j < friendsObject.ArrayLength; j++)
                {
                    sb.Append((int)friendsObject[j][id]);
                    sb.Append((string)friendsObject[j][name]);
                }
                sb.Append((string)obj[i][greeting]);
                sb.Append((string)obj[i][favoriteFruit]);
            }
            return(sb.ToString());
        }
예제 #26
0
 internal Enumerator(SplitResult result)
 {
     _current = default;
     _state   = result._state; // copy by value
 }
예제 #27
0
            public override int Compare(Utf8Span x, Utf8Span y)
            {
                // TODO_UTF8STRING: Avoid the allocations below.

                return(_compareInfo.Compare(x.ToString(), y.ToString(), _options));
            }
예제 #28
0
 internal Utf8Span AsSpanSkipNullCheck()
 {
     return(Utf8Span.UnsafeCreateWithoutValidation(this.AsBytesSkipNullCheck()));
 }
예제 #29
0
        public static bool TryWrite(Span <byte> output, Sha256 hash, Utf8Span keyType, Utf8Span verb, Utf8Span resourceId, Utf8Span resourceType, Utf8Span tokenVersion, DateTime utc, out int bytesWritten)
        {
            Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize];
            var         writer = BufferWriter.Create(buffer);

            writer.Enlarge = (minumumSize) => { return(new byte[minumumSize * 2]); };

            // compute signature hash
            writer.WriteLine(verb, s_toLower);
            writer.WriteLine(resourceType, s_toLower);
            writer.WriteLine(resourceId, s_toLower);
            writer.WriteLine(utc, 'l');
            writer.Write('\n');
            hash.Append(writer.Written);

            // combine token
            writer.WrittenCount = 0; // reuse writer and buffer
            writer.Write(s_typeLiteral);
            writer.Write(keyType);
            writer.Write(s_verLiteral);
            writer.Write(tokenVersion);
            writer.Write(s_sigLiteral);

            writer.WriteBytes(hash, s_toBase64);

            if (UrlEncoder.Utf8.Encode(writer.Written, output, out var consumed, out bytesWritten) != OperationStatus.Done)
            {
                bytesWritten = 0;
                return(false);
            }
            return(true);
        }
예제 #30
0
 public override void WriteFieldName(Utf8Span utf8FieldName)
 {
     this.WriteFieldName(Encoding.UTF8.GetString(utf8FieldName.Span));
 }