Пример #1
0
 internal static object Convert(InternalObject obj, Type type)
 {
     if (type == typeof(IEnumerable))
     {
         return(ConvertToIEnumerable(obj));
     }
     return(ConvertToObject(obj, type));
 }
Пример #2
0
 internal void Add(InternalObject obj)
 {
     if (Count == _array.Length)
     {
         Array.Resize(ref _array, _array.Length * 2);
     }
     _array[Count++] = obj;
 }
Пример #3
0
 internal static object Convert(InternalObject obj, Type type)
 {
     if (type == typeof(IEnumerable) || type == typeof(Dictionary <string, object>))
     {
         return(ConvertToIEnumerable(obj));
     }
     return(new ConvertTo().ConvertToObject(obj, type));
 }
Пример #4
0
 public bool TryNext(ref InternalObject obj)
 {
     if (!_enumerator.MoveNext())
     {
         return(false);
     }
     obj = _enumerator.Current;
     return(true);
 }
Пример #5
0
 public bool MoveNext()
 {
     Position++;
     if (Position == _count)
     {
         return(false);
     }
     _current = _array[Position];
     return(true);
 }
Пример #6
0
 public bool TryNext(ref object value, ref InternalObject result)
 {
     while (true)
     {
         _position++;
         if (_position == _getters.Length)
         {
             return(false);
         }
         result.Type = JsonType.Null;
         value       = _getters[_position].Invoke(_target, ref result);
         _name       = _getters[_position].Name;
         if (result.Type == JsonType.Null)
         {
             return(true);
         }
         DstDictionary[_name] = result;
     }
 }
Пример #7
0
 public bool TryNext(ref Type type, ref InternalObject value)
 {
     while (true)
     {
         _position++;
         if (_position == _setters.Length)
         {
             return(false);
         }
         _current = _setters[_position];
         type     = _current.Type;
         if (!_dict.TryGetValue(_current.Name, out value))
         {
             continue;
         }
         if (_current.DirectInvoke == null)
         {
             return(true);
         }
         _current.DirectInvoke(DstObject, value);
     }
 }
Пример #8
0
        internal static object ToValue(InternalObject obj)
        {
            switch (obj.Type)
            {
            case JsonType.Null:
                return(null);

            case JsonType.True:
                return(true);

            case JsonType.False:
                return(false);

            case JsonType.String:
                return(obj.String);

            case JsonType.Array:
            case JsonType.Object:
                return(new JsonObject(obj));

            default:
                return(obj.Number);
            }
        }
Пример #9
0
            private static object ConvertToObject(InternalObject obj, Type type)
            {
                var    stack   = new Stack <Context>();
                var    context = new Context();
                object result;

Convert:
                if (type == typeof(object))
                {
                    result = ToValue(obj);
                    goto Return;
                }
                switch (obj.Type)
                {
                case JsonType.Null:
                    result = ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.True:
                case JsonType.False:
                    result = type == typeof(bool)
                            ? obj.Type == JsonType.True
                            : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.String:
                    result = type == typeof(string) ? obj.String : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.Array:
                    stack.Push(context);
                    if (!type.IsArray && !IsGenericList(type))
                    {
                        throw InvalidCastException(obj, type);
                    }
                    if (type.IsArray)
                    {
                        var element = type.GetElementType();
                        context = new Context
                        {
                            Mode     = ConvertMode.Array,
                            Type     = element,
                            DstArray = Array.CreateInstance(element, obj.Array.Count)
                        };
                    }
                    else
                    {
                        context = new Context
                        {
                            Mode     = ConvertMode.List,
                            Type     = type.GetGenericArguments()[0],
                            DstArray = ReflectiveOperation.GetObjectCreator(type)()
                        };
                    }
                    context.JsonArrayEnumerator = obj.Array.GetEnumerator();
                    goto ArrayNext;

                case JsonType.Object:
                    if (type.IsArray)
                    {
                        throw InvalidCastException(obj, type);
                    }
                    stack.Push(context);
                    context = new Context
                    {
                        Mode             = ConvertMode.Object,
                        DstObject        = ReflectiveOperation.GetObjectCreator(type)(),
                        SetterEnumerator = new SetterEnumerator(type, obj.Dictionary)
                    };
                    goto ObjectNext;

                default:
                    result = type == typeof(double)
                            ? obj.Number
                            : type == typeof(int)
                                ? (int)obj.Number
                                : type == typeof(float)
                                    ? (float)obj.Number
                                    : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;
                }

Return:
                if (stack.Count == 0)
                {
                    return(result);
                }
                switch (context.Mode)
                {
                case ConvertMode.Array:
                    // ReSharper disable once RedundantCast
                    context.DstArray[context.JsonArrayEnumerator.Position] = (dynamic)result;
                    break;

                case ConvertMode.List:
                    context.DstArray.Add((dynamic)result);
                    break;

                case ConvertMode.Object:
                    context.SetterEnumerator.Current.Invoke(context.DstObject, result);
                    goto ObjectNext;
                }

ArrayNext:
                if (!context.JsonArrayEnumerator.MoveNext())
                {
                    result  = context.DstArray;
                    context = stack.Pop();
                    goto Return;
                }
                type = context.Type;
                obj  = context.JsonArrayEnumerator.Current;
                goto Convert;

ObjectNext:
                if (!context.SetterEnumerator.MoveNext())
                {
                    result  = context.DstObject;
                    context = stack.Pop();
                    goto Return;
                }
                var current = context.SetterEnumerator.Current;

                type = current.Type;
                obj  = current.Value;
                goto Convert;
            }
