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)); } switch (Values.Peek().Type) { case JsonValueType.Array: readArray(); return; case JsonValueType.Object: readObject(); return; } if (JsonApi.HasFlag(Values.Peek().Type, JsonValueType.Value)) { value(Values.Peek().Value, Values.Peek().Type); return; } throw new JsonNotSupportException(Values.Peek().Type); }
public object Write(object value = null, JsonConfig config = null) { if (config is null) { config = JsonConfig.Default; } WriteParameters[0] = JsonApi.ChangeType(value, AfterType, config); return(JsonApi.ChangeType(WriteMethod.Invoke(Instance, WriteParameters), WriteMethod.ReturnType, config)); }
public object Read(object value = null, JsonConfig config = null) { if (config is null) { config = JsonConfig.Default; } ReadParameters[0] = JsonApi.ChangeType(value, BeforeType, config); return(JsonApi.ChangeType(ReadMethod.Invoke(Instance, ReadParameters), ReadMethod.ReturnType, config)); }
public object BuildValue(Type type = null, object instance = null) { object returnValue = null; Reader.ReadValue( (value, _) => returnValue = JsonApi.ChangeType(value, type, Config), () => returnValue = BuildArray(type, instance), () => returnValue = BuildObject(type, instance) ); return(returnValue); }
public JsonObject BuildObject(JsonObject jsonObject = null) { JsonObject returnValue = jsonObject ?? new JsonObject(); string key = null; Reader.ReadObject(name => { key = name; return(true); }, () => returnValue.Add(JsonApi.Naming(key, Config.NamingType), BuildValue(returnValue.Get(key)))); //todo 待测试复用是否正常 return(returnValue); }
public void BuildObject() { TextWriter.BeginObject(); Reader.ReadObject( name => { TextWriter.Write(JsonApi.Naming(name, Config.NamingType), JsonValueType.String); return(true); }, () => BuildValue() ); TextWriter.EndObject(); }
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); }
public JsonConverter(Type type) { Type = type ?? throw new ArgumentNullException(nameof(type)); Type interfaceType = Type.GetInterface(typeof(IJsonConverter <object, object>).Name); if (interfaceType is null) { throw new JsonException($"{type}需要实现{typeof (IJsonConverter<object, object>)}接口"); } Type[] types = interfaceType.GetGenericArguments(); BeforeType = types[0]; AfterType = types[1]; ReadMethod = interfaceType.GetMethod(nameof(IJsonConverter <object, object> .Read), new Type[] { BeforeType }); WriteMethod = interfaceType.GetMethod(nameof(IJsonConverter <object, object> .Write), new Type[] { AfterType }); Instance = JsonApi.CreateInstance(Type); }
internal void Write(object value, JsonValueType valueType) { CheckEnd(); Head(); if (JsonApi.HasFlag(Stacks.Peek().Stage, JsonTextWriterStage.Key)) { valueType = JsonValueType.String; } switch (valueType) { case JsonValueType.Null: TextWriter.Write(JsonKeyword.Null); break; case JsonValueType.Integer: TextWriter.Write(value); break; case JsonValueType.Decimal: TextWriter.Write(value); if (value.ToString().IndexOf('.') < 0) { TextWriter.Write(".0"); } break; case JsonValueType.Bool: TextWriter.Write(Convert.ToBoolean(value) ? JsonKeyword.True : JsonKeyword.False); break; case JsonValueType.String: WriteString(JsonApi.CancelUnescape(Convert.ToString(value))); break; case JsonValueType.DateTime: DateTime dateTime = Convert.ToDateTime(value); WriteString(Config.UTCTime ? dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") : dateTime.ToString()); break; default: throw new JsonNotSupportException(valueType); } Tail(); }
object ConverterRead(Type type, object instance, JsonField field) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (field?.HasConverter ?? false) { Type readType; if (field.ConverterReadType == type.BaseType || JsonApi.GetElementType(field.ConverterReadType) == JsonApi.GetElementType(type).BaseType) //todo 让多个转换器之间也支持 { readType = type; } else { readType = field.ConverterReadType; } return(JsonApi.ChangeType(field.ConverterRead(BuildValue(readType, instance), Config), type, Config)); } return(BuildValue(type, instance)); }
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 void Write(object value) { if (value is JsonValue jsonValue) { new JsonTextBuilder(new JsonValueReader(jsonValue, Config), this, Config).BuildValue(); return; } if (value is JsonArray array) { new JsonTextBuilder(new JsonValueReader(array, Config), this, Config).BuildArray(); return; } if (value is JsonObject jsonObject) { new JsonTextBuilder(new JsonValueReader(jsonObject, Config), this, Config).BuildObject(); return; } if (JsonApi.TryGetValueType(value, out JsonValueType valueType, Config)) { Write(value, valueType); return; } new JsonTextBuilder(new JsonSerializer(value, Config), this, Config).BuildValue(); }
public void ReadObject(JsonFunc <string, bool> key, JsonAction readValue) { if (key is null) { throw new ArgumentNullException(nameof(key)); } if (readValue is null) { throw new ArgumentNullException(nameof(readValue)); } Initialize(false); switch (Stacks.Peek().ObjectType) { default: throw new JsonNotSupportException(Stacks.Peek().ObjectType); case JsonObjectType.Class: JsonApi.ForEachSerializableMembers(Stacks.Peek().Type, (memberInfo, fieldInfo, propertyInfo, field) => { bool isReaded = false; object instance = null; Type fieldType = null; object Read() { if (isReaded) { return(instance); } isReaded = true; switch (memberInfo.MemberType) { default: throw new JsonNotSupportException(memberInfo.MemberType); case MemberTypes.Field: fieldType = fieldInfo.FieldType; return(instance = fieldInfo.GetValue(Stacks.Peek().Instance)); case MemberTypes.Property: fieldType = propertyInfo.PropertyType; return(instance = propertyInfo.GetValue(Stacks.Peek().Instance, null)); } } object ConverterWrite(object value) { if (field?.HasConverter ?? false) { if (field.ConverterWriteType != fieldType.BaseType && JsonApi.GetElementType(field.ConverterWriteType) != JsonApi.GetElementType(fieldType).BaseType ) { fieldType = field.ConverterWriteType; } return(field.ConverterWrite(value, Config)); } return(value); } if (!JsonApi.CanSerializeValue(Read(), Config)) { return; } if (key(field?.Name ?? memberInfo.Name)) { Stacks.Push(new JsonSerializerStack(ConverterWrite(Read()), field)); Stacks.Peek().Type = fieldType; readValue(); Stacks.Pop(); } }); break; case JsonObjectType.DataRow: { DataRow dataRow = (DataRow)Stacks.Peek().Instance; for (int i = 0; i < dataRow.Table.Columns.Count; i++) { if (key(dataRow.Table.Columns[i].ColumnName)) { Stacks.Push(new JsonSerializerStack(dataRow[i])); readValue(); Stacks.Pop(); } } break; } case JsonObjectType.DataSet: { DataSet dataSet = (DataSet)Stacks.Peek().Instance; foreach (DataTable dataTable in dataSet.Tables) { if (key(dataTable.TableName)) { Stacks.Push(new JsonSerializerStack(dataTable)); readValue(); Stacks.Pop(); } } break; } case JsonObjectType.GenericDictionary: case JsonObjectType.GenericSortedDictionary: case JsonObjectType.GenericSortedList: { IDictionary dictionary = (IDictionary)Stacks.Peek().Instance; foreach (DictionaryEntry entry in dictionary) { if (key(Convert.ToString(entry.Key))) { Stacks.Push(new JsonSerializerStack(entry.Value)); readValue(); Stacks.Pop(); } } break; } case JsonObjectType.GenericKeyValuePair: { if (key(Convert.ToString(Stacks.Peek().Type.GetProperty("Key").GetValue(Stacks.Peek().Instance, null)))) { Stacks.Push(new JsonSerializerStack(Stacks.Peek().Type.GetProperty("Value").GetValue(Stacks.Peek().Instance, null))); readValue(); Stacks.Pop(); } break; } } }
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); } } }
public object BuildObject(Type type, object instance = null) { if (type is null) { throw new ArgumentNullException(nameof(type)); } if (!JsonApi.TryGetObjectType(type, out JsonObjectType objectType)) { throw new JsonNotSupportException(type); } if (instance?.GetType() != type) { instance = JsonApi.CreateInstance(type); } switch (objectType) { default: throw new JsonNotSupportException(objectType); case JsonObjectType.Class: { MemberInfo memberInfo = null; FieldInfo fieldInfo = null; PropertyInfo propertyInfo = null; JsonField field = null; Reader.ReadObject(name => { foreach (MemberInfo current in JsonApi.GetMembers(type)) { if (JsonApi.CanSerializeMember(current, out fieldInfo, out propertyInfo, out field)) { if (JsonApi.Equals(name, field?.Name ?? current.Name, Config)) { memberInfo = current; return(true); } } } return(false); }, () => { object value; switch (memberInfo.MemberType) { default: throw new JsonNotSupportException(memberInfo.MemberType); case MemberTypes.Field: value = ConverterRead(fieldInfo.FieldType, fieldInfo.GetValue(instance), field); break; case MemberTypes.Property: value = ConverterRead(propertyInfo.PropertyType, propertyInfo.GetValue(instance, null), field); break; } if (!JsonApi.CanSerializeValue(value, Config)) { return; } switch (memberInfo.MemberType) { default: throw new JsonNotSupportException(memberInfo.MemberType); case MemberTypes.Field: fieldInfo.SetValue(instance, value); break; case MemberTypes.Property: propertyInfo.SetValue(instance, value, null); break; } }); return(instance); } case JsonObjectType.DataSet: { DataSet dataSet = (DataSet)instance; string tableName = null; Reader.ReadObject(name => { tableName = name; return(true); }, () => { DataTable dataTable = dataSet.Tables[tableName]; bool hasTable = dataTable != null; dataTable = BuildArray <DataTable> (dataTable); if (!hasTable) { dataSet.Tables.Add(dataTable); } dataTable.TableName = JsonApi.Naming(tableName, Config.NamingType); }); return(instance); } case JsonObjectType.GenericDictionary: case JsonObjectType.GenericSortedDictionary: case JsonObjectType.GenericSortedList: { Type keyType = type.GetGenericArguments()[0]; Type valueType = type.GetGenericArguments()[1]; IDictionary dictionary = (IDictionary)instance; dictionary.Clear(); object key = null; Reader.ReadObject(name => { key = JsonApi.ChangeType(JsonApi.Naming(name, Config.NamingType), keyType, Config); return(true); }, () => { dictionary[key] = BuildValue(valueType); }); return(instance); } case JsonObjectType.GenericKeyValuePair: { Type keyType = type.GetGenericArguments()[0]; Type valueType = type.GetGenericArguments()[1]; Reader.ReadObject(name => { type.GetRuntimeField("key").SetValue(instance, JsonApi.ChangeType(JsonApi.Naming(name, Config.NamingType), keyType, Config)); return(true); }, () => { FieldInfo fieldInfo = type.GetRuntimeField("value"); fieldInfo.SetValue(instance, BuildValue(valueType, fieldInfo.GetValue(instance))); }); return(instance); } } }