コード例 #1
0
 public void WriteQuotation()
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = (byte)'\"';
 }
コード例 #2
0
        public void WriteString(string value)
        {
            if (value == null)
            {
                WriteNull();
                return;
            }

            // single-path escape

            // nonescaped-ensure
            var startOffset = Offset;
            var max         = StringEncoding.UTF8.GetMaxByteCount(value.Length) + 2;

            BinaryUtil.EnsureCapacity(ref Buffer, startOffset, max);

            var from = 0;

            Buffer[Offset++] = (byte)'\"';

            // for JIT Optimization, for-loop i < str.Length
            for (var i = 0; i < value.Length; i++)
            {
                byte escapeChar = default;
                switch (value[i])
                {
                case '"':
                    escapeChar = (byte)'"';
                    break;

                case '\\':
                    escapeChar = (byte)'\\';
                    break;

                case '\b':
                    escapeChar = (byte)'b';
                    break;

                case '\f':
                    escapeChar = (byte)'f';
                    break;

                case '\n':
                    escapeChar = (byte)'n';
                    break;

                case '\r':
                    escapeChar = (byte)'r';
                    break;

                case '\t':
                    escapeChar = (byte)'t';
                    break;

                case (char)0:
                case (char)1:
                case (char)2:
                case (char)3:
                case (char)4:
                case (char)5:
                case (char)6:
                case (char)7:
                case (char)11:
                case (char)14:
                case (char)15:
                case (char)16:
                case (char)17:
                case (char)18:
                case (char)19:
                case (char)20:
                case (char)21:
                case (char)22:
                case (char)23:
                case (char)24:
                case (char)25:
                case (char)26:
                case (char)27:
                case (char)28:
                case (char)29:
                case (char)30:
                case (char)31:
                case '\u0085':
                case '\u2028':
                case '\u2029':
                    break;

                default:
                    continue;
                }

                max += escapeChar == default ? 6 : 2;
                BinaryUtil.EnsureCapacity(ref Buffer, startOffset, max);                 // check +escape capacity
                Offset += StringEncoding.UTF8.GetBytes(value, from, i - from, Buffer, Offset);
                from    = i + 1;

                if (escapeChar == default)
                {
                    ToUnicode(value[i], ref Offset, Buffer);
                }
                else
                {
                    Buffer[Offset++] = (byte)'\\';
                    Buffer[Offset++] = escapeChar;
                }
            }

            if (from != value.Length)
            {
                Offset += StringEncoding.UTF8.GetBytes(value, @from, value.Length - @from, Buffer, Offset);
            }

            Buffer[Offset++] = (byte)'\"';
        }
コード例 #3
0
 public void WriteEndObject()
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = (byte)'}';
 }
コード例 #4
0
 public void WriteNameSeparator()
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = (byte)':';
 }
コード例 #5
0
 public void WriteRaw(byte rawValue)
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = rawValue;
 }
コード例 #6
0
 public void WriteEndArray()
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = (byte)']';
 }
コード例 #7
0
 public byte[] ToUtf8ByteArray() =>
                 Buffer == null
                         ? Array.Empty <byte>()
                         : BinaryUtil.FastCloneWithResize(Buffer, Offset);
コード例 #8
0
 public void EnsureCapacity(int appendLength) => BinaryUtil.EnsureCapacity(ref Buffer, Offset, appendLength);