Пример #10
0
 internal JsonObject(InternalObject obj)
 {
     _data = obj;
 }
Пример #11
0
 private static object ConvertToIEnumerable(InternalObject obj)
 {
     return(obj.IsArray
         ? (object)obj.Array.GetEnumerator().GetEnumerable().Select(ToValue)
         : obj.Dictionary.GetEnumerator().GetEnumerable().ToDictionary(x => x.Key, x => ToValue(x.Value)));
 }
Пример #12
0
 private static InvalidCastException InvalidCastException(InternalObject obj, Type type)
 {
     return(new InvalidCastException($"Unable to cast value of type {obj.Type} to type '{type.Name}'"));
 }
Пример #13
0
            private void SerializeInternal(InternalObject obj, TextWriter writer, int maxDepth)
            {
                _buffer      = BufferPool.Rent() ?? new Buffer();
                _writeBuffer = _buffer.Write;
                _stack       = _buffer.Stack;
                var context = new Context();

                _writer = writer;
                fixed(char *bufferStart = _writeBuffer)
                {
                    _bufferStart = bufferStart;
                    _bufferEnd   = bufferStart + _writeBuffer.Length;
                    _pointer     = bufferStart;
Convert:
                    switch (obj.Type)
                    {
                    case JsonType.Null:
                        EnsureBuffer(4);
                        *_pointer++ = 'n';
                        *_pointer++ = 'u';
                        *_pointer++ = 'l';
                        *_pointer++ = 'l';
                        break;

                    case JsonType.True:
                        EnsureBuffer(4);
                        *_pointer++ = 't';
                        *_pointer++ = 'r';
                        *_pointer++ = 'u';
                        *_pointer++ = 'e';
                        break;

                    case JsonType.False:
                        EnsureBuffer(5);
                        *_pointer++ = 'f';
                        *_pointer++ = 'a';
                        *_pointer++ = 'l';
                        *_pointer++ = 's';
                        *_pointer++ = 'e';
                        break;

                    case JsonType.String:
                        WriteString(obj.String);
                        break;

                    case JsonType.Array:
                        if (obj.Array.Count == 0)
                        {
                            EnsureBuffer(2);
                            *_pointer++ = '[';
                            *_pointer++ = ']';
                            break;
                        }
                        EnsureBuffer(1);
                        *_pointer++ = '[';
                        _stack.Push(context);
                        context = new Context
                        {
                            Mode            = Mode.Array,
                            ArrayEnumerator = obj.Array.GetEnumerator()
                        };
                        break;

                    case JsonType.Object:
                        if (obj.Dictionary.Count == 0)
                        {
                            EnsureBuffer(2);
                            *_pointer++ = '{';
                            *_pointer++ = '}';
                            break;
                        }
                        EnsureBuffer(1);
                        *_pointer++ = '{';
                        if (_stack.Count == maxDepth)
                        {
                            throw new JsonSerializerException("Too deep nesting");
                        }
                        _stack.Push(context);
                        context = new Context
                        {
                            DictionaryEnumerator = obj.Dictionary.GetEnumerator()
                        };
                        break;

                    default:
                        EnsureBuffer(24);
                        _pointer += FastDtoa.Convert(obj.Number, _pointer);
                        break;
                    }

Return:
                    if (_stack.Count == 0)
                    {
                        var len = (int)(_pointer - _bufferStart);
                        if (len > 0)
                        {
                            _writer.Write(_writeBuffer, 0, len);
                        }
                        BufferPool.Return(_buffer);
                        return;
                    }

                    if ((context.Mode & Mode.Array) != 0)
                    {
                        if (context.ArrayEnumerator.MoveNext())
                        {
                            if ((context.Mode & Mode.Delimiter) != 0)
                            {
                                EnsureBuffer(1);
                                *_pointer++ = ',';
                            }
                            context.Mode |= Mode.Delimiter;
                            obj           = context.ArrayEnumerator.Current;
                            goto Convert;
                        }
                        EnsureBuffer(1);
                        *_pointer++ = ']';
                    }
                    else
                    {
                        if (context.DictionaryEnumerator.MoveNext())
                        {
                            var current = context.DictionaryEnumerator.Current;

                            if ((context.Mode & Mode.Delimiter) != 0)
                            {
                                EnsureBuffer(1);
                                *_pointer++ = ',';
                            }
                            WriteString(current.Key);
                            EnsureBuffer(1);
                            *_pointer++ = ':';
                            context.Mode |= Mode.Delimiter;
                            obj           = current.Value;
                            goto Convert;
                        }
                        EnsureBuffer(1);
                        *_pointer++ = '}';
                    }
                    context = _stack.Pop();
                    goto Return;
                }
            }
