Ejemplo n.º 1
0
        public static unsafe void WriteRaw28(ref JsonWriter writer, byte[] src)
        {
            BinaryUtil.EnsureCapacity(ref writer.buffer, writer.offset, src.Length);

            fixed(byte *pSrc = &src[0])
            fixed(byte *pDst = &writer.buffer[writer.offset])
            {
                *(int *)(pDst + 0)  = *(int *)(pSrc + 0);
                *(int *)(pDst + 4)  = *(int *)(pSrc + 4);
                *(int *)(pDst + 8)  = *(int *)(pSrc + 8);
                *(int *)(pDst + 12) = *(int *)(pSrc + 12);
                *(int *)(pDst + 16) = *(int *)(pSrc + 16);
                *(int *)(pDst + 20) = *(int *)(pSrc + 20);
                *(int *)(pDst + 24) = *(int *)(pSrc + 24);
            }

            writer.offset += src.Length;
        }
Ejemplo n.º 2
0
 public void WriteBoolean(bool value)
 {
     if (value)
     {
         BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
         buffer[offset + 0] = (byte)'t';
         buffer[offset + 1] = (byte)'r';
         buffer[offset + 2] = (byte)'u';
         buffer[offset + 3] = (byte)'e';
         offset            += 4;
     }
     else
     {
         BinaryUtil.EnsureCapacity(ref buffer, offset, 5);
         buffer[offset + 0] = (byte)'f';
         buffer[offset + 1] = (byte)'a';
         buffer[offset + 2] = (byte)'l';
         buffer[offset + 3] = (byte)'s';
         buffer[offset + 4] = (byte)'e';
         offset            += 5;
     }
 }
Ejemplo n.º 3
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;
            var to   = value.Length;

            buffer[offset++] = (byte)'\"';

            // for JIT Optimization, for-loop i < str.Length
            for (int i = 0; i < value.Length; i++)
            {
                byte escapeChar = default(byte);
                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;

                // use switch jumptable
                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 (char)32:
                case (char)33:
                case (char)35:
                case (char)36:
                case (char)37:
                case (char)38:
                case (char)39:
                case (char)40:
                case (char)41:
                case (char)42:
                case (char)43:
                case (char)44:
                case (char)45:
                case (char)46:
                case (char)47:
                case (char)48:
                case (char)49:
                case (char)50:
                case (char)51:
                case (char)52:
                case (char)53:
                case (char)54:
                case (char)55:
                case (char)56:
                case (char)57:
                case (char)58:
                case (char)59:
                case (char)60:
                case (char)61:
                case (char)62:
                case (char)63:
                case (char)64:
                case (char)65:
                case (char)66:
                case (char)67:
                case (char)68:
                case (char)69:
                case (char)70:
                case (char)71:
                case (char)72:
                case (char)73:
                case (char)74:
                case (char)75:
                case (char)76:
                case (char)77:
                case (char)78:
                case (char)79:
                case (char)80:
                case (char)81:
                case (char)82:
                case (char)83:
                case (char)84:
                case (char)85:
                case (char)86:
                case (char)87:
                case (char)88:
                case (char)89:
                case (char)90:
                case (char)91:
                default:
                    continue;
                }

                max += 2;
                BinaryUtil.EnsureCapacity(ref buffer, startoffset, max); // check +escape capacity

                offset          += StringEncoding.UTF8.GetBytes(value, from, i - from, buffer, offset);
                from             = i + 1;
                buffer[offset++] = (byte)'\\';
                buffer[offset++] = escapeChar;
            }

            if (from != value.Length)
            {
                offset += StringEncoding.UTF8.GetBytes(value, from, value.Length - from, buffer, offset);
            }

            buffer[offset++] = (byte)'\"';
        }
Ejemplo n.º 4
0
 public void WriteQuotation()
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = (byte)'\"';
 }
Ejemplo n.º 5
0
 public void WriteNameSeparator()
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = (byte)':';
 }
Ejemplo n.º 6
0
 public void WriteEndObject()
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = (byte)'}';
 }
Ejemplo n.º 7
0
 public void WriteEndArray()
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = (byte)']';
 }
Ejemplo n.º 8
0
 public void WriteRaw(byte rawValue)
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = rawValue;
 }
Ejemplo n.º 9
0
 public void EnsureCapacity(int appendLength)
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, appendLength);
 }
Ejemplo n.º 10
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);
 }
Ejemplo n.º 11
0
 public void AddCharacter(byte str)
 {
     BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
     buffer[offset++] = str;
 }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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);
        }
Ejemplo n.º 14
0
        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 (int 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':
                                if (codePointStringBuffer == null) codePointStringBuffer = StringBuilderCache.GetCodePointStringBuffer();

                                if (codePointStringOffet == 0)
                                {
                                    if (builder == null) 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;
            }
        }