Пример #1
0
        internal static void WriteValue(int value, JsonSerializerHandler handler)
        {
            // Gotta special case this, we can't negate it
            if (value == int.MinValue)
            {
                handler.WriteString("-2147483648");
                return;
            }
            if (value == int.MaxValue)
            {
                handler.WriteString("2147483647");
                return;
            }
            var ptr = 35;

            char[] buffer = new char[36];
            uint   copy;

            if (value < 0)
            {
                handler.WriteChar('-');
                copy = (uint)(-value);
            }
            else
            {
                copy = (uint)value;
            }

            do
            {
                byte ix = (byte)(copy % 100);
                copy /= 100;

                var chars = SpecialTypeNormal.DigitPairs[ix];
                buffer[ptr--] = chars.Second;
                buffer[ptr--] = chars.First;
            } while (copy != 0);

            if (buffer[ptr + 1] == '0')
            {
                ptr++;
            }

            handler.WriteChars(buffer, ptr + 1, 35 - ptr);
        }
Пример #2
0
        internal static void WriteValue(long value, JsonSerializerHandler handler)
        {
            if (value == long.MinValue)
            {
                handler.WriteString("-9223372036854775808");
                return;
            }
            char[] buffer = new char[36];
            var    ptr    = 35;

            ulong copy;

            if (value < 0)
            {
                handler.WriteChar('-');
                copy = (ulong)(-value);
            }
            else
            {
                copy = (ulong)value;
            }

            do
            {
                byte ix = (byte)(copy % 100);
                copy /= 100;

                var chars = SpecialTypeNormal.DigitPairs[ix];
                buffer[ptr--] = chars.Second;
                buffer[ptr--] = chars.First;
            } while (copy != 0);

            if (buffer[ptr + 1] == '0')
            {
                ptr++;
            }

            handler.WriteChars(buffer, ptr + 1, 35 - ptr);
        }
Пример #3
0
        internal static unsafe void WriteValue(string value, JsonSerializerHandler handler)
        {
            /*
             * string = quotation-mark *char quotation-mark
             *
             * char = unescaped /
             *     escape (
             *         %x22 /          ; "    quotation mark  U+0022
             *         %x5C /          ; \    reverse solidus U+005C
             *         %x2F /          ; /    solidus         U+002F
             *         %x62 /          ; b    backspace       U+0008
             *         %x66 /          ; f    form feed       U+000C
             *         %x6E /          ; n    line feed       U+000A
             *         %x72 /          ; r    carriage return U+000D
             *         %x74 /          ; t    tab             U+0009
             *         %x75 4HEXDIG )  ; uXXXX                U+XXXX
             *
             * escape = %x5C              ; \
             *
             * quotation-mark = %x22      ; "
             *
             * unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
             */
            if (value == null)
            {
                handler.WriteString("null");
                return;
            }
            //handler.Writer.EnsureCapacity(handler.Writer.Capacity + value.Length);
            handler.WriteString("\"");
            fixed(char *strFixed = value)
            {
                char *str = strFixed;
                char  c;
                var   len = value.Length;

                while (len > 0)
                {
                    c = *str;
                    str++;
                    len--;

                    if (c == '\\')//\u005c   //%x5c        a\\b  =>  a\u005cb
                    {
                        handler.WriteString(@"\\");
                        continue;
                    }

                    if (c == '"')//\u0022   //%x22
                    {
                        handler.WriteString("\\\"");
                        continue;
                    }
                    switch (c)
                    {
                    //%x00-x19
                    case '\u0000': handler.WriteString(@"\u0000"); continue;

                    case '\u0001': handler.WriteString(@"\u0001"); continue;

                    case '\u0002': handler.WriteString(@"\u0002"); continue;

                    case '\u0003': handler.WriteString(@"\u0003"); continue;

                    case '\u0004': handler.WriteString(@"\u0004"); continue;

                    case '\u0005': handler.WriteString(@"\u0005"); continue;

                    case '\u0006': handler.WriteString(@"\u0006"); continue;

                    case '\u0007': handler.WriteString(@"\u0007"); continue;

                    case '\u0008': handler.WriteString(@"\b"); continue;

                    case '\u0009': handler.WriteString(@"\t"); continue;

                    case '\u000A': handler.WriteString(@"\n"); continue;

                    case '\u000B': handler.WriteString(@"\u000b"); continue;

                    case '\u000C': handler.WriteString(@"\f"); continue;

                    case '\u000D': handler.WriteString(@"\r"); continue;

                    case '\u000E': handler.WriteString(@"\u000e"); continue;

                    case '\u000F': handler.WriteString(@"\u000f"); continue;

                    case '\u0010': handler.WriteString(@"\u0010"); continue;

                    case '\u0011': handler.WriteString(@"\u0011"); continue;

                    case '\u0012': handler.WriteString(@"\u0012"); continue;

                    case '\u0013': handler.WriteString(@"\u0013"); continue;

                    case '\u0014': handler.WriteString(@"\u0014"); continue;

                    case '\u0015': handler.WriteString(@"\u0015"); continue;

                    case '\u0016': handler.WriteString(@"\u0016"); continue;

                    case '\u0017': handler.WriteString(@"\u0017"); continue;

                    case '\u0018': handler.WriteString(@"\u0018"); continue;

                    case '\u0019': handler.WriteString(@"\u0019"); continue;

                    case '\u001A': handler.WriteString(@"\u001a"); continue;

                    case '\u001B': handler.WriteString(@"\u001b"); continue;

                    case '\u001C': handler.WriteString(@"\u001c"); continue;

                    case '\u001D': handler.WriteString(@"\u001d"); continue;

                    case '\u001E': handler.WriteString(@"\u001e"); continue;

                    case '\u001F': handler.WriteString(@"\u001f"); continue;

                    /*JavaScript   */
                    case '\u0085':     // Next Line
                        handler.WriteString(@"\u0085"); continue;

                    case '\u2028':     // Line Separator
                        handler.WriteString(@"\u2028"); continue;

                    case '\u2029':     // Paragraph Separator
                        handler.WriteString(@"\u2029"); continue;

                    default: handler.WriteChar(c); continue;
                    }
                }
            }

            handler.WriteString("\"");
        }