Пример #14
0
 public static void Serialize(InternalObject obj, TextWriter writer, int maxDepth)
 {
     new Serializer().SerializeInternal(obj, writer, maxDepth);
 }
Пример #15
0
            private object ConvertToObject(InternalObject obj, Type type)
            {
                _stack.Count = 0;
                var    context = new Context();
                object result;

Convert:
                if (type == typeof(object))
                {
                    result = ToValue(obj);
                    goto Return;
                }
                switch (obj.Type)
                {
                case JsonType.Null:
                    result = ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.True:
                case JsonType.False:
                    result = type == typeof(bool)
                            ? obj.Type == JsonType.True
                            : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.String:
                    result = type == typeof(string) ? obj.String : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;

                case JsonType.Array:
                    _stack.Push(context);
                    if (!type.IsArray && !IsGenericList(type))
                    {
                        throw InvalidCastException(obj, type);
                    }
                    if (type.IsArray)
                    {
                        context = new Context
                        {
                            Mode            = ConvertMode.Array,
                            ArrayEnumerator = new ArrayEnumerator(type, obj.Array)
                        };
                        goto ArrayNext;
                    }
                    else
                    {
                        context = new Context
                        {
                            Mode           = ConvertMode.List,
                            ListEnumerator = new ListEnumerator(type, obj.Array)
                        };
                        goto ListNext;
                    }

                case JsonType.Object:
                    if (type.IsArray)
                    {
                        throw InvalidCastException(obj, type);
                    }
                    _stack.Push(context);
                    context = new Context
                    {
                        Mode             = ConvertMode.Object,
                        SetterEnumerator = new SetterEnumerator(type, obj.Dictionary)
                    };
                    goto ObjectNext;

                default:
                    result = type == typeof(double)
                            ? obj.Number
                            : type == typeof(int)
                                ? (int)obj.Number
                                : type == typeof(float)
                                    ? (float)obj.Number
                                    : ChangeType(ToValue(obj), type, InvariantCulture);
                    break;
                }

Return:
                if (_stack.Count == 0)
                {
                    return(result);
                }
                switch (context.Mode)
                {
                case ConvertMode.Array:
                    context.ArrayEnumerator.SetResult(result);
                    break;

                case ConvertMode.List:
                    context.ListEnumerator.SetResult(result);
                    goto ListNext;

                case ConvertMode.Object:
                    context.SetterEnumerator.SetResult(result);
                    goto ObjectNext;
                }
ArrayNext:
                if (!context.ArrayEnumerator.TryNext(ref obj))
                {
                    result  = context.ArrayEnumerator.DstObject;
                    context = _stack.Pop();
                    goto Return;
                }
                type = context.ArrayEnumerator.Element;
                goto Convert;
ListNext:
                if (!context.ListEnumerator.TryNext(ref obj))
                {
                    result  = context.ListEnumerator.DstObject;
                    context = _stack.Pop();
                    goto Return;
                }
                type = context.ListEnumerator.Element;
                goto Convert;
ObjectNext:
                if (!context.SetterEnumerator.TryNext(ref type, ref obj))
                {
                    result  = context.SetterEnumerator.DstObject;
                    context = _stack.Pop();
                    goto Return;
                }
                goto Convert;
            }
