예제 #1
0
        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);
        }
예제 #2
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);
        }
        public unsafe void UInt64PositiveTests(string text, int length, ulong expectedValue, int expectedConsumed)
        {
            byte[] byteBuffer            = new Utf8String(text).CopyBytes();
            ReadOnlySpan <byte> byteSpan = new ReadOnlySpan <byte>(byteBuffer);

            char[] charBuffer            = text.ToCharArray();
            ReadOnlySpan <char> charSpan = new ReadOnlySpan <char>(charBuffer);

            bool  result;
            ulong actualValue;
            int   actualConsumed;

            result = PrimitiveParser.TryParseUInt64(byteSpan, out actualValue, out actualConsumed, EncodingData.InvariantUtf8);

            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);
            Assert.Equal(expectedConsumed, actualConsumed);

            fixed(byte *bytePointer = byteBuffer)
            {
                result = PrimitiveParser.InvariantUtf8.TryParseUInt64(bytePointer, length, out actualValue);

                Assert.True(result);
                Assert.Equal(expectedValue, actualValue);

                result = PrimitiveParser.InvariantUtf8.TryParseUInt64(bytePointer, length, out actualValue, out actualConsumed);

                Assert.True(result);
                Assert.Equal(expectedValue, actualValue);
                Assert.Equal(expectedConsumed, actualConsumed);
            }

            result = PrimitiveParser.InvariantUtf8.TryParseUInt64(byteSpan, out actualValue);

            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);

            result = PrimitiveParser.InvariantUtf8.TryParseUInt64(byteSpan, out actualValue, out actualConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);
            Assert.Equal(expectedConsumed, actualConsumed);

            ReadOnlySpan <byte> utf16ByteSpan = charSpan.Cast <char, byte>();

            result = PrimitiveParser.TryParseUInt64(utf16ByteSpan, out actualValue, out actualConsumed, EncodingData.InvariantUtf16);
            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);
            Assert.Equal(expectedConsumed, actualConsumed / 2);

            fixed(char *charPointer = charBuffer)
            {
                result = PrimitiveParser.InvariantUtf16.TryParseUInt64(charPointer, length, out actualValue);

                Assert.True(result);
                Assert.Equal(expectedValue, actualValue);

                result = PrimitiveParser.InvariantUtf16.TryParseUInt64(charPointer, length, out actualValue, out actualConsumed);

                Assert.True(result);
                Assert.Equal(expectedValue, actualValue);
                Assert.Equal(expectedConsumed, actualConsumed);
            }

            result = PrimitiveParser.InvariantUtf16.TryParseUInt64(charSpan, out actualValue);

            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);

            result = PrimitiveParser.InvariantUtf16.TryParseUInt64(charSpan, out actualValue, out actualConsumed);

            Assert.True(result);
            Assert.Equal(expectedValue, actualValue);
            Assert.Equal(expectedConsumed, actualConsumed);
        }