Пример #4
0
        internal static void WriteValue(StringBuilder value, JsonSerializerHandler handler)
        {
            if (value == null)
            {
                handler.WriteString("null");
            }
            else
            {
                handler.WriteString("\"");
                for (int i = 0; i < value.Length; i++)
                {
                    char c = value[i];
                    if (c == '\\')//\u005c   //%x5c        a\\b  =>  a\u005cb
                    {
                        handler.WriteString(@"\\");
                        continue;
                    }

                    if (c == '"')//\u0022   //%x22
                    {
                        handler.WriteString("\\\"");
                        continue;
                    }
                    //如果是jsonp格式,多了 u2028 u2029的转换
                    switch (c)
                    {
                    //%x00-x19
                    case '\u0000': handler.WriteString(@"\u0000"); continue;

                    case '\u0001': handler.WriteString(@"\u0001"); continue;

                    case '\u0002': handler.WriteString(@"\u0002"); continue;

                    case '\u0003': handler.WriteString(@"\u0003"); continue;

                    case '\u0004': handler.WriteString(@"\u0004"); continue;

                    case '\u0005': handler.WriteString(@"\u0005"); continue;

                    case '\u0006': handler.WriteString(@"\u0006"); continue;

                    case '\u0007': handler.WriteString(@"\u0007"); continue;

                    case '\u0008': handler.WriteString(@"\b"); continue;

                    case '\u0009': handler.WriteString(@"\t"); continue;

                    case '\u000A': handler.WriteString(@"\n"); continue;

                    case '\u000B': handler.WriteString(@"\u000b"); continue;

                    case '\u000C': handler.WriteString(@"\f"); continue;

                    case '\u000D': handler.WriteString(@"\r"); continue;

                    case '\u000E': handler.WriteString(@"\u000e"); continue;

                    case '\u000F': handler.WriteString(@"\u000f"); continue;

                    case '\u0010': handler.WriteString(@"\u0010"); continue;

                    case '\u0011': handler.WriteString(@"\u0011"); continue;

                    case '\u0012': handler.WriteString(@"\u0012"); continue;

                    case '\u0013': handler.WriteString(@"\u0013"); continue;

                    case '\u0014': handler.WriteString(@"\u0014"); continue;

                    case '\u0015': handler.WriteString(@"\u0015"); continue;

                    case '\u0016': handler.WriteString(@"\u0016"); continue;

                    case '\u0017': handler.WriteString(@"\u0017"); continue;

                    case '\u0018': handler.WriteString(@"\u0018"); continue;

                    case '\u0019': handler.WriteString(@"\u0019"); continue;

                    case '\u001A': handler.WriteString(@"\u001a"); continue;

                    case '\u001B': handler.WriteString(@"\u001b"); continue;

                    case '\u001C': handler.WriteString(@"\u001c"); continue;

                    case '\u001D': handler.WriteString(@"\u001d"); continue;

                    case '\u001E': handler.WriteString(@"\u001e"); continue;

                    case '\u001F': handler.WriteString(@"\u001f"); continue;

                    default: handler.WriteChar(c); continue;
                    }
                }
                handler.WriteString("\"");
            }
        }
