﻿#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if GOOGLE_PROTOBUF_SIMD
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
#endif
using System.Security;
using System.Text;

namespace Google.Protobuf
{
    /// <summary>
    /// Primitives for encoding protobuf wire format.
    /// </summary>
    [SecuritySafeCritical]
    internal static class WritingPrimitives
    {
#if NET5_0
        internal static Encoding Utf8Encoding => Encoding.UTF8; // allows JIT to devirtualize
#else
        internal static readonly Encoding Utf8Encoding = Encoding.UTF8; // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
#endif

        #region Writing of values (not including tags)

        /// <summary>
        /// Writes a double field value, without a tag, to the stream.
        /// </summary>
        public static void WriteDouble(ref Span<byte> buffer, ref WriterInternalState state, double value)
        {
            WriteRawLittleEndian64(ref buffer, ref state, (ulong)BitConverter.DoubleToInt64Bits(value));
        }

        /// <summary>
        /// Writes a float field value, without a tag, to the stream.
        /// </summary>
        public static unsafe void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
        {
            const int length = sizeof(float);
            if (buffer.Length - state.position >= length)
            {
                // if there's enough space in the buffer, write the float directly into the buffer
                var floatSpan = buffer.Slice(state.position, length);
                Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);

                if (!BitConverter.IsLittleEndian)
                {
                    floatSpan.Reverse();
                }
                state.position += length;
            }
            else
            {
                WriteFloatSlowPath(ref buffer, ref state, value);
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static unsafe void WriteFloatSlowPath(ref Span<byte> buffer, ref WriterInternalState state, float value)
        {
            const int length = sizeof(float);

            // TODO(jtattermusch): deduplicate the code. Populating the span is the same as for the fastpath.
            Span<byte> floatSpan = stackalloc byte[length];
            Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
            if (!BitConverter.IsLittleEndian)
            {
                floatSpan.Reverse();
            }

            WriteRawByte(ref buffer, ref state, floatSpan[0]);
            WriteRawByte(ref buffer, ref state, floatSpan[1]);
            WriteRawByte(ref buffer, ref state, floatSpan[2]);
            WriteRawByte(ref buffer, ref state, floatSpan[3]);
        }

        /// <summary>
        /// Writes a uint64 field value, without a tag, to the stream.
        /// </summary>
        public static void WriteUInt64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
        {
            WriteRawVarint64(ref buffer, ref state, value);
        }

        /// <summary>
        /// Writes an int64 field value, without a tag, to the stream.
        /// </summary>
        public static void WriteInt64(ref Span<byte> buffer, ref WriterInternalState state, long value)
        {
            WriteRawVarint64(ref buffer, ref state, (ulong)value);
        }

        /// <summary>
        /// Writes an int32 field value, without a tag, to the stream.
        /// </summary>
        public static void WriteInt32(ref Span<byte> buffer, ref WriterInternalState state, int value)
        {
            if (value >= 0)
            {
                WriteRawVarint32(ref buffer, ref state, (uint)value);
            }
            else
            {
                // Must sign-extend.
                WriteRawVarint64(ref buffer, ref state, (ulong)value);
            }
        }

        /// <summary>
        /// Writes a fixed64 field value, without a tag, to the stream.
        /// </summary>
        public static void WriteFixed64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
        {
            WriteRawLittleEndian64(ref buffer, ref state, value);
        }

        /// <summary>
        /// Writes a fixed32 field value, without a tag, to the stream.
        /// </summary>
        public static void WriteFixed32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
        {
            WriteRawLittleEndian32(ref buffer, ref state, value);
        }

        /// <summary>
        /// Writes a bool field value, without a tag, to the stream.
        /// </summary>
        public static void WriteBool(ref Span<byte> buffer, ref WriterInternalState state, bool value)
        {
            WriteRawByte(ref buffer, ref state, value ? (byte)1 : (byte)0);
        }

        /// <summary>
        /// Writes a string field value, without a tag, to the stream.
        /// The data is length-prefixed.
        /// </summary>
        public static void WriteString(ref Span<byte> buffer, ref WriterInternalState state, string value)
        {
            const int MaxBytesPerChar = 3;
            const int MaxSmallStringLength = 128 / MaxBytesPerChar;

            // The string is small enough that the length will always be a 1 byte varint.
            // Also there is enough space to write length + bytes to buffer.
            // Write string directly to the buffer, and then write length.
            // This saves calling GetByteCount on the string. We get the string length from GetBytes.
            if (value.Length <= MaxSmallStringLength && buffer.Length - state.position - 1 >= value.Length * MaxBytesPerChar)
            {
                int indexOfLengthDelimiter = state.position++;
                buffer[indexOfLengthDelimiter] = (byte)WriteStringToBuffer(buffer, ref state, value);
                return;
            }

            int length = Utf8Encoding.GetByteCount(value);
            WriteLength(ref buffer, ref state, length);

            // Optimise the case where we have enough space to write
            // the string directly to the buffer, which should be common.
            if (buffer.Length - state.position >= length)
            {
                if (length == value.Length) // Must be all ASCII...
                {
                    WriteAsciiStringToBuffer(buffer, ref state, value, length);
                }
                else
                {
                    WriteStringToBuffer(buffer, ref state, value);
                }
            }
            else
            {
                // Opportunity for future optimization:
                // Large strings that don't fit into the current buffer segment
                // can probably be optimized by using Utf8Encoding.GetEncoder()
                // but more benchmarks would need to be added as evidence.
                byte[] bytes = Utf8Encoding.GetBytes(value);
                WriteRawBytes(ref buffer, ref state, bytes);
            }
        }

        // Calling this method with non-ASCII content will break.
        // Content must be verified to be all ASCII before using this method.
        private static void WriteAsciiStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value, int length)
        {
            ref char sourceChars = ref MemoryMarshal.GetReference(value.AsSpan());
            ref byte destinationBytes = ref MemoryMarshal.GetReference(buffer.Slice(state.position));

            int currentIndex = 0;
            // If 64bit, process 4 chars at a time.
            // The logic inside this check will be elided by JIT in 32bit programs.
            if (IntPtr.Size == 8)
            {
                // Need at least 4 chars available to use this optimization. 
                if (length >= 4)
                {
                    ref byte sourceBytes = ref Unsafe.As<char, byte>(ref sourceChars);

                    // Process 4 chars at a time until there are less than 4 remaining.
                    // We already know all characters are ASCII so there is no need to validate the source.
                    int lastIndexWhereCanReadFourChars = value.Length - 4;
                    do
                    {
                        NarrowFourUtf16CharsToAsciiAndWriteToBuffer(
                            ref Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex),
                            Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref sourceBytes, (IntPtr)(currentIndex * 2))));

                    } while ((currentIndex += 4) <= lastIndexWhereCanReadFourChars);
                }
            }

            // Process any remaining, 1 char at a time.
            // Avoid bounds checking with ref + Unsafe
            for (; currentIndex < length; currentIndex++)
            {
                Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex) = (byte)Unsafe.AddByteOffset(ref sourceChars, (IntPtr)(currentIndex * 2));
            }

            state.position += length;
        }

        // Copied with permission from https://github.com/dotnet/runtime/blob/1cdafd27e4afd2c916af5df949c13f8b373c4335/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs#L1119-L1171
        //
        /// <summary>
        /// Given a QWORD which represents a buffer of 4 ASCII chars in machine-endian order,
        /// narrows each WORD to a BYTE, then writes the 4-byte result to the output buffer
        /// also in machine-endian order.
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, ulong value)
        {
#if GOOGLE_PROTOBUF_SIMD
            if (Sse2.X64.IsSupported)
            {
                // Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
                // [ b0 b1 b2 b3 b0 b1 b2 b3 ], then writes 4 bytes (32 bits) to the destination.

                Vector128<short> vecWide = Sse2.X64.ConvertScalarToVector128UInt64(value).AsInt16();
                Vector128<uint> vecNarrow = Sse2.PackUnsignedSaturate(vecWide, vecWide).AsUInt32();
                Unsafe.WriteUnaligned<uint>(ref outputBuffer, Sse2.ConvertToUInt32(vecNarrow));
            }
            else if (AdvSimd.IsSupported)
            {
                // Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
                // [ b0 b1 b2 b3 * * * * ], then writes 4 bytes (32 bits) to the destination.

                Vector128<short> vecWide = Vector128.CreateScalarUnsafe(value).AsInt16();
                Vector64<byte> lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(vecWide);
                Unsafe.WriteUnaligned<uint>(ref outputBuffer, lower.AsUInt32().ToScalar());
            }
            else
#endif
            {
                // Fallback to non-SIMD approach when SIMD is not available.
                // This could happen either because the APIs are not available, or hardware doesn't support it.
                // Processing 4 chars at a time in this fallback is still faster than casting one char at a time.
                if (BitConverter.IsLittleEndian)
                {
                    outputBuffer = (byte)value;
                    value >>= 16;
                    Unsafe.Add(ref outputBuffer, 1) = (byte)value;
                    value >>= 16;
                    Unsafe.Add(ref outputBuffer, 2) = (byte)value;
                    value >>= 16;
                    Unsafe.Add(ref outputBuffer, 3) = (byte)value;
                }
                else
                {
                    Unsafe.Add(ref outputBuffer, 3) = (byte)value;
                    value >>= 16;
                    Unsafe.Add(ref outputBuffer, 2) = (byte)value;
                    value >>= 16;
                    Unsafe.Add(ref outputBuffer, 1) = (byte)value;
                    value >>= 16;
                    outputBuffer = (byte)value;
                }
            }
        }

        private static int WriteStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value)
        {
#if NETSTANDARD1_1
            // slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
            byte[] bytes = Utf8Encoding.GetBytes(value);
            WriteRawBytes(ref buffer, ref state, bytes);
            return bytes.Length;
#else
            ReadOnlySpan<char> source = value.AsSpan();
            int bytesUsed;
            unsafe
            {
                fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
                fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer))
                {
                    bytesUsed = Utf8Encoding.GetBytes(
                        sourceChars,
                        source.Length,
                        destinationBytes + state.position,
                        buffer.Length - state.position);
                }
            }
            state.position += bytesUsed;
            return bytesUsed;