コード例 #9
0
        public static int WriteInt64(ref byte[] buffer, int offset, long value)
        {
            var startOffset = offset;

            long num1 = value, num2, num3, num4, num5, div;

            if (value < 0)
            {
                if (value == long.MinValue)                 // -9223372036854775808
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 20);
                    buffer[offset++] = (byte)'-';
                    buffer[offset++] = (byte)'9';
                    buffer[offset++] = (byte)'2';
                    buffer[offset++] = (byte)'2';
                    buffer[offset++] = (byte)'3';
                    buffer[offset++] = (byte)'3';
                    buffer[offset++] = (byte)'7';
                    buffer[offset++] = (byte)'2';
                    buffer[offset++] = (byte)'0';
                    buffer[offset++] = (byte)'3';
                    buffer[offset++] = (byte)'6';
                    buffer[offset++] = (byte)'8';
                    buffer[offset++] = (byte)'5';
                    buffer[offset++] = (byte)'4';
                    buffer[offset++] = (byte)'7';
                    buffer[offset++] = (byte)'7';
                    buffer[offset++] = (byte)'5';
                    buffer[offset++] = (byte)'8';
                    buffer[offset++] = (byte)'0';
                    buffer[offset++] = (byte)'8';
                    return(offset - startOffset);
                }

                BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
                buffer[offset++] = (byte)'-';
                num1             = unchecked (-value);
            }

            // WriteUInt64(inlined)

            if (num1 < 10000)
            {
                if (num1 < 10)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
                    goto L1;
                }
                if (num1 < 100)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 2);
                    goto L2;
                }
                if (num1 < 1000)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 3);
                    goto L3;
                }
                BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
                goto L4;
            }
            else
            {
                num2  = num1 / 10000;
                num1 -= num2 * 10000;
                if (num2 < 10000)
                {
                    if (num2 < 10)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 5);
                        goto L5;
                    }
                    if (num2 < 100)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 6);
                        goto L6;
                    }
                    if (num2 < 1000)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 7);
                        goto L7;
                    }
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 8);
                    goto L8;
                }
                else
                {
                    num3  = num2 / 10000;
                    num2 -= num3 * 10000;
                    if (num3 < 10000)
                    {
                        if (num3 < 10)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 9);
                            goto L9;
                        }
                        if (num3 < 100)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 10);
                            goto L10;
                        }
                        if (num3 < 1000)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 11);
                            goto L11;
                        }
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 12);
                        goto L12;
                    }
                    else
                    {
                        num4  = num3 / 10000;
                        num3 -= num4 * 10000;
                        if (num4 < 10000)
                        {
                            if (num4 < 10)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 13);
                                goto L13;
                            }
                            if (num4 < 100)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 14);
                                goto L14;
                            }
                            if (num4 < 1000)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 15);
                                goto L15;
                            }
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 16);
                            goto L16;
                        }
                        else
                        {
                            num5  = num4 / 10000;
                            num4 -= num5 * 10000;
                            if (num5 < 10000)
                            {
                                if (num5 < 10)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 17);
                                    goto L17;
                                }
                                if (num5 < 100)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 18);
                                    goto L18;
                                }
                                if (num5 < 1000)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 19);
                                    goto L19;
                                }
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 20);
                                goto L20;
                            }
L20:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 8389L) >> 23));
                            num5            -= div * 1000;
L19:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 5243L) >> 19));
                            num5            -= div * 100;
L18:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 6554L) >> 16));
                            num5            -= div * 10;
L17:
                            buffer[offset++] = (byte)('0' + (num5));
                        }
L16:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 8389L) >> 23));
                        num4            -= div * 1000;
L15:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 5243L) >> 19));
                        num4            -= div * 100;
L14:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 6554L) >> 16));
                        num4            -= div * 10;
L13:
                        buffer[offset++] = (byte)('0' + (num4));
                    }
L12:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 8389L) >> 23));
                    num3            -= div * 1000;
L11:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 5243L) >> 19));
                    num3            -= div * 100;
L10:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 6554L) >> 16));
                    num3            -= div * 10;
L9:
                    buffer[offset++] = (byte)('0' + (num3));
                }
L8:
                buffer[offset++] = (byte)('0' + (div = (num2 * 8389L) >> 23));
                num2            -= div * 1000;
L7:
                buffer[offset++] = (byte)('0' + (div = (num2 * 5243L) >> 19));
                num2            -= div * 100;
L6:
                buffer[offset++] = (byte)('0' + (div = (num2 * 6554L) >> 16));
                num2            -= div * 10;
L5:
                buffer[offset++] = (byte)('0' + (num2));
            }
L4:
            buffer[offset++] = (byte)('0' + (div = (num1 * 8389L) >> 23));
            num1            -= div * 1000;
L3:
            buffer[offset++] = (byte)('0' + (div = (num1 * 5243L) >> 19));
            num1            -= div * 100;
L2:
            buffer[offset++] = (byte)('0' + (div = (num1 * 6554L) >> 16));
            num1            -= div * 10;
L1:
            buffer[offset++] = (byte)('0' + (num1));

            return(offset - startOffset);
        }
