コード例 #1
0
        public static bool TryParseUInt32 <TMultispan>(this TMultispan bytes, EncodingData encoding, out uint value, out int consumed) where TMultispan : ISequence <Span <byte> >
        {
            Position position = Position.BeforeFirst;
            var      first    = bytes.TryGetItem(ref position);

            if (!position.IsValid)
            {
                throw new ArgumentException("bytes cannot be empty");
            }

            if (!PrimitiveParser.TryParse(first, EncodingData.Encoding.Utf8, out value, out consumed))
            {
                return(false); // TODO: maybe we should continue in some cases, e.g. if the first span ends in a decimal separator
                               // ... cont, maybe consumed could be set even if TryParse returns false
            }
            if (position.IsEnd || first.Length > consumed)
            {
                return(true);
            }

            var second = bytes.TryGetItem(ref position);

            Span <byte> temp;
            int         numberOfBytesFromSecond = second.Length;

            if (numberOfBytesFromSecond > 64)
            {
                numberOfBytesFromSecond = 64;
            }
            var tempBufferLength = first.Length + numberOfBytesFromSecond;

            if (tempBufferLength > 128)
            {
                temp = new byte[tempBufferLength];
            }
            else
            {
                unsafe
                {
                    byte *data = stackalloc byte[tempBufferLength];
                    temp = new Span <byte>(data, tempBufferLength);
                }
            }

            first.TryCopyTo(temp);

            second.Slice(0, numberOfBytesFromSecond).TryCopyTo(temp.Slice(first.Length));

            if (!PrimitiveParser.TryParse(temp, EncodingData.Encoding.Utf8, out value, out consumed))
            {
                return(false);
            }

            if (position.IsEnd || temp.Length > consumed)
            {
                return(true);
            }

            throw new NotImplementedException();
        }