#endif
        }

        /// <summary>
        /// Write a byte string, without a tag, to the stream.
        /// The data is length-prefixed.
        /// </summary>
        public static void WriteBytes(ref Span<byte> buffer, ref WriterInternalState state, ByteString value)
        {
            WriteLength(ref buffer, ref state, value.Length);
            WriteRawBytes(ref buffer, ref state, value.Span);
        }

        /// <summary>
        /// Writes a uint32 value, without a tag, to the stream.
        /// </summary>
        public static void WriteUInt32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
        {
            WriteRawVarint32(ref buffer, ref state, value);
        }

        /// <summary>
        /// Writes an enum value, without a tag, to the stream.
        /// </summary>
        public static void WriteEnum(ref Span<byte> buffer, ref WriterInternalState state, int value)
        {
            WriteInt32(ref buffer, ref state, value);
        }

        /// <summary>
        /// Writes an sfixed32 value, without a tag, to the stream.
        /// </summary>
        public static void WriteSFixed32(ref Span<byte> buffer, ref WriterInternalState state, int value)
        {
            WriteRawLittleEndian32(ref buffer, ref state, (uint)value);
        }

        /// <summary>
        /// Writes an sfixed64 value, without a tag, to the stream.
        /// </summary>
        public static void WriteSFixed64(ref Span<byte> buffer, ref WriterInternalState state, long value)
        {
            WriteRawLittleEndian64(ref buffer, ref state, (ulong)value);
        }

        /// <summary>
        /// Writes an sint32 value, without a tag, to the stream.
        /// </summary>
        public static void WriteSInt32(ref Span<byte> buffer, ref WriterInternalState state, int value)
        {
            WriteRawVarint32(ref buffer, ref state, EncodeZigZag32(value));
        }

        /// <summary>
        /// Writes an sint64 value, without a tag, to the stream.
        /// </summary>
        public static void WriteSInt64(ref Span<byte> buffer, ref WriterInternalState state, long value)
        {
            WriteRawVarint64(ref buffer, ref state, EncodeZigZag64(value));
        }

        /// <summary>
        /// Writes a length (in bytes) for length-delimited data.
        /// </summary>
        /// <remarks>
        /// This method simply writes a rawint, but exists for clarity in calling code.
        /// </remarks>
        public static void WriteLength(ref Span<byte> buffer, ref WriterInternalState state, int length)
        {
            WriteRawVarint32(ref buffer, ref state, (uint)length);
        }

        #endregion

        #region Writing primitives
        /// <summary>
        /// Writes a 32 bit value as a varint. The fast route is taken when
        /// there's enough buffer space left to whizz through without checking
        /// for each byte; otherwise, we resort to calling WriteRawByte each time.
        /// </summary>
        public static void WriteRawVarint32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
        {
            // Optimize for the common case of a single byte value
            if (value < 128 && state.position < buffer.Length)
            {
                buffer[state.position++] = (byte)value;
                return;
            }

            // Fast path when capacity is available
            while (state.position < buffer.Length)
            {
                if (value > 127)
                {
                    buffer[state.position++] = (byte)((value & 0x7F) | 0x80);
                    value >>= 7;
                }
                else
                {
                    buffer[state.position++] = (byte)value;
                    return;
                }
            }

            while (value > 127)
            {
                WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80));
                value >>= 7;
            }

            WriteRawByte(ref buffer, ref state, (byte)value);
        }

        public static void WriteRawVarint64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
        {
            // Optimize for the common case of a single byte value
            if (value < 128 && state.position < buffer.Length)
            {
                buffer[state.position++] = (byte)value;
                return;
            }

            // Fast path when capacity is available
            while (state.position < buffer.Length)
            {
                if (value > 127)
                {
                    buffer[state.position++] = (byte)((value & 0x7F) | 0x80);
                    value >>= 7;
                }
                else
                {
                    buffer[state.position++] = (byte)value;
                    return;
                }
            }

            while (value > 127)
            {
                WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80));
                value >>= 7;
            }

            WriteRawByte(ref buffer, ref state, (byte)value);
        }

        public static void WriteRawLittleEndian32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
        {
            const int length = sizeof(uint);
            if (state.position + length > buffer.Length)
            {
                WriteRawLittleEndian32SlowPath(ref buffer, ref state, value);
            }
            else
            {
                BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(state.position), value);
                state.position += length;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void WriteRawLittleEndian32SlowPath(ref Span<byte> buffer, ref WriterInternalState state, uint value)
        {
            WriteRawByte(ref buffer, ref state, (byte)value);
            WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
        }

        public static void WriteRawLittleEndian64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
        {
            const int length = sizeof(ulong);
            if (state.position + length > buffer.Length)
            {
                WriteRawLittleEndian64SlowPath(ref buffer, ref state, value);
            }
            else
            {
                BinaryPrimitives.WriteUInt64LittleEndian(buffer.Slice(state.position), value);
                state.position += length;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        public static void WriteRawLittleEndian64SlowPath(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
        {
            WriteRawByte(ref buffer, ref state, (byte)value);
            WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 32));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 40));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 48));
            WriteRawByte(ref buffer, ref state, (byte)(value >> 56));
        }

        private static void WriteRawByte(ref Span<byte> buffer, ref WriterInternalState state, byte value)
        {
            if (state.position == buffer.Length)
            {
                WriteBufferHelper.RefreshBuffer(ref buffer, ref state);
            }

            buffer[state.position++] = value;
        }

        /// <summary>
        /// Writes out an array of bytes.
        /// </summary>
        public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, byte[] value)
        {
            WriteRawBytes(ref buffer, ref state, new ReadOnlySpan<byte>(value));
        }

        /// <summary>
        /// Writes out part of an array of bytes.
        /// </summary>
        public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, byte[] value, int offset, int length)
        {
            WriteRawBytes(ref buffer, ref state, new ReadOnlySpan<byte>(value, offset, length));
        }

        /// <summary>
        /// Writes out part of an array of bytes.
        /// </summary>
        public static void WriteRawBytes(ref Span<byte> buffer, ref WriterInternalState state, ReadOnlySpan<byte> value)
        {
            if (buffer.Length - state.position >= value.Length)
            {
                // We have room in the current buffer.    
                value.CopyTo(buffer.Slice(state.position, value.Length));
                state.position += value.Length;
            }
            else
            {
                // When writing to a CodedOutputStream backed by a Stream, we could avoid
                // copying the data twice (first copying to the current buffer and
                // and later writing from the current buffer to the underlying Stream)
                // in some circumstances by writing the data directly to the underlying Stream.
                // Current this is not being done to avoid specialcasing the code for
                // CodedOutputStream vs IBufferWriter<byte>.
                int bytesWritten = 0;
                while (buffer.Length - state.position < value.Length - bytesWritten)
                {
                    int length = buffer.Length - state.position;
                    value.Slice(bytesWritten, length).CopyTo(buffer.Slice(state.position, length));
                    bytesWritten += length;
                    state.position += length;
                    WriteBufferHelper.RefreshBuffer(ref buffer, ref state);
                }

                // copy the remaining data
                int remainderLength = value.Length - bytesWritten;
                value.Slice(bytesWritten, remainderLength).CopyTo(buffer.Slice(state.position, remainderLength));
                state.position += remainderLength;
            }
        }
        #endregion

        #region Raw tag writing
        /// <summary>
        /// Encodes and writes a tag.
        /// </summary>
        public static void WriteTag(ref Span<byte> buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type)
        {
            WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type));
        }

        /// <summary>
        /// Writes an already-encoded tag.
        /// </summary>
        public static void WriteTag(ref Span<byte> buffer, ref WriterInternalState state, uint tag)
        {
            WriteRawVarint32(ref buffer, ref state, tag);
        }

        /// <summary>
        /// Writes the given single-byte tag directly to the stream.
        /// </summary>
        public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1)
        {
            WriteRawByte(ref buffer, ref state, b1);
        }

        /// <summary>
        /// Writes the given two-byte tag directly to the stream.
        /// </summary>
        public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
        {
            if (state.position + 2 > buffer.Length)
            {
                WriteRawTagSlowPath(ref buffer, ref state, b1, b2);
            }
            else
            {
                buffer[state.position++] = b1;
                buffer[state.position++] = b2;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
        {
            WriteRawByte(ref buffer, ref state, b1);
            WriteRawByte(ref buffer, ref state, b2);
        }

        /// <summary>
        /// Writes the given three-byte tag directly to the stream.
        /// </summary>
        public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
        {
            if (state.position + 3 > buffer.Length)
            {
                WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3);
            }
            else
            {
                buffer[state.position++] = b1;
                buffer[state.position++] = b2;
                buffer[state.position++] = b3;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
        {
            WriteRawByte(ref buffer, ref state, b1);
            WriteRawByte(ref buffer, ref state, b2);
            WriteRawByte(ref buffer, ref state, b3);
        }

        /// <summary>
        /// Writes the given four-byte tag directly to the stream.
        /// </summary>
        public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
        {
            if (state.position + 4 > buffer.Length)
            {
                WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4);
            }
            else
            {
                buffer[state.position++] = b1;
                buffer[state.position++] = b2;
                buffer[state.position++] = b3;
                buffer[state.position++] = b4;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]

        private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
        {
            WriteRawByte(ref buffer, ref state, b1);
            WriteRawByte(ref buffer, ref state, b2);
            WriteRawByte(ref buffer, ref state, b3);
            WriteRawByte(ref buffer, ref state, b4);
        }

        /// <summary>
        /// Writes the given five-byte tag directly to the stream.
        /// </summary>
        public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
        {
            if (state.position + 5 > buffer.Length)
            {
                WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5);
            }
            else
            {
                buffer[state.position++] = b1;
                buffer[state.position++] = b2;
                buffer[state.position++] = b3;
                buffer[state.position++] = b4;
                buffer[state.position++] = b5;
            }
        }

        [MethodImpl(MethodImplOptions.NoInlining)]
        private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
        {
            WriteRawByte(ref buffer, ref state, b1);
            WriteRawByte(ref buffer, ref state, b2);
            WriteRawByte(ref buffer, ref state, b3);
            WriteRawByte(ref buffer, ref state, b4);
            WriteRawByte(ref buffer, ref state, b5);
        }
        #endregion

        /// <summary>
        /// Encode a 32-bit value with ZigZag encoding.
        /// </summary>
        /// <remarks>
        /// ZigZag encodes signed integers into values that can be efficiently
        /// encoded with varint.  (Otherwise, negative values must be 
        /// sign-extended to 64 bits to be varint encoded, thus always taking
        /// 10 bytes on the wire.)
        /// </remarks>
        public static uint EncodeZigZag32(int n)
        {
            // Note:  the right-shift must be arithmetic
            return (uint)((n << 1) ^ (n >> 31));
        }

        /// <summary>
        /// Encode a 64-bit value with ZigZag encoding.
        /// </summary>
        /// <remarks>
        /// ZigZag encodes signed integers into values that can be efficiently
        /// encoded with varint.  (Otherwise, negative values must be 
        /// sign-extended to 64 bits to be varint encoded, thus always taking
        /// 10 bytes on the wire.)
        /// </remarks>
        public static ulong EncodeZigZag64(long n)
        {
            return (ulong)((n << 1) ^ (n >> 63));
        }
    }
}