//apply to IDictionary impl public static TypeInfo BuildIDictionaryImplementationType(DynamicFormatterAssembly assembly, ConstructorInfo constructor, Type type) { TypeBuilder typeBuilder = assembly.DefineFormatterType(type); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.SerializeIDictionary), BindingFlags.Public | BindingFlags.Static)); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); ParameterInfo[] args = constructor.GetParameters(); Type dynamicCacheType = typeof(IDictionaryDynamicDelegateCache <>).MakeGenericType(type); if (args.Length == 1) { DEBUG.Assert(args[0].ParameterType == typeof(IDictionary)); //return new T(IDictionaryFormatter.Deserialize) MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(IDictionaryDynamicDelegateCache <int> .GenerateInjectCtor)); methodinfo.Invoke(null, new object[] { constructor, args[0].ParameterType }); } else { MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(IDictionaryDynamicDelegateCache <int> .GenerateDeserializeWithIDictionaryEmptyCtor)); methodinfo.Invoke(null, new object[] { }); } TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(IDictionaryDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static)); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.SizeIDictionary), BindingFlags.Public | BindingFlags.Static)); return(typeBuilder.CreateTypeInfo()); }
//apply to IDictionary<>/IReadOnlyDictionary<> public static TypeInfo BuildGenericIDictionaryInterfaceType(DynamicFormatterAssembly assembly, Type type, Type genericTypeDefine, Type genericKeyType, Type genericValueType) { DEBUG.Assert(genericTypeDefine == typeof(IDictionary <,>) || genericTypeDefine == typeof(IReadOnlyDictionary <,>)); TypeBuilder typeBuilder = assembly.DefineFormatterType(type); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.SerializeGenericDictionary), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(new Type[] { genericKeyType, genericValueType })); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); if (genericTypeDefine == typeof(IDictionary <,>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.GenericDictionaryDeserialize), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(new Type[] { genericKeyType, genericValueType })); } else { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.ReadOnlyGenericDictionaryDeserialize), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(new Type[] { genericKeyType, genericValueType })); } MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(MapFormatterHelper).GetMethod(nameof(MapFormatterHelper.SizeGenericDictionary), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(genericKeyType, genericValueType)); return(typeBuilder.CreateTypeInfo()); }
public Raw64BytesISegment(byte[] us, int len) { DEBUG.Assert(len > 0); _us = us; _len = len; _raw64Count = (int)Math.Ceiling((decimal)len / 8); _lastRaw64ByteCount = 8 - (_raw64Count * 8 - _len); }
public static int GetIDictionaryCount <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > value) { DEBUG.Assert(value is IDictionary <TKey, TValue> || value is IReadOnlyDictionary <TKey, TValue>); if (value is IDictionary <TKey, TValue> idic) { return(idic.Count); } else { return(((IReadOnlyDictionary <TKey, TValue>)value).Count); } }
public static IEnumerable <KeyValuePair <string, object> > GetPublicMembersWithDynamicObject(this object value) { DEBUG.Assert(value != null); Type t = value.GetType(); foreach (FieldInfo p in t.GetFields(BindingFlags.Public | BindingFlags.Instance)) { yield return(new KeyValuePair <string, object>(p.Name, p.GetValue(value))); } foreach (PropertyInfo p in t.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (p.GetIndexParameters().Length == 0 && p.CanRead && p.CanWrite) { yield return(new KeyValuePair <string, object>(p.Name, p.GetValue(value))); } } }
//Serialize IList<> / IReadOnlyList<> public static void SerializeGenerIList <TElement>(ref BssomWriter writer, ref BssomSerializeContext context, IEnumerable <TElement> value) { if (value == null) { writer.WriteNull(); } else { DEBUG.Assert(value is IList <TElement> || value is IReadOnlyList <TElement>); IBssomFormatter <TElement> formatter = context.Option.FormatterResolver.GetFormatterWithVerify <TElement>(); writer.WriteArray2Type(); long pos = writer.FillUInt32FixNumber(); if (value is IList <TElement> list) { writer.WriteVariableNumber(list.Count); for (int i = 0; i < list.Count; i++) { context.CancellationToken.ThrowIfCancellationRequested(); formatter.Serialize(ref writer, ref context, list[i]); } } else { IReadOnlyList <TElement> rels = Unsafe.As <IEnumerable <TElement>, IReadOnlyList <TElement> >(ref value); writer.WriteVariableNumber(rels.Count); for (int i = 0; i < rels.Count; i++) { context.CancellationToken.ThrowIfCancellationRequested(); formatter.Serialize(ref writer, ref context, rels[i]); } } writer.WriteBackFixNumber(pos, checked ((int)(writer.Position - pos - BssomBinaryPrimitives.FixUInt32NumberSize))); } }
public static TypeInfo BuildICollectionImplementationType(DynamicFormatterAssembly assembly, Type type, ConstructorInfo constructor, Type itemType, bool isImplGenerIList, bool IsImplIList, bool isImplGenerICollec, bool isImplIReadOnlyList) { TypeBuilder typeBuilder = assembly.DefineFormatterType(type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); if (itemType == typeof(object)) { //itemType is Object, Array2 if (IsImplIList) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } else { if (Array1FormatterHelper.IsArray1Type(itemType)) { //Array1 TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) })); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) })); } else { if (isImplGenerIList || isImplIReadOnlyList) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType)); } } MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); ParameterInfo[] args = constructor.GetParameters(); if (args.Length == 1 && args[0].ParameterType != typeof(int)) { //new T(IEnumerable t) Type dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type); MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateInjectCtor)); methodinfo.Invoke(null, new object[] { constructor, args[0].ParameterType }); TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static)); } else { if (itemType == typeof(DateTime))//DateTime需要特殊处理,因为要处理Standrand和Native { Type dtCollBuilder = typeof(DateTimeCollectionDeserializeBuilder <>).MakeGenericType(type); MethodInfo methodinfo = dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .ConstructorInit)); methodinfo.Invoke(null, new object[] { constructor }); TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .Deserialize))); } else { Type dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type); if (args.Length == 0) { MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithEmptyCtor)); methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType }); } else { DEBUG.Assert(args.Length == 1 && args[0].ParameterType == typeof(int)); MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithCapacityCtor)); methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType }); } TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static)); } } return(typeBuilder.CreateTypeInfo()); }
public static TypeInfo BuildICollectionInterfaceType(DynamicFormatterAssembly assembly, Type type, Type elementType) { TypeBuilder typeBuilder = assembly.DefineCollectionFormatterType(type, elementType); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); if (type.IsGenericType == false) { DEBUG.Assert(type == typeof(IEnumerable) || type == typeof(IList) || type == typeof(ICollection)); //itemType is Object, Array2 if (type == typeof(IList)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(object))); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } else { Type genericTypeDefine = type.GetGenericTypeDefinition(); DEBUG.Assert(genericTypeDefine == typeof(IEnumerable <>) || genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(ICollection <>) || genericTypeDefine == typeof(ISet <>) || genericTypeDefine == typeof(IReadOnlyList <>) || genericTypeDefine == typeof(IReadOnlyCollection <>)); if (Array1FormatterHelper.IsArray1Type(elementType)) { //Array1 TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array1FormatterHelper).GetMethod(Array1FormatterHelper.DeserializeSetPrefix + elementType.Name, BindingFlags.Public | BindingFlags.Static)); } else { Type listFormatterType = Array1ResolverGetFormatterHelper.GetListFormatterType(elementType); FieldInfo field = listFormatterType.GetField(nameof(DateTimeListFormatter.Instance), BindingFlags.Static | BindingFlags.Public); MethodInfo method = listFormatterType.GetMethod(nameof(DateTimeListFormatter.Deserialize)); TypeBuildHelper.CallOneStaticFieldMethodInDeserialize(deserializeMethod, field, method); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); } else { if (genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(IReadOnlyList <>)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeSet), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } } return(typeBuilder.CreateTypeInfo()); }