Пример #16
0
        private object ParseInternal(TextReader reader, int maxDepth)
        {
            Setup(reader);
            var stack   = new Context[maxDepth];
            var depth   = 0;
            var context = new Context();

            SkipWhiteSpaces();
            while (true)
            {
                var value = new InternalObject();
                switch (_nextChar)
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '-':
                    value.Number = GetNumber();
                    break;

                case 'n':
                    CheckToken("ull");
                    value.Type = JsonType.Null;
                    break;

                case 't':
                    CheckToken("rue");
                    value.Type = JsonType.True;
                    break;

                case 'f':
                    // ReSharper disable once StringLiteralTypo
                    CheckToken("alse");
                    value.Type = JsonType.False;
                    break;

                case '"':
                    value.Type   = JsonType.String;
                    value.String = GetString();
                    break;

                case '[':
                    if (depth == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(depth, _position);
                    }
                    Consume();
                    stack[depth++] = context;
                    context        = new Context
                    {
                        Array = new JsonArray()
                    };
                    SkipWhiteSpaces();
                    continue;

                case ']':
                    if (context.Array == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type  = JsonType.Array;
                    value.Array = context.Array;
                    context     = stack[--depth];
                    break;

                case '{':
                    if (depth == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(depth, _position);
                    }
                    Consume();
                    stack[depth++] = context;
                    context        = new Context
                    {
                        Dictionary = new JsonDictionary()
                    };
                    goto GetKey;

                case '}':
                    if (context.Dictionary == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type       = JsonType.Object;
                    value.Dictionary = context.Dictionary;
                    context          = stack[--depth];
                    break;

                default:
                    if (_isEnd)
                    {
                        throw JsonParserException.UnexpectedEnd(_position);
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }

                SkipWhiteSpaces();
                // Start
                if (depth == 0)
                {
                    if (_isEnd)
                    {
                        return(JsonObject.ToValue(value));
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }
                // Array
                if (context.Key == null)
                {
                    context.Array.Add(value);
                    if (_nextChar == ']')
                    {
                        continue;
                    }
                    if (_nextChar != ',')
                    {
                        throw JsonParserException.ExpectingError("',' or ']'", _position);
                    }
                    Consume();
                    SkipWhiteSpaces();
                    continue;
                }
                // Object
                context.Dictionary.Add(context.Key, value);
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != ',')
                {
                    throw JsonParserException.ExpectingError("',' or '}'", _position);
                }
                Consume();

GetKey:
                SkipWhiteSpaces();
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != '"')
                {
                    throw JsonParserException.ExpectingError("string", _position);
                }
                context.Key = GetString();
                SkipWhiteSpaces();
                if (_nextChar != ':')
                {
                    throw JsonParserException.ExpectingError("':'", _position);
                }
                Consume();
                SkipWhiteSpaces();
            }
        }
Пример #17
0
 public JsonObject(object obj)
 {
     _data = ConvertFrom.Convert(obj);
 }
Пример #18
0
            private InternalObject ConvertInternal(object value)
            {
                var context = new Context();
                var result  = new InternalObject();

Convert:
                if (value == null)
                {
                    result.Type = JsonType.Null;
                    goto Return;
                }
                var type = value.GetType();

                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    result.Type = JsonType.Null;
                    break;

                case TypeCode.Boolean:
                    result.Type = (bool)value ? JsonType.True : JsonType.False;
                    break;

                case TypeCode.Byte:
                case TypeCode.SByte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Decimal:
                    result.Number = ConvertToDouble(value);
                    break;

                case TypeCode.Int32:
                    result.Number = (int)value;
                    break;

                case TypeCode.Single:
                    result.Number = (float)value;
                    break;

                case TypeCode.Double:
                    result.Number = (double)value;
                    break;

                case TypeCode.Char:
                case TypeCode.DateTime:
                    result.Type   = JsonType.String;
                    result.String = ConvertToString(value);
                    break;

                case TypeCode.String:
                    result.Type   = JsonType.String;
                    result.String = (string)value;
                    break;

                case TypeCode.Object:
                    if (typeof(IDictionary).IsAssignableFrom(type))
                    {
                        _stack.Push(context);
                        context = new Context
                        {
                            Mode = ConvertMode.Dictionary,
                            DictionaryEnumerator = new DictionaryEnumerator(value)
                        };
                        goto DictionaryNext;
                    }
                    if (typeof(IEnumerable).IsAssignableFrom(type))     // Can convert to array
                    {
                        _stack.Push(context);
                        context = new Context
                        {
                            Mode            = ConvertMode.Array,
                            ArrayEnumerator = new ArrayEnumerator(value)
                        };
                        goto ArrayNext;
                    }
                    if (value is JsonObject obj)
                    {
                        result = obj._data;
                        goto Return;
                    }
                    _stack.Push(context);
                    var v1 = value;
                    context = new Context
                    {
                        Mode             = ConvertMode.Object,
                        GetterEnumerator = new GetterEnumerator(v1),
                    };
                    goto ObjectNext;
                }

Return:
                if (_stack.Count == 0)
                {
                    return(result);
                }
                if (context.Mode == ConvertMode.Array)
                {
                    context.ArrayEnumerator.SetResult(result);
                    goto ArrayNext;
                }
                if (context.Mode == ConvertMode.Dictionary)
                {
                    context.DictionaryEnumerator.SetResult(result);
                    goto DictionaryNext;
                }
                context.GetterEnumerator.SetResult(result);

ObjectNext:
                if (context.GetterEnumerator.TryNext(ref value, ref result))
                {
                    goto Convert;
                }
                result.Type       = JsonType.Object;
                result.Dictionary = context.GetterEnumerator.DstDictionary;
                context           = _stack.Pop();
                goto Return;

ArrayNext:
                if (context.ArrayEnumerator.TryNext(ref value))
                {
                    goto Convert;
                }
                result.Type  = JsonType.Array;
                result.Array = context.ArrayEnumerator.DstArray;
                context      = _stack.Pop();
                goto Return;

DictionaryNext:
                if (context.DictionaryEnumerator.TryNext(ref value))
                {
                    goto Convert;
                }
                result.Type       = JsonType.Object;
                result.Dictionary = context.DictionaryEnumerator.DstDictionary;
                context           = _stack.Pop();
                goto Return;
            }
