예제 #1
0
 public void ReadValue(JsonAction <object, JsonValueType> value, JsonAction readArray, JsonAction readObject)
 {
     if (value is null)
     {
         throw new ArgumentNullException(nameof(value));
     }
     if (readArray is null)
     {
         throw new ArgumentNullException(nameof(readArray));
     }
     if (readObject is null)
     {
         throw new ArgumentNullException(nameof(readObject));
     }
     if (Stacks.Peek().ArrayType != JsonArrayType.Unknown)
     {
         readArray();
         return;
     }
     if (Stacks.Peek().ObjectType != JsonObjectType.Unknown)
     {
         readObject();
         return;
     }
     Stacks.Peek().IsInitialized = true;
     if (Stacks.Peek().Instance is null)
     {
         value(null, JsonValueType.Null);
         return;
     }
     if (Stacks.Peek().Type is null)
     {
         Stacks.Peek().Type = Stacks.Peek().Instance.GetType();
     }
     if (JsonApi.TryGetValueType(Stacks.Peek().Type, out JsonValueType valueType, Config))
     {
         value(Stacks.Peek().Instance, valueType);
         return;
     }
     if (JsonApi.TryGetArrayType(Stacks.Peek().Type, out Stacks.Peek().ArrayType))
     {
         readArray();
         return;
     }
     if (JsonApi.TryGetObjectType(Stacks.Peek().Type, out Stacks.Peek().ObjectType))
     {
         readObject();
         return;
     }
     throw new JsonNotSupportException(Stacks.Peek().Type);
 }
예제 #2
0
 void Initialize(bool isArray)
 {
     if (Stacks.Peek().IsInitialized)
     {
         return;
     }
     Stacks.Peek().IsInitialized = true;
     if (Stacks.Peek().Instance is null)
     {
         return;
     }
     if (Stacks.Peek().Type is null)
     {
         Stacks.Peek().Type = Stacks.Peek().Instance.GetType();
     }
     if (isArray)
     {
         JsonApi.TryGetArrayType(Stacks.Peek().Type, out Stacks.Peek().ArrayType);
         return;
     }
     JsonApi.TryGetObjectType(Stacks.Peek().Type, out Stacks.Peek().ObjectType);
 }
예제 #3
0
        public object BuildArray(Type type, object instance = null)
        {
            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (!JsonApi.TryGetArrayType(type, out JsonArrayType arrayType))
            {
                throw new JsonNotSupportException(type);
            }
            switch (arrayType)
            {
            default:
                throw new JsonNotSupportException(arrayType);

            case JsonArrayType.Array: {
                JsonArray  jsonArray = new JsonValueBuilder(Reader, Config).BuildArray();
                List <int> bounds    = new List <int> ();
                MeasureArray(jsonArray, ref bounds);
                if (bounds.Count != type.GetArrayRank())
                {
                    throw new JsonException("数组维数不匹配");
                }
                Type  elementType = type.GetElementType();
                Array array       = null;
                bool  create      = false;
                if (instance?.GetType() != type)
                {
                    create = true;
                }
                else
                {
                    array = (Array)instance;
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (array.GetLength(i) != bounds[i])
                        {
                            create = true;
                            break;
                        }
                    }
                }
                if (create)
                {
                    if (bounds.Count == 1)
                    {
                        array = Array.CreateInstance(elementType, bounds[0]);
                    }
                    else
                    {
                        array = Array.CreateInstance(elementType, bounds.ToArray());
                    }
                }
                if (array.Rank == 1)
                {
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        JsonDeserializer deserializer = new JsonDeserializer(new JsonValueReader(jsonArray[i], Config), Config);
                        array.SetValue(deserializer.BuildValue(elementType, array.GetValue(i)), i);
                    }
                    return(array);
                }
                int[] indices   = new int[bounds.Count];
                int   dimension = 0;
                void ForEachArray(JsonArray currentArray)
                {
                    int length = bounds[dimension];

                    for (int i = 0; i < length; i++)
                    {
                        indices[dimension] = i;
                        if (dimension == indices.Length - 1)
                        {
                            JsonDeserializer deserializer = new JsonDeserializer(new JsonValueReader(currentArray[i], Config), Config);
                            array.SetValue(deserializer.BuildValue(elementType, array.GetValue(indices)), indices);
                            continue;
                        }
                        dimension++;
                        ForEachArray(currentArray[i]);
                    }
                    dimension--;
                }

                ForEachArray(jsonArray);
                return(array);
            }

            case JsonArrayType.GenericList:
            case JsonArrayType.GenericIList:
            case JsonArrayType.GenericObservableCollection: {
                Type elementType = type.GetGenericArguments()[0];
                if (instance?.GetType() != type)
                {
                    if (type.IsInterface)
                    {
                        switch (arrayType)
                        {
                        default:
                            throw new JsonNotSupportException(arrayType);

                        case JsonArrayType.GenericIList:
                            instance = JsonApi.CreateInstance(typeof(List <>).MakeGenericType(elementType));
                            break;
                        }
                    }
                    else
                    {
                        instance = JsonApi.CreateInstance(type);
                    }
                }
                IList list     = (IList)instance;
                int   oldCount = list.Count;
                int   newCount = 0;
                Reader.ReadArray(i => {
                        newCount = i + 1;
                        if (i < oldCount)
                        {
                            list[i] = BuildValue(elementType, list[i]);
                            return;
                        }
                        list.Add(BuildValue(elementType));
                    });
                while (list.Count > newCount)
                {
                    list.RemoveAt(list.Count - 1);
                }
                return(list);
            }

            case JsonArrayType.DataTable: {
                if (instance?.GetType() != type)
                {
                    instance = JsonApi.CreateInstance(type);
                }
                DataTable dataTable    = (DataTable)instance;
                int       columnNumber = dataTable.Columns.Count;
                int       columnIndex;
                ArrayList arrayList = null;
                object[]  values    = null;
                Reader.ReadArray(i => {
                        bool hasRow = dataTable.Rows.Count > i;
                        if (!hasRow)
                        {
                            if (i == 0)
                            {
                                arrayList = new ArrayList();
                            }
                            else if (values is null)
                            {
                                values = new object[columnNumber];
                            }
                        }
                        columnIndex = 0;
                        Reader.ReadObject(columnName => {
                            if (!hasRow && i == 0)
                            {
                                columnNumber++;
                                dataTable.Columns.Add(columnName);
                            }
                            return(true);
                        }, () => {
                            object value = BuildValue();
                            if (hasRow)
                            {
                                dataTable.Rows[i].ItemArray[columnIndex] = value;
                                return;
                            }
                            if (i == 0)
                            {
                                arrayList.Add(value);
                                return;
                            }
                            values[columnIndex] = value;
                            columnIndex++;
                        });
                        if (!hasRow)
                        {
                            dataTable.Rows.Add(i == 0 ? arrayList.ToArray() : values);
                        }
                    });
                return(dataTable);
            }
            }
        }