コード例 #2
0
ファイル: BytesReader.cs プロジェクト: tmds/corefxlab
        public bool TryParseUInt64(out ulong value)
        {
            int consumed;
            var unread = Unread;

            if (PrimitiveParser.TryParseUInt64(unread, out value, out consumed, default(TextFormat), _encoder))
            {
                if (unread.Length > consumed)
                {
                    _currentSegmentIndex += consumed;
                    return(true);
                }
            }

            unsafe
            {
                byte *temp     = stackalloc byte[32];
                var   tempSpan = new Span <byte>(temp, 32);
                var   copied   = CopyTo(tempSpan);

                if (PrimitiveParser.TryParseUInt64(tempSpan.Slice(0, copied), out value, out consumed, 'G', _encoder))
                {
                    Advance(consumed);
                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
        public static JsonObjectType GetType(ref ReadOnlySpan <char> content)
        {
            JsonTokenType tokenType = JsonToken.GetType(content);

            switch (tokenType)
            {
            case JsonTokenType.ArrayStart:
                return(JsonObjectType.Array);

            case JsonTokenType.ObjectStart:
                return(JsonObjectType.Object);

            case JsonTokenType.NameBoundary:
                return(JsonObjectType.String);

            case JsonTokenType.Unknown:
                if (PrimitiveParser.IsPrimitive(content))
                {
                    return(JsonObjectType.Primitive);
                }
                break;
            }

            throw new InvalidOperationException("Unsupported token type.");
        }
コード例 #4
0
        /// <summary>
        /// Parses a <see cref="uint"/> from the specified <see cref="ReadableBuffer"/>
        /// </summary>
        /// <param name="buffer">The <see cref="ReadableBuffer"/> to parse</param>
        public unsafe static uint GetUInt32(this ReadableBuffer buffer)
        {
            ReadOnlySpan <byte> textSpan;

            if (buffer.IsSingleSpan)
            {
                // It fits!
                textSpan = buffer.First.Span;
            }
            else if (buffer.Length < 128) // REVIEW: What's a good number
            {
                var data        = stackalloc byte[128];
                var destination = new Span <byte>(data, 128);

                buffer.CopyTo(destination);

                textSpan = destination.Slice(0, buffer.Length);
            }
            else
            {
                // Heap allocated copy to parse into array (should be rare)
                textSpan = new ReadOnlySpan <byte>(buffer.ToArray());
            }

            uint value;
            var  utf8Buffer = new Utf8String(textSpan);

            if (!PrimitiveParser.TryParseUInt32(utf8Buffer, out value))
            {
                throw new InvalidOperationException();
            }
            return(value);
        }
コード例 #5
0
        uint ReadCount(ReadOnlySpan <byte> json)
        {
            uint count;
            var  reader = new JsonReader(new Utf8String(json));

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonReader.JsonTokenType.Property:
                    var name  = reader.GetName();
                    var value = reader.GetValue();
                    Console.WriteLine("Property {0} = {1}", name, value);
                    if (name == "Count")
                    {
                        if (!PrimitiveParser.TryParse(value, out count))
                        {
                            return(1);
                        }
                        return(count);
                    }
                    break;
                }
            }
            return(1);
        }
コード例 #6
0
        /// <summary>
        /// The method based on ReadOnlySpan
        /// </summary>
        /// <param name="str"></param>
        public static void ParseStringSpan(ReadOnlySpan <char> str)
        {
            var url    = str.Slice(13, 19);
            var method = str.Slice(58, 3);

            PrimitiveParser.TryParseInt32(str.Slice(84, 3).AsBytes(), out int statusCode, out int bytesConsumed);
            var remoteAddr     = str.Slice(116, 14);
            var referrerPolicy = str.Slice(157, 26);
            var accept         = str.Slice(201, 85);
            var acceptEncoding = str.Slice(313, 13);
            var acceptLanguage = str.Slice(353, 44);
            var connection     = str.Slice(419, 10);
            var cookie         = str.Slice(447, 118);
            var host           = str.Slice(581, 11);

            PrimitiveParser.TryParseInt32(str.Slice(629, 1).AsBytes(), out int updgradeInsecureRequest, out int bytesConsumed2);
            var userAgent = str.Slice(652, 115);

            Debug.WriteLine(url);
            Debug.WriteLine(method);
            Debug.WriteLine(statusCode);
            Debug.WriteLine(remoteAddr);
            Debug.WriteLine(accept);
            Debug.WriteLine(acceptEncoding);
            Debug.WriteLine(acceptLanguage);
            Debug.WriteLine(connection);
            Debug.WriteLine(cookie);
            Debug.WriteLine(host);
            Debug.WriteLine(updgradeInsecureRequest);
            Debug.WriteLine(userAgent);
        }
コード例 #7
0
        // TODO: format should be ReadOnlySpan<T>
        public static Format.Parsed Parse(ReadOnlySpan <char> format)
        {
            if (format.Length == 0)
            {
                return(default(Format.Parsed));
            }

            uint precision = NoPrecision;

            if (format.Length > 1)
            {
                var span = format.Slice(1, format.Length - 1);

                if (!PrimitiveParser.TryParseUInt32(span, out precision))
                {
                    throw new NotImplementedException("UnableToParsePrecision");
                }

                if (precision > Parsed.MaxPrecision)
                {
                    // TODO: this is a contract violation
                    throw new Exception("PrecisionValueOutOfRange");
                }
            }

            // TODO: this is duplicated from above. It needs to be refactored
            var specifier = format[0];

            return(new Parsed(specifier, (byte)precision));
        }
コード例 #8
0
ファイル: BytesReader.cs プロジェクト: tmds/corefxlab
        // TODO: how to we chose the lengths of the temp buffers?
        // TODO: these methods call the slow overloads of PrimitiveParser.TryParseXXX. Do we need fast path?
        // TODO: these methods hardcode the format. Do we need this to be something that can be specified?
        public bool TryParseBoolean(out bool value)
        {
            int consumed;
            var unread = Unread;

            if (PrimitiveParser.TryParseBoolean(unread, out value, out consumed, _encoder))
            {
                if (unread.Length > consumed)
                {
                    _currentSegmentIndex += consumed;
                    return(true);
                }
            }

            unsafe
            {
                byte *temp     = stackalloc byte[15];
                var   tempSpan = new Span <byte>(temp, 15);
                var   copied   = CopyTo(tempSpan);

                if (PrimitiveParser.TryParseBoolean(tempSpan.Slice(0, copied), out value, out consumed, _encoder))
                {
                    Advance(consumed);
                    return(true);
                }
            }

            return(false);
        }
コード例 #9
0
        /// <summary>
        /// Parses a <see cref="ulong"/> from the specified <see cref="ReadableBuffer"/>
        /// </summary>
        /// <param name="buffer">The <see cref="ReadableBuffer"/> to parse</param>
        public unsafe static ulong GetUInt64(this ReadableBuffer buffer)
        {
            byte *addr;
            ulong value;
            int   consumed, len = buffer.Length;

            if (buffer.IsSingleSpan)
            {
                // It fits!
                addr = (byte *)buffer.First.UnsafePointer;
            }
            else if (len < 128) // REVIEW: What's a good number
            {
                var data = stackalloc byte[len];
                buffer.CopyTo(new Span <byte>(data, len));
                addr = data; // memory allocated via stackalloc is valid and
                // intact until the end of the method; we don't need to worry about scope
            }
            else
            {
                // Heap allocated copy to parse into array (should be rare)
                var arr = buffer.ToArray();
                if (!PrimitiveParser.TryParse(arr, 0, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
                {
                    throw new InvalidOperationException();
                }
                return(value);
            }

            if (!PrimitiveParser.TryParse(addr, 0, len, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
            {
                throw new InvalidOperationException();
            }
            return(value);
        }
コード例 #10
0
        // once we have a non allocating conversion from string to ReadOnlySpan<char>, we can remove this overload
        public static Format.Parsed Parse(string format)
        {
            if (format == null || format.Length == 0)
            {
                return(default(Format.Parsed));
            }

            uint precision = NoPrecision;

            if (format.Length > 1)
            {
                if (!PrimitiveParser.TryParseUInt32(format, 1, format.Length - 1, out precision))
                {
                    throw new NotImplementedException("Unable to parse precision specification");
                }

                if (precision > Parsed.MaxPrecision)
                {
                    // TODO: this is a contract violation
                    throw new Exception("PrecisionValueOutOfRange");
                }
            }

            var specifier = format[0];

            return(new Parsed(specifier, (byte)precision));
        }
コード例 #11
0
        public static IParserAlphabet Minimal(bool areRegexControlCharactersValid = true)
        {
            var parserAlphabet  = new ParserAlphabet();
            var primitiveParser = new PrimitiveParser(parserAlphabet);

            parserAlphabet.AddRegexControlCharacters(primitiveParser, areRegexControlCharactersValid);

            return(parserAlphabet);
        }
コード例 #12
0
        public void TryParseCharacter_ReturnsSuccessResult_WhenStringContainsValidCharacters(string input)
        {
            var stream = GetStringStreamFor(input);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacter(stream);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual("U", result.Value);
        }
コード例 #13
0
        public void TryParseCharacter_ReturnsFailureResult_WhenStringIsEmpty()
        {
            var stream = GetStringStreamFor("");
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacter(stream);

            Assert.IsFalse(result.IsSuccess);
            stream.Received(0).Pop();
        }
コード例 #14
0
        public void TryParseCharacter_ReturnsFailureResult_WhenStringContainsOnlyEscapeCharacter()
        {
            var stream = GetStringStreamFor(SpecialCharacters.Escape);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacter(stream);

            Assert.IsFalse(result.IsSuccess);
            stream.Received(0).Pop();
        }
コード例 #15
0
        public void TryParseIntegerInterval_FailureResult_WhenInputStringIsNoValidInterval(string input)
        {
            var inputStream = GetStringStreamFor(input);
            var parser      = new PrimitiveParser(_alphabet);

            var result = parser.TryParseIntegerInterval(inputStream);

            Assert.IsFalse(result.IsSuccess);
            inputStream.Received(0).Pop();
        }
コード例 #16
0
        public unsafe void ParseSubstringToUInt32(string text, int index, int count, uint expectedValue, int expectedConsumed)
        {
            uint parsedValue;
            int  charsConsumed;
            bool result = PrimitiveParser.TryParse(text, index, count, out parsedValue, out charsConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, parsedValue);
            Assert.Equal(expectedConsumed, charsConsumed);
        }
コード例 #17
0
        public void TryParseInteger_ReturnsSuccessResult_WhenStringStartsWithInteger(string input, int expected)
        {
            var stream = GetStringStreamFor(input);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseInteger(stream);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(expected, result.Value);
        }
コード例 #18
0
        /// <summary>
        /// Parses a <see cref="ulong"/> from the specified <see cref="ReadableBuffer"/>
        /// </summary>
        /// <param name="buffer">The <see cref="ReadableBuffer"/> to parse</param>
        public unsafe static ulong GetUInt64(this ReadableBuffer buffer)
        {
            byte *addr;
            ulong value;
            int   consumed, len = buffer.Length;

            if (buffer.IsSingleSpan)
            {
                // It fits!
                void *pointer;
                ArraySegment <byte> data;
                if (buffer.First.TryGetPointer(out pointer))
                {
                    if (!PrimitiveParser.TryParseUInt64((byte *)pointer, 0, len, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
                    {
                        throw new InvalidOperationException();
                    }
                }
                else if (buffer.First.TryGetArray(out data))
                {
                    if (!PrimitiveParser.TryParseUInt64(data.Array, 0, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
                    {
                        throw new InvalidOperationException();
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            else if (len < 128) // REVIEW: What's a good number
            {
                var data = stackalloc byte[len];
                buffer.CopyTo(new Span <byte>(data, len));
                addr = data;

                if (!PrimitiveParser.TryParseUInt64(addr, 0, len, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                // Heap allocated copy to parse into array (should be rare)
                var arr = buffer.ToArray();
                if (!PrimitiveParser.TryParseUInt64(arr, 0, EncodingData.InvariantUtf8, Format.Parsed.HexUppercase, out value, out consumed))
                {
                    throw new InvalidOperationException();
                }

                return(value);
            }

            return(value);
        }
コード例 #19
0
        public void TryParseCharacter_ReturnsFailureResult_WhenStringConsistsOfEscapeCharacterAndInvalidCharacter()
        {
            _alphabet.IsValid(Arg.Any <string>()).Returns(x => !x[0].Equals("N"));
            var stream = GetStringStreamFor($"{SpecialCharacters.Escape}N");
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacter(stream);

            Assert.IsFalse(result.IsSuccess);
            stream.Received(0).Pop();
        }
コード例 #20
0
        public unsafe void ParseSpanOfCharToUInt32(string text, uint expectedValue, int expectedConsumed)
        {
            var  span = new ReadOnlySpan <char>(text.ToCharArray());
            uint parsedValue;
            int  charsConsumed;
            bool result = PrimitiveParser.TryParse(span, out parsedValue, out charsConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, parsedValue);
            Assert.Equal(expectedConsumed, charsConsumed);
        }
コード例 #21
0
        public void TryParseInteger_ReturnsFailureResult_WhenInputStreamIsFaulty(string inputString)
        {
            var stream = GetStringStreamFor(inputString);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseInteger(stream);

            Assert.IsFalse(result.IsSuccess);
            Assert.AreEqual(RegSeedErrorType.IntegerExpected, result.ErrorType);
            stream.Received(0).Pop();
        }
コード例 #22
0
        public void TryParseCharacterRange_ReturnsFailureResult_WhenInputStreamIsTooShortForCharacterRange(string input)
        {
            var stream = GetStringStreamFor(input);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacterRange(stream);

            Assert.IsFalse(result.IsSuccess);
            Assert.AreEqual(RegSeedErrorType.None, result.ErrorType);
            stream.Received(0).Pop();
        }
コード例 #23
0
        public static IParserAlphabet MinimalExtendedBy(IEnumerable <string> additionalValidCharacters, bool areRegexControlCharactersValid = true)
        {
            var minimalAlphabet = Minimal(areRegexControlCharactersValid);
            var primitiveParser = new PrimitiveParser(minimalAlphabet);

            foreach (var additionalLetter in additionalValidCharacters)
            {
                minimalAlphabet.Add(additionalLetter, new CharacterParser(primitiveParser));
            }

            return(minimalAlphabet);
        }
コード例 #24
0
        public void TryParseIntegerInterval_SuccessResult_WhenInputStringIsValidInterval(string input, int?expectedLower, int?expectedUpper, int expectedPopCalls)
        {
            var inputStream = GetStringStreamFor(input);
            var parser      = new PrimitiveParser(_alphabet);

            var result = parser.TryParseIntegerInterval(inputStream);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(expectedLower, result.Value.Start);
            Assert.AreEqual(expectedUpper, result.Value.End);
            inputStream.Received(expectedPopCalls).Pop();
        }
コード例 #25
0
        public void TryParseCharacter_ReturnsSuccessResult_WhenStringStartsWithEscapeAndContainsOnlyValidCharacters(
            string input, string expected)
        {
            var stream = GetStringStreamFor(input);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacter(stream);

            Assert.IsTrue(result.IsSuccess);
            Assert.AreEqual(expected, result.Value);
            stream.Received(2).Pop();
        }
コード例 #26
0
ファイル: RegSeedTest.cs プロジェクト: JanZsch/RegSeed
        public void ConstructorWithPattern_GenerateCreatesString_WhenCalledWithParserAlphabet()
        {
            var alphabet        = RegexAlphabetFactory.Minimal();
            var primitiveParser = new PrimitiveParser(alphabet);

            alphabet.Add("a", new CharacterParser(primitiveParser));
            var regseed = new RegSeed("a", new Random(), alphabet);

            var result = regseed.Generate();

            Assert.AreEqual("a", result);
        }
コード例 #27
0
        public unsafe void ParseUtf8StringToUInt32(string text, uint expectedValue, int expectedConsumed)
        {
            var utf8 = new Utf8String(text);

            uint parsedValue;
            int  bytesConsumed;
            bool result = PrimitiveParser.TryParse(utf8, out parsedValue, out bytesConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, parsedValue);
            Assert.Equal(expectedConsumed, bytesConsumed);
        }
コード例 #28
0
        public void TryParseCharacterRange_ReturnsFailureResult_WhenThirdCharacterIsInvalidCharacter(string inputStream)
        {
            _alphabet.IsValid(Arg.Any <string>()).Returns(x => !x[0].Equals("s"));
            var stream = GetStringStreamFor(inputStream);
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacterRange(stream);

            Assert.IsFalse(result.IsSuccess);
            Assert.AreEqual(RegSeedErrorType.CharacterRangeExpected, result.ErrorType);
            _alphabet.Received(2).IsValid(Arg.Any <string>());
            stream.Received(0).Pop();
        }
コード例 #29
0
        public void TryParseCharacterRange_ReturnsFailureResult_WhenFirstStreamCharacterIsNotValidCharacter()
        {
            _alphabet.IsValid(Arg.Any <string>()).Returns(false);
            var stream = GetStringStreamFor("n-2");
            var parser = new PrimitiveParser(_alphabet);

            var result = parser.TryParseCharacterRange(stream);

            Assert.IsFalse(result.IsSuccess);
            Assert.AreEqual(RegSeedErrorType.None, result.ErrorType);
            _alphabet.Received(1).IsValid(Arg.Any <string>());
            stream.Received(0).Pop();
        }
コード例 #30
0
        public unsafe void ParseUtf8SpanOfBytesToUInt32(string text, uint expectedValue, int expectedConsumed)
        {
            byte[] textBuffer = Encoding.UTF8.GetBytes(text);
            var    span       = new ReadOnlySpan <byte>(textBuffer);

            uint parsedValue;
            int  bytesConsumed;
            bool result = PrimitiveParser.TryParse(span, EncodingData.Encoding.Utf8, out parsedValue, out bytesConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, parsedValue);
            Assert.Equal(expectedConsumed, bytesConsumed);
        }