コード例 #10
0
        public static int WriteUInt64(ref byte[] buffer, int offset, ulong value)
        {
            var startOffset = offset;

            ulong num1 = value, num2, num3, num4, num5, div;

            if (num1 < 10000)
            {
                if (num1 < 10)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
                    goto L1;
                }
                if (num1 < 100)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 2);
                    goto L2;
                }
                if (num1 < 1000)
                {
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 3);
                    goto L3;
                }
                BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
                goto L4;
            }
            else
            {
                num2  = num1 / 10000;
                num1 -= num2 * 10000;
                if (num2 < 10000)
                {
                    if (num2 < 10)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 5);
                        goto L5;
                    }
                    if (num2 < 100)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 6);
                        goto L6;
                    }
                    if (num2 < 1000)
                    {
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 7);
                        goto L7;
                    }
                    BinaryUtil.EnsureCapacity(ref buffer, offset, 8);
                    goto L8;
                }
                else
                {
                    num3  = num2 / 10000;
                    num2 -= num3 * 10000;
                    if (num3 < 10000)
                    {
                        if (num3 < 10)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 9);
                            goto L9;
                        }
                        if (num3 < 100)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 10);
                            goto L10;
                        }
                        if (num3 < 1000)
                        {
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 11);
                            goto L11;
                        }
                        BinaryUtil.EnsureCapacity(ref buffer, offset, 12);
                        goto L12;
                    }
                    else
                    {
                        num4  = num3 / 10000;
                        num3 -= num4 * 10000;
                        if (num4 < 10000)
                        {
                            if (num4 < 10)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 13);
                                goto L13;
                            }
                            if (num4 < 100)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 14);
                                goto L14;
                            }
                            if (num4 < 1000)
                            {
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 15);
                                goto L15;
                            }
                            BinaryUtil.EnsureCapacity(ref buffer, offset, 16);
                            goto L16;
                        }
                        else
                        {
                            num5  = num4 / 10000;
                            num4 -= num5 * 10000;
                            if (num5 < 10000)
                            {
                                if (num5 < 10)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 17);
                                    goto L17;
                                }
                                if (num5 < 100)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 18);
                                    goto L18;
                                }
                                if (num5 < 1000)
                                {
                                    BinaryUtil.EnsureCapacity(ref buffer, offset, 19);
                                    goto L19;
                                }
                                BinaryUtil.EnsureCapacity(ref buffer, offset, 20);
                                goto L20;
                            }
L20:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 8389UL) >> 23));
                            num5            -= div * 1000;
L19:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 5243UL) >> 19));
                            num5            -= div * 100;
L18:
                            buffer[offset++] = (byte)('0' + (div = (num5 * 6554UL) >> 16));
                            num5            -= div * 10;
L17:
                            buffer[offset++] = (byte)('0' + (num5));
                        }
L16:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 8389UL) >> 23));
                        num4            -= div * 1000;
L15:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 5243UL) >> 19));
                        num4            -= div * 100;
L14:
                        buffer[offset++] = (byte)('0' + (div = (num4 * 6554UL) >> 16));
                        num4            -= div * 10;
L13:
                        buffer[offset++] = (byte)('0' + (num4));
                    }
L12:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 8389UL) >> 23));
                    num3            -= div * 1000;
L11:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 5243UL) >> 19));
                    num3            -= div * 100;
L10:
                    buffer[offset++] = (byte)('0' + (div = (num3 * 6554UL) >> 16));
                    num3            -= div * 10;
L9:
                    buffer[offset++] = (byte)('0' + (num3));
                }
L8:
                buffer[offset++] = (byte)('0' + (div = (num2 * 8389UL) >> 23));
                num2            -= div * 1000;
L7:
                buffer[offset++] = (byte)('0' + (div = (num2 * 5243UL) >> 19));
                num2            -= div * 100;
L6:
                buffer[offset++] = (byte)('0' + (div = (num2 * 6554UL) >> 16));
                num2            -= div * 10;
L5:
                buffer[offset++] = (byte)('0' + (num2));
            }
L4:
            buffer[offset++] = (byte)('0' + (div = (num1 * 8389UL) >> 23));
            num1            -= div * 1000;
L3:
            buffer[offset++] = (byte)('0' + (div = (num1 * 5243UL) >> 19));
            num1            -= div * 100;
L2:
            buffer[offset++] = (byte)('0' + (div = (num1 * 6554UL) >> 16));
            num1            -= div * 10;
L1:
            buffer[offset++] = (byte)('0' + (num1));

            return(offset - startOffset);
        }
コード例 #11
0
 public void AddStringSlow(string str)
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, StringEncoding.UTF8.GetMaxByteCount(str.Length));
     Offset += StringEncoding.UTF8.GetBytes(str, 0, str.Length, Buffer, Offset);
 }
コード例 #12
0
 public void AddCharacter(byte str)
 {
     BinaryUtil.EnsureCapacity(ref Buffer, Offset, 1);
     Buffer[Offset++] = str;
 }
