Example #1
0
        public bool TryGetValue(string key, out InternalObject value)
        {
            value = default(InternalObject);
            var hashCode = GetHashCode(key);
            var hash     = hashCode % _capacity;

            if (_bucket[hash] == -1)
            {
                return(false);
            }
            var entry = _entries[_bucket[hash]];

            while (true)
            {
                if (entry.HashCode == hashCode && entry.Key == key)
                {
                    value = entry.Value;
                    return(true);
                }
                if (entry.Next == -1)
                {
                    return(false);
                }
                entry = _entries[entry.Next];
            }
        }
Example #2
0
 internal static object Convert(InternalObject obj, Type type)
 {
     if (type == typeof(IEnumerable))
     {
         return(ConvertToIEnumerable(obj));
     }
     return(ConvertToObject(obj, type));
 }
Example #3
0
 internal void Add(InternalObject obj)
 {
     if (Count == _array.Length)
     {
         Array.Resize(ref _array, _array.Length * 2);
     }
     _array[Count++] = obj;
 }
Example #4
0
 public bool MoveNext()
 {
     Position++;
     if (Position == _count)
     {
         return(false);
     }
     _current = _array[Position];
     return(true);
 }
Example #5
0
        private void Insert(string key, InternalObject value, bool add)
        {
            if (key == null)
            {
                throw new ArgumentNullException();
            }
            var hashCode = GetHashCode(key);
            var hash     = hashCode % _capacity;
            var index    = _bucket[hash];

            while (true)
            {
                if (index == -1)
                {
                    if (_count == _capacity)
                    {
                        Resize();
                        hash = hashCode % _capacity;
                    }
                    _entries[_count] = new Entry
                    {
                        HashCode = hashCode,
                        Key      = key,
                        Value    = value,
                        Next     = _bucket[hash]
                    };
                    _bucket[hash] = _count++;
                    return;
                }
                var entry = _entries[index];
                if (entry.HashCode == hashCode && entry.Key == key)
                {
                    if (!add)
                    {
                        entry.Value = value;
                    }
                    return;
                }
                index = entry.Next;
            }
        }
Example #6
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);
            }
        }
Example #7
0
 internal JsonObject(object obj)
 {
     _data = ConvertFrom.Convert(obj);
 }
Example #8
0
 internal JsonObject(InternalObject obj)
 {
     _data = obj;
 }
Example #9
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();
            }
        }
Example #10
0
            private void SerializeInternal(InternalObject obj, TextWriter writer, int maxDepth)
            {
                var stack   = new Context[maxDepth];
                var context = new Context();
                var depth   = 0;

                _writer = writer;
                fixed(char *bufferStart = _buffer)
                {
                    _bufferStart = bufferStart;
                    _bufferEnd   = bufferStart + _buffer.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[depth++] = 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 (depth == maxDepth)
                        {
                            throw new JsonSerializerException("Too deep nesting");
                        }
                        stack[depth++] = context;
                        context        = new Context
                        {
                            DictionaryEnumerator = obj.Dictionary.GetEnumerator()
                        };
                        break;

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

Return:
                    if (depth == 0)
                    {
                        var len = (int)(_pointer - _bufferStart);
                        if (len > 0)
                        {
                            _writer.Write(_buffer, 0, len);
                        }
                        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[--depth];
                    goto Return;
                }
            }
Example #11
0
 public static void Serialize(InternalObject obj, TextWriter writer, int maxDepth)
 {
     Instance.SerializeInternal(obj, writer, maxDepth);
 }
Example #12
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 = System.Convert.ChangeType(ToValue(obj), type, CultureInfo.InvariantCulture);
                    break;

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

                case JsonType.String:
                    result = type == typeof(string) ? obj.String : System.Convert.ChangeType(ToValue(obj), type, CultureInfo.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
                                    : System.Convert.ChangeType(ToValue(obj), type, CultureInfo.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;
            }
Example #13
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)));
 }
Example #14
0
 private static InvalidCastException InvalidCastException(InternalObject obj, Type type)
 {
     return(new InvalidCastException(string.Format("Unable to cast value of type {0} to type '{1}'", obj.Type, type.Name)));
 }
            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;
                    }
                    JsonObject obj = value as JsonObject;
                    if (obj != null)
                    {
                        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;
            }
Example #16
0
 public void Add(string key, InternalObject value)
 {
     Insert(key, value, true);
 }