Пример #1
0
        /// <summary>
        /// Parses a <see cref="ulong"/> from the specified <see cref="ReadOnlyBuffer"/>
        /// </summary>
        /// <param name="buffer">The <see cref="ReadOnlyBuffer"/> to parse</param>
        public static ulong GetUInt64(this ReadOnlyBuffer buffer)
        {
            if (Utf8Parser.TryParse(buffer.First.Span, out ulong value, out _))
            {
                return(value);
            }

            if (buffer.IsSingleSegment) // no more data to parse
            {
                throw new InvalidOperationException();
            }

            var bufferLength = buffer.Length;

            int toParseLength = 21; // longest invariant UTF8 UInt64 + 1 (so we know there is a delimiter at teh end)

            if (bufferLength < 21)
            {
                toParseLength = (int)bufferLength;
            }

            Span <byte> toParseBuffer = stackalloc byte[toParseLength];

            buffer.CopyTo(toParseBuffer);

            if (Utf8Parser.TryParse(toParseBuffer, out value, out _))
            {
                return(value);
            }

            throw new InvalidOperationException();
        }
Пример #2
0
        /// <summary>
        /// Decodes the utf8 encoded bytes in the <see cref="ReadOnlyBuffer"/> into a <see cref="string"/>
        /// </summary>
        /// <param name="buffer">The buffer to decode</param>
        public static string GetUtf8Span(this ReadOnlyBuffer buffer)
        {
            if (buffer.IsEmpty)
            {
                return(null);
            }

            // Assign 'textSpan' to something formally stack-referring.
            // The default classification is "returnable, not referring to stack", we want the opposite in this case.
            ReadOnlySpan <byte> textSpan = stackalloc byte[0];

            if (buffer.IsSingleSegment)
            {
                textSpan = buffer.First.Span;
            }
            else if (buffer.Length < 128) // REVIEW: What's a good number
            {
                Span <byte> destination = stackalloc byte[128];
                buffer.CopyTo(destination);

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

            return(new Utf8Span(textSpan).ToString());
        }
        public static void CopyToSpan()
        {
            int[] src = { 1, 2, 3 };
            int[] dst = { 99, 100, 101 };

            var srcBuffer = new ReadOnlyBuffer <int>(src);

            srcBuffer.CopyTo(dst.AsSpan());
            Assert.Equal <int>(src, dst);
        }
Пример #4
0
        public void Allocate_ReadBackBuffer_Copy_Range(Device device, int destinationOffset, int bufferOffset, int count)
        {
            int[] source = new int[4096];

            new Random(42).NextBytes(source.AsSpan().AsBytes());

            using ReadOnlyBuffer <int> readOnlyBuffer = device.Get().AllocateReadOnlyBuffer(source);
            using ReadBackBuffer <int> readBackBuffer = device.Get().AllocateReadBackBuffer <int>(readOnlyBuffer.Length);

            readOnlyBuffer.CopyTo(readBackBuffer, destinationOffset, bufferOffset, count);

            Assert.AreEqual(source.Length, readBackBuffer.Length);
            Assert.IsTrue(source.AsSpan(bufferOffset, count).SequenceEqual(readBackBuffer.Span.Slice(destinationOffset, count)));
        }
Пример #5
0
        public void Allocate_ReadBackBuffer_Copy_Full(Device device)
        {
            int[] source = new int[4096];

            new Random(42).NextBytes(source.AsSpan().AsBytes());

            using ReadOnlyBuffer <int> readOnlyBuffer = device.Get().AllocateReadOnlyBuffer(source);
            using ReadBackBuffer <int> readBackBuffer = device.Get().AllocateReadBackBuffer <int>(readOnlyBuffer.Length);

            readOnlyBuffer.CopyTo(readBackBuffer);

            Assert.AreEqual(source.Length, readBackBuffer.Length);
            Assert.IsTrue(source.AsSpan().SequenceEqual(readBackBuffer.Span));
        }