Пример #19
0
 public void SetResult(InternalObject result)
 {
     DstDictionary[_key] = result;
 }
Пример #20
0
        private unsafe object ParseInternal(TextReader reader, int maxDepth)
        {
            Setup(reader);
            var context    = new Context();
            var charBuffer = stackalloc char[StringInitialCapacity];

            SkipWhiteSpaces();
            while (true)
            {
                var value = new InternalObject();
                switch (_nextChar)
                {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '-':
                    value.Number = GetNumber();
                    break;

                case 'n':
                    CheckToken("ull");
                    value.Type = JsonType.Null;
                    break;

                case 't':
                    CheckToken("rue");
                    value.Type = JsonType.True;
                    break;

                case 'f':
                    // ReSharper disable once StringLiteralTypo
                    CheckToken("alse");
                    value.Type = JsonType.False;
                    break;

                case '"':
                    value.Type   = JsonType.String;
                    value.String = GetString(charBuffer);
                    break;

                case '[':
                    if (_stack.Count == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(_stack.Count, _position);
                    }
                    Consume();
                    _stack.Push(context);
                    context = new Context
                    {
                        Array = new JsonArray()
                    };
                    SkipWhiteSpaces();
                    continue;

                case ']':
                    if (context.Array == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type  = JsonType.Array;
                    value.Array = context.Array;
                    context     = _stack.Pop();
                    break;

                case '{':
                    if (_stack.Count == maxDepth)
                    {
                        throw JsonParserException.TooDeepNesting(_stack.Count, _position);
                    }
                    Consume();
                    _stack.Push(context);
                    context = new Context
                    {
                        Dictionary = new JsonDictionary()
                    };
                    goto GetKey;

                case '}':
                    if (context.Dictionary == null)
                    {
                        throw JsonParserException.UnexpectedError(_nextChar, _position);
                    }
                    Consume();
                    value.Type       = JsonType.Object;
                    value.Dictionary = context.Dictionary;
                    context          = _stack.Pop();
                    break;

                default:
                    if (_isEnd)
                    {
                        throw JsonParserException.UnexpectedEnd(_position);
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }

                SkipWhiteSpaces();
                // Start
                if (_stack.Count == 0)
                {
                    // The buffer intentionally leaks in exceptional cases to simplify the code for exceptions.
                    BufferPool.Return(_buffer);
                    if (_isEnd)
                    {
                        return(JsonObject.ToValue(value));
                    }
                    throw JsonParserException.UnexpectedError(_nextChar, _position);
                }
                // Array
                if (context.Key == null)
                {
                    context.Array.Add(value);
                    if (_nextChar == ']')
                    {
                        continue;
                    }
                    if (_nextChar != ',')
                    {
                        throw JsonParserException.ExpectingError("',' or ']'", _position);
                    }
                    Consume();
                    SkipWhiteSpaces();
                    continue;
                }
                // Object
                context.Dictionary.Add(context.Key, value);
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != ',')
                {
                    throw JsonParserException.ExpectingError("',' or '}'", _position);
                }
                Consume();

GetKey:
                SkipWhiteSpaces();
                if (_nextChar == '}')
                {
                    continue;
                }
                if (_nextChar != '"')
                {
                    throw JsonParserException.ExpectingError("string", _position);
                }
                context.Key = GetString(charBuffer);
                SkipWhiteSpaces();
                if (_nextChar != ':')
                {
                    throw JsonParserException.ExpectingError("':'", _position);
                }
                Consume();
                SkipWhiteSpaces();
            }
        }
Пример #21
0
            public static InternalObject Convert(object value)
            {
                var stack   = new Stack <Context>();
                var context = new Context();
                var result  = new InternalObject();

Convert:
                if (value == null)
                {
                    result.Type = JsonType.Null;
                    goto Return;
                }
                var type = value.GetType();

                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    result.Type = JsonType.Null;
                    break;

                case TypeCode.Boolean:
                    result.Type = (bool)value ? JsonType.True : JsonType.False;
                    break;

                case TypeCode.Byte:
                case TypeCode.SByte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Decimal:
                    result.Number = ConvertToDouble(value);
                    break;

                case TypeCode.Int32:
                    result.Number = (int)value;
                    break;

                case TypeCode.Single:
                    result.Number = (float)value;
                    break;

                case TypeCode.Double:
                    result.Number = (double)value;
                    break;

                case TypeCode.Char:
                case TypeCode.DateTime:
                    result.Type   = JsonType.String;
                    result.String = ConvertToString(value);
                    break;

                case TypeCode.String:
                    result.Type   = JsonType.String;
                    result.String = (string)value;
                    break;

                case TypeCode.Object:
                    if (typeof(IEnumerable).IsAssignableFrom(type))     // Can convert to array
                    {
                        stack.Push(context);
                        context = new Context
                        {
                            Mode            = ConvertMode.Array,
                            ArrayEnumerator = ((IEnumerable)value).GetEnumerator(),
                            DstArray        = new JsonArray()
                        };
                        goto ArrayNext;
                    }
                    if (value is JsonObject obj)
                    {
                        result = obj._data;
                        break;
                    }
                    stack.Push(context);
                    var v1 = value;
                    context = new Context
                    {
                        Mode             = ConvertMode.Object,
                        GetterEnumerator = new GetterEnumerator(v1),
                        DstDictionary    = new JsonDictionary()
                    };
                    goto ObjectNext;
                }

Return:
                if (stack.Count == 0)
                {
                    return(result);
                }
                if (context.Mode == ConvertMode.Array)
                {
                    context.DstArray.Add(result);
                    goto ArrayNext;
                }
                context.DstDictionary[context.GetterEnumerator.Current.Name] = result;

ObjectNext:
                if (context.GetterEnumerator.MoveNext())
                {
                    value = context.GetterEnumerator.Current.Value;
                    goto Convert;
                }
                result.Type       = JsonType.Object;
                result.Dictionary = context.DstDictionary;
                context           = stack.Pop();
                goto Return;

ArrayNext:
                if (context.ArrayEnumerator.MoveNext())
                {
                    value = context.ArrayEnumerator.Current;
                    goto Convert;
                }
                result.Type  = JsonType.Array;
                result.Array = context.DstArray;
                context      = stack.Pop();
                goto Return;
            }
Пример #22
0
 public void SetResult(InternalObject result)
 {
     DstArray.Add(result);
 }