Пример #5
0
        internal static void WriteValue(TimeSpan value, JsonSerializerHandler handler)
        {
            if (handler.Option.TimespanFormat == TimespanFormatEnum.ISO8601)
            {
                // can't negate this, have to handle it manually
                if (value.Ticks == long.MinValue)
                {
                    handler.WriteString("\"-P10675199DT2H48M5.4775808S\"");
                    return;
                }
                char[] buffer = new char[36];
                handler.WriteChar('"');

                if (value.Ticks < 0)
                {
                    handler.WriteChar('-');
                    value = value.Negate();
                }

                handler.WriteChar('P');

                var days    = value.Days;
                var hours   = value.Hours;
                var minutes = value.Minutes;
                var seconds = value.Seconds;

                // days
                if (days > 0)
                {
                    _CustomWriteIntUnrolledSigned(handler, days, buffer);
                    handler.WriteChar('D');
                }

                // time separator
                handler.WriteChar('T');

                // hours
                if (hours > 0)
                {
                    _CustomWriteIntUnrolledSigned(handler, hours, buffer);
                    handler.WriteChar('H');
                }

                // minutes
                if (minutes > 0)
                {
                    _CustomWriteIntUnrolledSigned(handler, minutes, buffer);
                    handler.WriteChar('M');
                }

                // seconds
                _CustomWriteIntUnrolledSigned(handler, seconds, buffer);

                // fractional part
                {
                    var endCount       = 0;
                    var remainingTicks = (value - new TimeSpan(days, hours, minutes, seconds, 0)).Ticks;

                    if (remainingTicks > 0)
                    {
                        int fracEnd;

                        buffer[0] = '.';

                        var fracPart = remainingTicks % 100;
                        remainingTicks /= 100;

                        TwoDigits digits;
                        if (fracPart > 0)
                        {
                            digits    = DigitPairs[fracPart];
                            buffer[7] = digits.Second;
                            buffer[6] = digits.First;
                            fracEnd   = 8;
                        }
                        else
                        {
                            fracEnd = 6;
                        }

                        fracPart        = remainingTicks % 100;
                        remainingTicks /= 100;
                        if (fracPart > 0)
                        {
                            digits    = DigitPairs[fracPart];
                            buffer[5] = digits.Second;
                            buffer[4] = digits.First;
                        }
                        else
                        {
                            if (fracEnd == 6)
                            {
                                fracEnd = 4;
                            }
                            else
                            {
                                buffer[5] = '0';
                                buffer[4] = '0';
                            }
                        }

                        fracPart        = remainingTicks % 100;
                        remainingTicks /= 100;
                        if (fracPart > 0)
                        {
                            digits    = DigitPairs[fracPart];
                            buffer[3] = digits.Second;
                            buffer[2] = digits.First;
                        }
                        else
                        {
                            if (fracEnd == 4)
                            {
                                fracEnd = 2;
                            }
                            else
                            {
                                buffer[3] = '0';
                                buffer[2] = '0';
                            }
                        }

                        fracPart  = remainingTicks;
                        buffer[1] = (char)('0' + fracPart);

                        endCount = fracEnd;
                    }

                    handler.WriteChars(buffer, 0, endCount);
                }

                handler.WriteString("S\"");
            }
            else
            {
                if (value.Ticks == long.MinValue)
                {
                    handler.WriteString("\"-10675199.02:48:05.4775808\"");
                    return;
                }
                char[] buffer = new char[36];
                handler.WriteChar('"');

                if (value.Ticks < 0)
                {
                    handler.WriteChar('-');
                    value = value.Negate();
                }

                var days    = value.Days;
                var hours   = value.Hours;
                var minutes = value.Minutes;
                var secs    = value.Seconds;

                TwoDigits digits;

                // days
                {
                    if (days != 0)
                    {
                        PrimitiveNormal.WriteValue(days, handler);
                        handler.WriteChar('.');
                    }
                }

                // hours
                {
                    digits    = DigitPairs[hours];
                    buffer[0] = digits.First;
                    buffer[1] = digits.Second;
                }

                buffer[2] = ':';

                // minutes
                {
                    digits    = DigitPairs[minutes];
                    buffer[3] = digits.First;
                    buffer[4] = digits.Second;
                }

                buffer[5] = ':';

                // seconds
                {
                    digits    = DigitPairs[secs];
                    buffer[6] = digits.First;
                    buffer[7] = digits.Second;
                }

                int endCount = 8;

                // factional part
                {
                    var remainingTicks = (value - new TimeSpan(value.Days, value.Hours, value.Minutes, value.Seconds, 0)).Ticks;
                    if (remainingTicks > 0)
                    {
                        int fracEnd;

                        buffer[8] = '.';

                        var fracPart = remainingTicks % 100;
                        remainingTicks /= 100;
                        if (fracPart > 0)
                        {
                            digits     = DigitPairs[fracPart];
                            buffer[15] = digits.Second;
                            buffer[14] = digits.First;
                            fracEnd    = 16;
                        }
                        else
                        {
                            fracEnd = 14;
                        }

                        fracPart        = remainingTicks % 100;
                        remainingTicks /= 100;
                        if (fracPart > 0)
                        {
                            digits     = DigitPairs[fracPart];
                            buffer[13] = digits.Second;
                            buffer[12] = digits.First;
                        }
                        else
                        {
                            if (fracEnd == 14)
                            {
                                fracEnd = 12;
                            }
                            else
                            {
                                buffer[13] = '0';
                                buffer[12] = '0';
                            }
                        }

                        fracPart        = remainingTicks % 100;
                        remainingTicks /= 100;
                        if (fracPart > 0)
                        {
                            digits     = DigitPairs[fracPart];
                            buffer[11] = digits.Second;
                            buffer[10] = digits.First;
                        }
                        else
                        {
                            if (fracEnd == 12)
                            {
                                fracEnd = 10;
                            }
                            else
                            {
                                buffer[11] = '0';
                                buffer[10] = '0';
                            }
                        }

                        fracPart  = remainingTicks;
                        buffer[9] = (char)('0' + fracPart);

                        endCount = fracEnd;
                    }
                }

                handler.WriteChars(buffer, 0, endCount);

                handler.WriteChar('"');
            }
        }
