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); }
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); }
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); } } }