コード例 #13
0
        private void ReadStringSegmentCore(out byte[] resultBytes, out int resultOffset, out int resultLength)
        {
            // SkipWhiteSpace is already called from IsNull

            byte[] builder       = null;
            var    builderOffset = 0;

            char[] codePointStringBuffer = null;
            var    codePointStringOffet  = 0;

            if (_bytes[_offset] != '\"')
            {
                throw CreateParsingException("String Begin Token");
            }

            _offset++;

            var from = _offset;

            // eliminate array-bound check
            for (var i = _offset; i < _bytes.Length; i++)
            {
                byte escapeCharacter = 0;
                switch (_bytes[i])
                {
                case (byte)'\\':                         // escape character
                    switch ((char)_bytes[i + 1])
                    {
                    case '"':
                    case '\\':
                    case '/':
                        escapeCharacter = _bytes[i + 1];
                        goto COPY;

                    case 'b':
                        escapeCharacter = (byte)'\b';
                        goto COPY;

                    case 'f':
                        escapeCharacter = (byte)'\f';
                        goto COPY;

                    case 'n':
                        escapeCharacter = (byte)'\n';
                        goto COPY;

                    case 'r':
                        escapeCharacter = (byte)'\r';
                        goto COPY;

                    case 't':
                        escapeCharacter = (byte)'\t';
                        goto COPY;

                    case 'u':
                        codePointStringBuffer ??= StringBuilderCache.GetCodePointStringBuffer();

                        if (codePointStringOffet == 0)
                        {
                            builder ??= StringBuilderCache.GetBuffer();

                            var copyCount = i - from;
                            BinaryUtil.EnsureCapacity(ref builder, builderOffset, copyCount + 1);                                             // require + 1
                            Buffer.BlockCopy(_bytes, from, builder, builderOffset, copyCount);
                            builderOffset += copyCount;
                        }

                        if (codePointStringBuffer.Length == codePointStringOffet)
                        {
                            Array.Resize(ref codePointStringBuffer, codePointStringBuffer.Length * 2);
                        }

                        var a         = (char)_bytes[i + 2];
                        var b         = (char)_bytes[i + 3];
                        var c         = (char)_bytes[i + 4];
                        var d         = (char)_bytes[i + 5];
                        var codepoint = GetCodePoint(a, b, c, d);
                        codePointStringBuffer[codePointStringOffet++] = (char)codepoint;
                        i       += 5;
                        _offset += 6;
                        from     = _offset;
                        continue;

                    default:
                        throw CreateParsingExceptionMessage("Bad JSON escape.");
                    }

                case (byte)'"':                         // endtoken
                    _offset++;
                    goto END;

                default:                         // string
                    if (codePointStringOffet != 0)
                    {
                        if (builder == null)
                        {
                            builder = StringBuilderCache.GetBuffer();
                        }
                        BinaryUtil.EnsureCapacity(ref builder, builderOffset, StringEncoding.UTF8.GetMaxByteCount(codePointStringOffet));
                        builderOffset       += StringEncoding.UTF8.GetBytes(codePointStringBuffer, 0, codePointStringOffet, builder, builderOffset);
                        codePointStringOffet = 0;
                    }
                    _offset++;
                    continue;
                }

COPY:
                {
                    if (builder == null)
                    {
                        builder = StringBuilderCache.GetBuffer();
                    }
                    if (codePointStringOffet != 0)
                    {
                        BinaryUtil.EnsureCapacity(ref builder, builderOffset, StringEncoding.UTF8.GetMaxByteCount(codePointStringOffet));
                        builderOffset       += StringEncoding.UTF8.GetBytes(codePointStringBuffer, 0, codePointStringOffet, builder, builderOffset);
                        codePointStringOffet = 0;
                    }

                    var copyCount = i - from;
                    BinaryUtil.EnsureCapacity(ref builder, builderOffset, copyCount + 1);                     // require + 1!
                    Buffer.BlockCopy(_bytes, from, builder, builderOffset, copyCount);
                    builderOffset           += copyCount;
                    builder[builderOffset++] = escapeCharacter;
                    i       += 1;
                    _offset += 2;
                    from     = _offset;
                }
            }

            resultLength = 0;
            resultBytes  = null;
            resultOffset = 0;
            throw CreateParsingException("String End Token");

END:
            if (builderOffset == 0 && codePointStringOffet == 0)             // no escape
            {
                resultBytes  = _bytes;
                resultOffset = from;
                resultLength = _offset - 1 - from;                 // skip last quote
            }
            else
            {
                if (builder == null)
                {
                    builder = StringBuilderCache.GetBuffer();
                }
                if (codePointStringOffet != 0)
                {
                    BinaryUtil.EnsureCapacity(ref builder, builderOffset, StringEncoding.UTF8.GetMaxByteCount(codePointStringOffet));
                    builderOffset       += StringEncoding.UTF8.GetBytes(codePointStringBuffer, 0, codePointStringOffet, builder, builderOffset);
                    codePointStringOffet = 0;
                }

                var copyCount = _offset - from - 1;
                BinaryUtil.EnsureCapacity(ref builder, builderOffset, copyCount);
                Buffer.BlockCopy(_bytes, from, builder, builderOffset, copyCount);
                builderOffset += copyCount;

                resultBytes  = builder;
                resultOffset = 0;
                resultLength = builderOffset;
            }
        }