Пример #6
0
        internal static void WriteValue(DateTime value, JsonSerializerHandler handler)
        {
            if (handler.Option.DatetimeFormat == DatetimeFormatEnum.ISO8601)
            {
                // "yyyy-mm-ddThh:mm:ss.fffffffZ"
                // 0123456789ABCDEFGHIJKL
                //
                // Yes, DateTime.Max is in fact guaranteed to have a 4 digit year (and no more)
                // f of 7 digits allows for 1 Tick level resolution
                char[] buffer = new char[36];
                buffer[0] = '"';

                // Year
                uint val    = (uint)value.Year;
                var  digits = DigitPairs[(byte)(val % 100)];
                buffer[4] = digits.Second;
                buffer[3] = digits.First;
                digits    = DigitPairs[(byte)(val / 100)];
                buffer[2] = digits.Second;
                buffer[1] = digits.First;

                // delimiter
                buffer[5] = '-';

                // Month
                digits    = DigitPairs[value.Month];
                buffer[7] = digits.Second;
                buffer[6] = digits.First;

                // Delimiter
                buffer[8] = '-';

                // Day
                digits     = DigitPairs[value.Day];
                buffer[10] = digits.Second;
                buffer[9]  = digits.First;

                // Delimiter
                buffer[11] = 'T';

                digits     = DigitPairs[value.Hour];
                buffer[13] = digits.Second;
                buffer[12] = digits.First;

                // Delimiter
                buffer[14] = ':';

                digits     = DigitPairs[value.Minute];
                buffer[16] = digits.Second;
                buffer[15] = digits.First;

                // Delimiter
                buffer[17] = ':';

                digits     = DigitPairs[value.Second];
                buffer[19] = digits.Second;
                buffer[18] = digits.First;

                int fracEnd;
                var remainingTicks = (value - new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second)).Ticks;
                if (remainingTicks > 0)
                {
                    buffer[20] = '.';

                    var fracPart = remainingTicks % 100;
                    remainingTicks /= 100;
                    if (fracPart > 0)
                    {
                        digits     = DigitPairs[fracPart];
                        buffer[27] = digits.Second;
                        buffer[26] = digits.First;
                        fracEnd    = 28;
                    }
                    else
                    {
                        fracEnd = 26;
                    }

                    fracPart        = remainingTicks % 100;
                    remainingTicks /= 100;
                    if (fracPart > 0)
                    {
                        digits     = DigitPairs[fracPart];
                        buffer[25] = digits.Second;
                        buffer[24] = digits.First;
                    }
                    else
                    {
                        if (fracEnd == 26)
                        {
                            fracEnd = 24;
                        }
                        else
                        {
                            buffer[25] = '0';
                            buffer[24] = '0';
                        }
                    }

                    fracPart        = remainingTicks % 100;
                    remainingTicks /= 100;
                    if (fracPart > 0)
                    {
                        digits     = DigitPairs[fracPart];
                        buffer[23] = digits.Second;
                        buffer[22] = digits.First;
                    }
                    else
                    {
                        if (fracEnd == 24)
                        {
                            fracEnd = 22;
                        }
                        else
                        {
                            buffer[23] = '0';
                            buffer[22] = '0';
                        }
                    }

                    fracPart   = remainingTicks;
                    buffer[21] = (char)('0' + fracPart);
                }
                else
                {
                    fracEnd = 20;
                }

                buffer[fracEnd]     = 'Z';
                buffer[fracEnd + 1] = '"';

                handler.WriteChars(buffer, 0, fracEnd + 2);
            }
            else if (handler.Option.DatetimeFormat == DatetimeFormatEnum.RFC1123)
            {
                // ddd, dd MMM yyyy HH:mm:ss GMT'"
                handler.WriteChar('"');

                // compiles as a switch
                switch (value.DayOfWeek)
                {
                case DayOfWeek.Sunday: handler.WriteString("Sun, "); break;

                case DayOfWeek.Monday: handler.WriteString("Mon, "); break;

                case DayOfWeek.Tuesday: handler.WriteString("Tue, "); break;

                case DayOfWeek.Wednesday: handler.WriteString("Wed, "); break;

                case DayOfWeek.Thursday: handler.WriteString("Thu, "); break;

                case DayOfWeek.Friday: handler.WriteString("Fri, "); break;

                case DayOfWeek.Saturday: handler.WriteString("Sat, "); break;
                }

                {
                    var day = DigitPairs[value.Day];
                    handler.WriteChar(day.First);
                    handler.WriteChar(day.Second);
                    handler.WriteChar(' ');
                }

                // compiles as a switch
                switch (value.Month)
                {
                case 1: handler.WriteString("Jan "); break;

                case 2: handler.WriteString("Feb "); break;

                case 3: handler.WriteString("Mar "); break;

                case 4: handler.WriteString("Apr "); break;

                case 5: handler.WriteString("May "); break;

                case 6: handler.WriteString("Jun "); break;

                case 7: handler.WriteString("Jul "); break;

                case 8: handler.WriteString("Aug "); break;

                case 9: handler.WriteString("Sep "); break;

                case 10: handler.WriteString("Oct "); break;

                case 11: handler.WriteString("Nov "); break;

                case 12: handler.WriteString("Dec "); break;
                }

                {
                    var year          = value.Year;
                    var firstHalfYear = DigitPairs[year / 100];
                    handler.WriteChar(firstHalfYear.First);
                    handler.WriteChar(firstHalfYear.Second);

                    var secondHalfYear = DigitPairs[year % 100];
                    handler.WriteChar(secondHalfYear.First);
                    handler.WriteChar(secondHalfYear.Second);
                    handler.WriteChar(' ');
                }

                {
                    var hour = DigitPairs[value.Hour];
                    handler.WriteChar(hour.First);
                    handler.WriteChar(hour.Second);
                    handler.WriteChar(':');
                }

                {
                    var minute = DigitPairs[value.Minute];
                    handler.WriteChar(minute.First);
                    handler.WriteChar(minute.Second);
                    handler.WriteChar(':');
                }

                {
                    var second = DigitPairs[value.Second];
                    handler.WriteChar(second.First);
                    handler.WriteChar(second.Second);
                }

                handler.WriteString(" GMT\"");
            }
            else if (handler.Option.DatetimeFormat == DatetimeFormatEnum.Microsoft)
            {
                /*
                 *  "\/Date(628318530718)\/"
                 */
                handler.WriteString("\"\\/Date(");
                handler.WriteLong((value.Ticks - 621355968000000000L) / 10000L);
                handler.WriteString(")\\/\"");
            }
        }