public static bool TryParseUInt32(Utf8Span str, out uint val)
 {
     if (!Utf8Parser.TryParseUInt32(str, out val, out var consumed) || consumed != str.Length())
     {
         return(false);
     }
     return(true);
 }
 public static uint ParseUInt32(Utf8Span str)
 {
     if (!Utf8Parser.TryParseUInt32(str, out var value, out var consumed))
     {
         throw new FormatException();
     }
     if (consumed != str.Length())
     {
         throw new FormatException();
     }
     return(value);
 }
Пример #3
0
        public bool TryGetUInt32(Utf8Span property, out uint value)
        {
            var       jsonProperty = new JsonProperty(this, property);
            JsonValue jsonValue;

            if (!_properties.TryGetValue(jsonProperty, out jsonValue))
            {
                value = default;
                return(false);
            }

            if (jsonValue.Type != JsonValueType.Number)
            {
                throw new InvalidOperationException();
            }
            return(Utf8Parser.TryParseUInt32(jsonValue.Value.Bytes, out value));
        }
        [InlineData("0")]          // min value
        private unsafe static void PrimitiveParserByteSpanToUInt32(string text)
        {
            byte[] utf8ByteArray = Text.Encoding.UTF8.GetBytes(text);
            var    utf8ByteSpan  = new ReadOnlySpan <byte>(utf8ByteArray);

            foreach (var iteration in Benchmark.Iterations)
            {
                using (iteration.StartMeasurement())
                {
                    for (int i = 0; i < TestHelper.LoadIterations; i++)
                    {
                        uint value;
                        Utf8Parser.TryParseUInt32(utf8ByteSpan, out value);
                        TestHelper.DoNotIgnore(value, 0);
                    }
                }
            }
        }
        private unsafe static void PrimitiveParserByteSpanToUInt32_BytesConsumed_VariableLength()
        {
            int textLength = s_UInt32TextArray.Length;

            byte[][] utf8ByteArray = (byte[][])Array.CreateInstance(typeof(byte[]), textLength);
            for (var i = 0; i < textLength; i++)
            {
                utf8ByteArray[i] = Text.Encoding.UTF8.GetBytes(s_UInt32TextArray[i]);
            }
            foreach (var iteration in Benchmark.Iterations)
            {
                using (iteration.StartMeasurement())
                {
                    for (int i = 0; i < TestHelper.LoadIterations; i++)
                    {
                        ReadOnlySpan <byte> utf8ByteSpan = utf8ByteArray[i % textLength];
                        uint value;
                        int  bytesConsumed;
                        Utf8Parser.TryParseUInt32(utf8ByteSpan, out value, out bytesConsumed);
                        TestHelper.DoNotIgnore(value, bytesConsumed);
                    }
                }
            }
        }
Пример #6
0
        public static bool TryParseUInt32 <T>(this T bufferSequence, out uint value, out int consumed) where T : ISequence <ReadOnlyMemory <byte> >
        {
            value    = default;
            consumed = default;
            Position position = Position.First;

            // Fetch the first segment
            ReadOnlyMemory <byte> first;

            if (!bufferSequence.TryGet(ref position, out first))
            {
                return(false);
            }

            // Attempt to parse the first segment. If it works (and it should in most cases), then return success.
            bool parsed = Utf8Parser.TryParseUInt32(first.Span, out value, out consumed);

            if (parsed && consumed < first.Length)
            {
                return(true);
            }

            // Apparently the we need data from the second segment to succesfully parse, and so fetch the second segment.
            ReadOnlyMemory <byte> second;

            if (!bufferSequence.TryGet(ref position, out second))
            {
                // if there is no second segment and the first parsed succesfully, return the result of the parsing.
                if (parsed)
                {
                    return(true);
                }
                return(false);
            }

            // Combine the first, the second, and potentially more segments into a stack allocated buffer
            if (first.Length < StackBufferSize)
            {
                Span <byte> destination = stackalloc byte[StackBufferSize];

                first.Span.CopyTo(destination);
                var free = destination.Slice(first.Length);

                if (second.Length > free.Length)
                {
                    second = second.Slice(0, free.Length);
                }
                second.Span.CopyTo(free);
                free = free.Slice(second.Length);

                ReadOnlyMemory <byte> next;
                while (free.Length > 0)
                {
                    if (bufferSequence.TryGet(ref position, out next))
                    {
                        if (next.Length > free.Length)
                        {
                            next = next.Slice(0, free.Length);
                        }
                        next.Span.CopyTo(free);
                        free = free.Slice(next.Length);
                    }
                    else
                    {
                        break;
                    }
                }

                var combinedStackSpan = destination.Slice(0, StackBufferSize - free.Length);

                // if the stack allocated buffer parsed succesfully (and for uint it should always do), then return success.
                if (Utf8Parser.TryParseUInt32(combinedStackSpan, out value, out consumed))
                {
                    if (consumed < combinedStackSpan.Length || combinedStackSpan.Length < StackBufferSize)
                    {
                        return(true);
                    }
                }
            }

            // for invariant culture, we should never reach this point, as invariant uint text is never longer than 127 bytes.
            // I left this code here, as we will need it for custom cultures and possibly when we shrink the stack allocated buffer.
            var combinedSpan = bufferSequence.ToSpan();

            if (!Utf8Parser.TryParseUInt32(combinedSpan, out value, out consumed))
            {
                return(false);
            }
            return(true);
        }