/// <summary> /// 添加字段 /// </summary> /// <param name="field">字段信息</param> public void Push(FieldIndex field) { push(field.AnonymousName); bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(field.Member.FieldType, ref isCustom); if (isCustom) { if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldflda, field.Member); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.Emit(OpCodes.Ldfld, field.Member); } generator.call(method); }
public void Serialize(object value) { if (value == null) { CharStream.WriteJsonNull(); } else if (value.GetType() == typeof(Node)) { Serialize((Node)value); } else if (Config.IsObject) { Type type = value.GetType(); if (type == typeof(object)) { CharStream.WriteJsonObject(); } else { SerializeMethodCache.GetObject(type)(this, value); } } else { CharStream.WriteJsonObject(); } }
/// <summary> /// 添加成员 /// </summary> /// <param name="name">成员名称</param> private unsafe void push(string name) { if (isFirstMember == 0) { generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNamePool(name), name.Length + 4); } else { generator.charStreamSimpleWriteNotNull(OpCodes.Ldloc_0, SerializeMethodCache.GetNamePool(name) + 1, name.Length + 3); isFirstMember = 0; } }
/// <summary> /// 设置字段信息 /// </summary> /// <param name="field"></param> public void Set(FieldIndex field) { this.field = field.Member; Name = field.AnonymousName; MemberIndex = field.MemberIndex; bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(this.field.FieldType, ref isCustom); if (isCustom) { customSerializeMethod = (Action <object, Serializer>) typeof(AutoCSer.Reflection.InvokeMethodRef1 <,>).MakeGenericType(this.field.FieldType, typeof(Serializer)).GetMethod("getObjectType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } else { serializeMethod = (Action <Serializer, object>) typeof(AutoCSer.Reflection.InvokeMethod <,>).MakeGenericType(typeof(Serializer), this.field.FieldType).GetMethod("getTypeObject", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } }
/// <summary> /// 添加属性 /// </summary> /// <param name="property">属性信息</param> /// <param name="propertyMethod">函数信息</param> public void Push(PropertyIndex property, MethodInfo propertyMethod) { Label end = generator.DefineLabel(); push(property.Member.Name, property.MemberIndex, end); bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(property.Member.PropertyType, ref isCustom); if (isCustom) { LocalBuilder loadMember = generator.DeclareLocal(property.Member.PropertyType); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.call(propertyMethod); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloca_S, loadMember); generator.Emit(OpCodes.Ldarg_1); } else { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.call(propertyMethod); } generator.call(method); generator.MarkLabel(end); }
/// <summary> /// 添加成员 /// </summary> /// <param name="name">成员名称</param> /// <param name="memberIndex"></param> /// <param name="end"></param> private unsafe void push(string name, int memberIndex, Label end) { Label next = generator.DefineLabel(), value = generator.DefineLabel(); generator.memberMapIsMember(OpCodes.Ldarg_0, memberIndex); generator.Emit(OpCodes.Brfalse_S, end); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Brtrue_S, next); char *nameChar = SerializeMethodCache.GetNamePool(name); generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.Stloc_0); generator.charStreamSimpleWriteNotNull(OpCodes.Ldarg_3, nameChar + 1, name.Length + 3); generator.Emit(OpCodes.Br_S, value); generator.MarkLabel(next); generator.charStreamSimpleWriteNotNull(OpCodes.Ldarg_3, nameChar, name.Length + 4); generator.MarkLabel(value); }
/// <summary> /// 添加字段 /// </summary> /// <param name="field">字段信息</param> public void Push(FieldIndex field) { Label end = generator.DefineLabel(); push(field.AnonymousName, field.MemberIndex, end); bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(field.Member.FieldType, ref isCustom); if (isCustom) { if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.Emit(OpCodes.Ldflda, field.Member); generator.Emit(OpCodes.Ldarg_1); } else { generator.Emit(OpCodes.Ldarg_1); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 2); } else { generator.Emit(OpCodes.Ldarg_2); } generator.Emit(OpCodes.Ldfld, field.Member); } generator.call(method); generator.MarkLabel(end); }
/// <summary> /// 添加属性 /// </summary> /// <param name="property">属性信息</param> /// <param name="propertyMethod">函数信息</param> public void PushBox(PropertyIndex property, MethodInfo propertyMethod) { bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(property.Member.PropertyType, ref isCustom); if (isCustom) { LocalBuilder loadMember = generator.DeclareLocal(property.Member.PropertyType); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloca_S, loadMember); generator.Emit(OpCodes.Ldarg_0); } else { generator.Emit(OpCodes.Ldarg_0); if (isValueType) { generator.Emit(OpCodes.Ldarga_S, 1); } else { generator.Emit(OpCodes.Ldarg_1); } generator.call(propertyMethod); } generator.call(method); }
/// <summary> /// 设置属性信息 /// </summary> /// <param name="property"></param> public void Set(KeyValue <PropertyIndex, MethodInfo> property) { PropertyInfo = property.Key.Member; if (PropertyInfo.DeclaringType.IsValueType) { getMethod = (Func <object, object>) typeof(AutoCSer.Reflection.InvokeMethodRefReturn <,>).MakeGenericType(PropertyInfo.DeclaringType, PropertyInfo.PropertyType).GetMethod("getObjectReturn", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { PropertyInfo.GetGetMethod(true) }); } else { getMethod = (Func <object, object>) typeof(AutoCSer.Reflection.InvokeMethodReturn <,>).MakeGenericType(PropertyInfo.DeclaringType, PropertyInfo.PropertyType).GetMethod("getObjectReturn", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { PropertyInfo.GetGetMethod(true) }); } MemberIndex = property.Key.MemberIndex; bool isCustom = false; MethodInfo method = SerializeMethodCache.GetMemberMethodInfo(PropertyInfo.PropertyType, ref isCustom); if (isCustom) { customSerializeMethod = (Action <object, Serializer>) typeof(AutoCSer.Reflection.InvokeMethodRef1 <,>).MakeGenericType(PropertyInfo.PropertyType, typeof(Serializer)).GetMethod("getObjectType", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } else { serializeMethod = (Action <Serializer, object>) typeof(AutoCSer.Reflection.InvokeMethod <,>).MakeGenericType(typeof(Serializer), PropertyInfo.PropertyType).GetMethod("getTypeObject", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); } }
static TypeSerializer() { Type type = typeof(valueType); MethodInfo methodInfo = Serializer.GetSerializeMethod(type); if (methodInfo != null) { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), methodInfo); isValueType = true; return; } if (type.IsArray) { //if (type.GetArrayRank() == 1) defaultSerializer = (Action<Serializer, valueType>)Delegate.CreateDelegate(typeof(Action<Serializer, valueType>), SerializeMethodCache.GetArray(type.GetElementType())); if (type.GetArrayRank() == 1) { Type elementType = type.GetElementType(); if (elementType.IsValueType && (!elementType.IsGenericType || elementType.GetGenericTypeDefinition() != typeof(Nullable <>))) { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), StructGenericType.Get(elementType).JsonSerializeStructArrayMethod); } else { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), GenericType.Get(elementType).JsonSerializeArrayMethod); } } else { defaultSerializer = arrayManyRank; } isValueType = true; return; } if (type.IsEnum) { defaultSerializer = enumToString; isValueType = true; return; } if (type.IsInterface || type.IsPointer || typeof(Delegate).IsAssignableFrom(type)) { defaultSerializer = toNull; isValueType = true; return; } if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); if (genericType == typeof(Dictionary <,>)) { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), SerializeMethodCache.GetDictionary(type)); isValueType = true; return; } if (genericType == typeof(Nullable <>)) { //defaultSerializer = (Action<Serializer, valueType>)Delegate.CreateDelegate(typeof(Action<Serializer, valueType>), SerializeMethodCache.GetNullable(type)); defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), StructGenericType.Get(type.GetGenericArguments()[0]).JsonSerializeNullableMethod); isValueType = true; return; } if (genericType == typeof(KeyValuePair <,>)) { //defaultSerializer = (Action<Serializer, valueType>)Delegate.CreateDelegate(typeof(Action<Serializer, valueType>), SerializeMethodCache.GetKeyValuePair(type)); defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), GenericType2.Get(type.GetGenericArguments()).JsonSerializeKeyValuePairMethod); isValueType = true; return; } } if ((methodInfo = SerializeMethodCache.GetCustom(type)) != null) { if (type.IsValueType) { #if NOJIT defaultSerializer = new CustomSerializer(methodInfo).Serialize; #else DynamicMethod dynamicMethod = new DynamicMethod("CustomJsonSerializer", null, new Type[] { typeof(Serializer), type }, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarga_S, 1); generator.Emit(OpCodes.Ldarg_0); generator.call(methodInfo); generator.Emit(OpCodes.Ret); defaultSerializer = (Action <Serializer, valueType>)dynamicMethod.CreateDelegate(typeof(Action <Serializer, valueType>)); #endif } else { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), methodInfo); } isValueType = true; } else if ((methodInfo = SerializeMethodCache.GetIEnumerable(type)) != null) { defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), methodInfo); isValueType = true; } else { Type attributeType; attribute = type.customAttribute <SerializeAttribute>(out attributeType) ?? (type.Name[0] == '<' ? SerializeAttribute.AnonymousTypeMember : Serializer.AllMemberAttribute); if (type.IsValueType) { isValueType = true; } else if (attribute != Serializer.AllMemberAttribute && attributeType != type) { for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType) { SerializeAttribute baseAttribute = baseType.customAttribute <SerializeAttribute>(); if (baseAttribute != null) { if (baseAttribute.IsBaseType) { methodInfo = SerializeMethodCache.BaseSerializeMethod.MakeGenericMethod(baseType, type); defaultSerializer = (Action <Serializer, valueType>)Delegate.CreateDelegate(typeof(Action <Serializer, valueType>), methodInfo); return; } break; } } } LeftArray <FieldIndex> fields = SerializeMethodCache.GetFields(MemberIndexGroup <valueType> .GetFields(attribute.MemberFilters), attribute); LeftArray <KeyValue <PropertyIndex, MethodInfo> > properties = SerializeMethodCache.GetProperties(MemberIndexGroup <valueType> .GetProperties(attribute.MemberFilters), attribute); bool isBox = false; if (type.IsValueType && fields.Length + properties.Length == 1) { BoxSerializeAttribute boxSerialize = AutoCSer.Metadata.TypeAttribute.GetAttribute <BoxSerializeAttribute>(type); if (boxSerialize != null && boxSerialize.IsJson) { isBox = true; } } #if AutoCSer AutoCSer.WebView.ClientTypeAttribute clientType = isBox ? null : AutoCSer.Metadata.TypeAttribute.GetAttribute <AutoCSer.WebView.ClientTypeAttribute>(type); if (clientType != null) { if (clientType.MemberName == null) { viewClientTypeName = "new " + clientType.GetClientName(type) + "({"; } else { viewClientTypeName = clientType.GetClientName(type) + ".Get({"; } } #endif #if NOJIT if (isBox) { defaultSerializer = memberSerializer = new FieldPropertySerializer(ref fields, ref properties).SerializeBox; } else { memberSerializer = new FieldPropertySerializer(ref fields, ref properties).Serialize; memberMapSerializer = new MemberMapSerializer(ref fields, ref properties).Serialize; } #else SerializeMemberDynamicMethod dynamicMethod = new SerializeMemberDynamicMethod(type); SerializeMemberMapDynamicMethod memberMapDynamicMethod = isBox ? default(SerializeMemberMapDynamicMethod) : new SerializeMemberMapDynamicMethod(type); foreach (FieldIndex member in fields) { if (isBox) { dynamicMethod.PushBox(member); } else { dynamicMethod.Push(member); memberMapDynamicMethod.Push(member); } } foreach (KeyValue <PropertyIndex, MethodInfo> member in properties) { if (isBox) { dynamicMethod.PushBox(member.Key, member.Value); } else { dynamicMethod.Push(member.Key, member.Value); memberMapDynamicMethod.Push(member.Key, member.Value); } } memberSerializer = (Action <Serializer, valueType>)dynamicMethod.Create <Action <Serializer, valueType> >(); if (isBox) { defaultSerializer = memberSerializer; } else { memberMapSerializer = (Action <MemberMap, Serializer, valueType, CharStream>)memberMapDynamicMethod.Create <Action <MemberMap, Serializer, valueType, CharStream> >(); } #endif } }