Exemplo n.º 1
0
        public unsafe static void WriteNumeric(ref WritableBufferWriter buffer, ulong number)
        {
            const byte AsciiDigitStart = (byte)'0';

            var span             = buffer.Span;
            var bytesLeftInBlock = span.Length;

            // Fast path, try copying to the available memory directly
            var simpleWrite = true;

            fixed(byte *output = &span.DangerousGetPinnableReference())
            {
                var start = output;

                if (number < 10 && bytesLeftInBlock >= 1)
                {
                    *(start) = (byte)(((uint)number) + AsciiDigitStart);
                    buffer.Advance(1);
                }
                else if (number < 100 && bytesLeftInBlock >= 2)
                {
                    var val  = (uint)number;
                    var tens = (byte)((val * 205u) >> 11); // div10, valid to 1028

                    *(start)     = (byte)(tens + AsciiDigitStart);
                    *(start + 1) = (byte)(val - (tens * 10) + AsciiDigitStart);
                    buffer.Advance(2);
                }
                else if (number < 1000 && bytesLeftInBlock >= 3)
                {
                    var val      = (uint)number;
                    var digit0   = (byte)((val * 41u) >> 12);  // div100, valid to 1098
                    var digits01 = (byte)((val * 205u) >> 11); // div10, valid to 1028

                    *(start)     = (byte)(digit0 + AsciiDigitStart);
                    *(start + 1) = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart);
                    *(start + 2) = (byte)(val - (digits01 * 10) + AsciiDigitStart);
                    buffer.Advance(3);
                }
                else
                {
                    simpleWrite = false;
                }
            }

            if (!simpleWrite)
            {
                WriteNumericMultiWrite(ref buffer, number);
            }
        }
Exemplo n.º 2
0
        public unsafe static void WriteAsciiNoValidation(ref WritableBufferWriter buffer, string data)
        {
            if (string.IsNullOrEmpty(data))
            {
                return;
            }

            var dest         = buffer.Span;
            var destLength   = dest.Length;
            var sourceLength = data.Length;

            // Fast path, try copying to the available memory directly
            if (sourceLength <= destLength)
            {
                fixed(char *input = data)
                fixed(byte *output = &dest.DangerousGetPinnableReference())
                {
                    EncodeAsciiCharsToBytes(input, output, sourceLength);
                }

                buffer.Advance(sourceLength);
            }
            else
            {
                WriteAsciiMultiWrite(ref buffer, data);
            }
        }
Exemplo n.º 3
0
        private unsafe static void WriteAsciiMultiWrite(ref WritableBufferWriter buffer, string data)
        {
            var remaining = data.Length;

            fixed(char *input = data)
            {
                var inputSlice = input;

                while (remaining > 0)
                {
                    var writable = Math.Min(remaining, buffer.Span.Length);

                    if (writable == 0)
                    {
                        buffer.Ensure();
                        continue;
                    }

                    fixed(byte *output = &buffer.Span.DangerousGetPinnableReference())
                    {
                        EncodeAsciiCharsToBytes(inputSlice, output, writable);
                    }

                    inputSlice += writable;
                    remaining  -= writable;

                    buffer.Advance(writable);
                }
            }
        }