Resolvers
ICollectionResolver.cs
//using System.Runtime.CompilerServices;
using Bssom.Serializer.Formatters;
using Bssom.Serializer.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
namespace Bssom.Serializer.Resolvers
{
///
/// 获取和生成具有IColloction行为的类型的
/// Get and generate the type with IColloction behavior
///
public sealed clast ICollectionResolver : IFormatterResolver
{
internal const string ModuleName = "Bssom.Serializer.Resolvers.IColloctionResolver";
internal static readonly DynamicFormatterastembly Dynamicastembly;
///
/// The singleton instance that can be used.
///
public static readonly ICollectionResolver Instance;
static ICollectionResolver()
{
Instance = new ICollectionResolver();
Dynamicastembly = new DynamicFormatterastembly(ModuleName);
}
public IBssomFormatter GetFormatter()
{
return FormatterCache.Formatter;
}
private static clast FormatterCache
{
public static readonly IBssomFormatter Formatter;
static FormatterCache()
{
Type t = typeof(T);
if (Array1ResolverGetFormatterHelper.TryGetFormatter(t, out IBssomFormatter formatter))
{
Formatter = (IBssomFormatter)formatter;
return;
}
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ArraySegment))
{
Formatter = (IBssomFormatter)Activator.CreateInstance(typeof(ArraySegmentFormatter).MakeGenericType(t.GetGenericArguments()));
return;
}
if (TypeIsArray(t, out int rank, out Type elementType))
{
if (rank == 1)
{
Formatter = (IBssomFormatter)Activator.CreateInstance(typeof(OneDimensionalArrayFormatter).MakeGenericType(elementType));
}
else if (rank == 2)
{
Formatter = (IBssomFormatter)Activator.CreateInstance(typeof(TwoDimensionalArrayFormatter).MakeGenericType(elementType));
}
else if (rank == 3)
{
Formatter = (IBssomFormatter)Activator.CreateInstance(typeof(ThreeDimensionalArrayFormatter).MakeGenericType(elementType));
}
else if (rank == 4)
{
Formatter = (IBssomFormatter)Activator.CreateInstance(typeof(FourDimensionalArrayFormatter).MakeGenericType(elementType));
}
else
{
throw BssomSerializationTypeFormatterException.UnsupportedType(t);
}
return;
}
if (TypeIsCollection(t,
out ConstructorInfo constructor,
out Type itemType,
out bool isImplGenerIList, out bool IsImplIList, out bool isImplGenerICollec, out bool isImplIReadOnlyList))
{
TypeInfo buildType;
if (t.IsInterface)
{
buildType = ICollectionFormatterTypeBuilder.BuildICollectionInterfaceType(Dynamicastembly, t, itemType);
}
else
{
buildType = ICollectionFormatterTypeBuilder.BuildICollectionImplementationType(Dynamicastembly, t, constructor, itemType, isImplGenerIList, IsImplIList, isImplGenerICollec, isImplIReadOnlyList);
}
Formatter = (IBssomFormatter)Activator.CreateInstance(buildType);
}
}
}
internal static bool TypeIsCollection(Type t, out ConstructorInfo constructor, out Type itemType, out bool isImplGenerIList, out bool IsImplIList, out bool isImplGenerICollec, out bool isImplIReadOnlyList)
{
constructor = null;
itemType = null;
IsImplIList = false;
isImplGenerIList = false;
isImplGenerICollec = false;
isImplIReadOnlyList = false;
if (t.IsInterface)
{
if (t == typeof(IEnumerable) || t == typeof(ICollection) || t == typeof(IList))
{
itemType = typeof(object);
if (t == typeof(IList))
{
IsImplIList = true;
}
return true;
}
if (t.IsGenericType)
{
Type genericType = t.GetGenericTypeDefinition();
if (genericType == typeof(IEnumerable) || genericType == typeof(IList) || genericType == typeof(ICollection) || genericType == typeof(ISet) || genericType == typeof(IReadOnlyList) || genericType == typeof(IReadOnlyCollection))
{
if (genericType == typeof(IList))
{
isImplGenerIList = true;
isImplGenerICollec = true;
}
else if (genericType == typeof(ICollection) || genericType == typeof(ISet))
{
isImplGenerICollec = true;
}
else if (genericType == typeof(IReadOnlyList))
{
isImplIReadOnlyList = true;
}
itemType = t.GetGenericArguments()[0];
return true;
}
}
return false;
}
if (t.IsGenericType)
{
Type genericType = t.GetGenericTypeDefinition();
if (genericType == typeof(List))
{
itemType = t.GetGenericArguments()[0];
isImplGenerIList = true;
IsImplIList = true;
isImplGenerICollec = true;
isImplIReadOnlyList = true;
constructor = t.GetConstructor(new Type[] { typeof(int) });
return true;
}
}
bool isImplGenerIEnumerable = false;
bool isImplICollection = false;
Type generIEnumerableItemType = null;
Type generILissatemType = null;
Type generICollectionItemType = null;
Type[] intserfaces = t.GetInterfaces();
foreach (Type item in intserfaces)
{
if (item.IsGenericType)
{
Type genericTypeDefinition = item.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(IEnumerable))
{
isImplGenerIEnumerable = true;
generIEnumerableItemType = item.GetGenericArguments()[0];
}
else if (genericTypeDefinition == typeof(ICollection))
{
isImplGenerICollec = true;
generICollectionItemType = item.GetGenericArguments()[0];
}
else if (genericTypeDefinition == typeof(IList))
{
isImplGenerIList = true;
generILissatemType = item.GetGenericArguments()[0];
}
}
else if (item == typeof(ICollection))
{
isImplICollection = true;
}
else if (item == typeof(IList))
{
IsImplIList = true;
}
}
if (isImplGenerIList)
{
if (TryGetConstructorInfo(t, generILissatemType, true, out constructor))
{
itemType = generILissatemType;
return true;
}
}
if (isImplGenerICollec)
{
if (TryGetConstructorInfo(t, generICollectionItemType, true, out constructor))
{
itemType = generICollectionItemType;
return true;
}
}
if (isImplGenerIEnumerable && isImplICollection)
{
if (TryGetConstructorInfo(t, generIEnumerableItemType, false, out constructor))
{
itemType = generIEnumerableItemType;
return true;
}
}
if (IsImplIList)
{
if (TryGetConstructorInfo(t, typeof(object), true, out constructor))
{
itemType = typeof(object);
return true;
}
}
if (isImplICollection)
{
if (TryGetConstructorInfo(t, typeof(object), false, out constructor))
{
itemType = typeof(object);
return true;
}
}
return false;
}
private static bool TypeIsArray(Type t, out int rank, out Type elementType)
{
if (t.IsArray)
{
rank = t.GetArrayRank();
elementType = t.GetElementType();
return true;
}
rank = 0;
elementType = null;
return false;
}
private static bool TryGetConstructorInfo(Type targetType, Type itemType, bool isFindEmptyCtor, out ConstructorInfo constructor)
{
constructor = null;
foreach (ConstructorInfo item in targetType.GetConstructors())
{
ParameterInfo[] paras = item.GetParameters();
if (isFindEmptyCtor)
{
if (paras.Length == 0)
{
constructor = item;
return true;
}
}
if (constructor != null)
{
continue;
}
if (paras.Length == 1)
{
Type ctorArgType = paras[0].ParameterType;
if (targetType == ctorArgType)
{
continue;
}
if (
(TypeIsArray(ctorArgType, out int rank, out Type eleType) &&
rank == 1 && eleType == itemType
) ||
(TypeIsCollection(ctorArgType, out ConstructorInfo a, out eleType, out bool c, out bool d, out bool e, out bool f) &&
eleType == itemType)
)
{
constructor = item;
if (!isFindEmptyCtor)
{
return true;
}
}
}
}
return constructor != null;
}
}
}
namespace Bssom.Serializer.Internal
{
internal static clast Array1ResolverGetFormatterHelper
{
private static readonly Dictionary FormatterMap = new Dictionary()
{
{ typeof(Int16[]), Int16ArrayFormatter.Instance },
{ typeof(Int32[]), Int32ArrayFormatter.Instance },
{ typeof(Int64[]), Int64ArrayFormatter.Instance },
{ typeof(UInt16[]), UInt16ArrayFormatter.Instance },
{ typeof(UInt32[]), UInt32ArrayFormatter.Instance },
{ typeof(UInt64[]), UInt64ArrayFormatter.Instance },
{ typeof(Single[]), Float32ArrayFormatter.Instance },
{ typeof(Double[]), Float64ArrayFormatter.Instance },
{ typeof(bool[]), BooleanArrayFormatter.Instance },
{ typeof(byte[]), UInt8ArrayFormatter.Instance },//special
{ typeof(sbyte[]), Int8ArrayFormatter.Instance },
{ typeof(char[]), CharArrayFormatter.Instance },
{ typeof(DateTime[]), DateTimeArrayFormatter.Instance },
{ typeof(Decimal[]), DecimalArrayFormatter.Instance },
{ typeof(Guid[]),GuidArrayFormatter.Instance },
{ typeof(List), Int16ListFormatter.Instance },
{ typeof(List), Int32ListFormatter.Instance },
{ typeof(List), Int64ListFormatter.Instance },
{ typeof(List), UInt16ListFormatter.Instance },
{ typeof(List), UInt32ListFormatter.Instance },
{ typeof(List), UInt64ListFormatter.Instance },
{ typeof(List), Float32ListFormatter.Instance },
{ typeof(List), Float64ListFormatter.Instance },
{ typeof(List), BooleanListFormatter.Instance },
{ typeof(List), UInt8ListFormatter.Instance },//special
{ typeof(List), Int8ListFormatter.Instance },
{ typeof(List), CharListFormatter.Instance },
{ typeof(List), DateTimeListFormatter.Instance },
{ typeof(List), DecimalListFormatter.Instance },
{ typeof(List),GuidListFormatter.Instance },
{ typeof(ArraySegment), BooleanArraySegmentFormatter.Instance },
{ typeof(ArraySegment), UInt8ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Int8ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Int16ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), UInt16ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), CharArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Int32ArraySegmentFormatter.Instance },
{ typeof(ArraySegment),UInt32ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Int64ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), UInt64ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Float32ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), Float64ArraySegmentFormatter.Instance },
{ typeof(ArraySegment), DateTimeArraySegmentFormatter.Instance },
{ typeof(ArraySegment), DecimalArraySegmentFormatter.Instance },
{ typeof(ArraySegment),GuidArraySegmentFormatter.Instance },
};
internal static bool TryGetFormatter(Type t, out IBssomFormatter formatter)
{
if (FormatterMap.TryGetValue(t, out formatter))
{
return true;
}
return false;
}
internal static Type GetListFormatterType(Type itemType)
{
Type listT = typeof(List).MakeGenericType(itemType);
return FormatterMap[listT].GetType();
}
}
internal static clast ICollectionFormatterTypeBuilder
{
public static TypeInfo BuildICollectionInterfaceType(DynamicFormatterastembly astembly, Type type, Type elementType)
{
TypeBuilder typeBuilder = astembly.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.astert(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.astert(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();
}
public static TypeInfo BuildICollectionImplementationType(DynamicFormatterastembly astembly, Type type, ConstructorInfo constructor,
Type itemType,
bool isImplGenerIList, bool IsImplIList, bool isImplGenerICollec, bool isImplIReadOnlyList)
{
TypeBuilder typeBuilder = astembly.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.GenerateInjectCtor));
methodinfo.Invoke(null, new object[] { constructor, args[0].ParameterType });
TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache.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.ConstructorInit));
methodinfo.Invoke(null, new object[] { constructor });
TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder.Deserialize)));
}
else
{
Type dynamicCacheType = typeof(CollectionDynamicDelegateCache).MakeGenericType(type);
if (args.Length == 0)
{
MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache.GenerateDeserializeWithEmptyCtor));
methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType });
}
else
{
DEBUG.astert(args.Length == 1 && args[0].ParameterType == typeof(int));
MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache.GenerateDeserializeWithCapacityCtor));
methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType });
}
TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache.Deserialize), BindingFlags.Public | BindingFlags.Static));
}
}
return typeBuilder.CreateTypeInfo();
}
}
internal static clast DateTimeCollectionDeserializeBuilder where T : ICollection
{
private delegate T Ctor(ref BssomReader reader, int count);
private static Ctor constructor;
public static T Deserialize(ref BssomReader reader, ref BssomDeserializeContext context)
{
if (reader.TryReadNullWithEnsureBuildInType(BssomType.Array1))
{
return default;
}
byte type = reader.ReadBssomType();
switch (type)
{
case BssomType.TimestampCode:
{
reader.SkipVariableNumber();
int len = reader.ReadVariableNumber();
T t = constructor(ref reader, len);
for (int i = 0; i < len; i++)
{
context.CancellationToken.ThrowIfCancellationRequested();
t.Add(reader.ReadStandDateTimeWithOutTypeHead());
}
return t;
}
case BssomType.NativeCode:
{
reader.EnsureType(NativeBssomType.DateTimeCode);
reader.SkipVariableNumber();
int len = reader.ReadVariableNumber();
T t = constructor(ref reader, len);
for (int i = 0; i < len; i++)
{
context.CancellationToken.ThrowIfCancellationRequested();
t.Add(reader.ReadNativeDateTimeWithOutTypeHead());
}
return t;
}
default:
throw BssomSerializationOperationException.UnexpectedCodeRead(type, reader.Position);
}
}
public static void ConstructorInit(ConstructorInfo ctor)
{
ParameterInfo[] paras = ctor.GetParameters();
ParameterExpression count = Expression.Parameter(typeof(int));
Expression body;
if (paras.Length == 0)
{
body = Expression.New(ctor);
}
else
{
body = Expression.New(ctor, count);
}
constructor = Expression.Lambda(body, CommonExpressionMeta.Par_Reader, count).Compile();
}
}
internal static clast CollectionDynamicDelegateCache
{
public static Deserialize Deserialize;
public static void GenerateDeserializeWithEmptyCtor(ConstructorInfo constructor, bool isImplGenerICollec, Type itemType)
{
GenerateDeserializeWithCore(isImplGenerICollec, itemType, (len) => Expression.New(constructor));
}
public static void GenerateDeserializeWithCapacityCtor(ConstructorInfo constructor, bool isImplGenerICollec, Type itemType)
{
GenerateDeserializeWithCore(isImplGenerICollec, itemType, (len) => Expression.New(constructor, len));
}
private static void GenerateDeserializeWithCore(bool isImplGenerICollec, Type itemType, Func ctor)
{
/*
if (reader.TryReadNullWithEnsureArray1BuildInType(BssomType.Int8Code))/TryReadNullWithEnsureArray1NativeType(NativeBssomType.CharCode)/TryReadNullWithEnsureBuildInType(BssomType.Array2)
return default;
context.option.Security.DepthStep(ref reader);
reader.SkipVariableNumber();
int len = reader.ReadVariableNumber();
T t = new T(len);
Fill(ref t,ref reader,ref context,len);
context.Depth--;
return t;
*/
bool isArray1Type = Array1FormatterHelper.IsArray1Type(itemType, out bool isNativeType, out byte typeCode, out string typeCodeName);
Type t = typeof(T);
List ary = new List(7);
LabelTarget returnTarget = Expression.Label(t, "returnLable");
if (isArray1Type)
{
if (isNativeType)
{
//if (reader.ryReadNullWithEnsureArray1NativeType(NativeType))
// goto label;
ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureArray1NativeType(typeCode), Expression.Return(returnTarget, Expression.Default(t))));
}
else
{
//if (reader.Call_Reader_TryReadNullWithEnsureArray1BuildInType(BuildInType))
// goto label;
ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureArray1BuildInType(typeCode), Expression.Return(returnTarget, Expression.Default(t))));
}
}
else
{
//if (reader.TryReadNullWithEnsureBuildInType(BssomType.Array2))
// goto label;
ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureBuildInType(BssomType.Array2), Expression.Return(returnTarget, Expression.Default(t))));
}
//context.option.Security.DepthStep(ref reader);
ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep);
//reader.SkipVariableNumber();
ary.Add(CommonExpressionMeta.Call_Reader_SkipVariableNumber);
//int len = reader.ReadVariableNumber();
ParameterExpression len = Expression.Variable(typeof(int));
ary.Add(Expression.astign(len, CommonExpressionMeta.Call_Reader_ReadVariableNumber));
//T t = ctor(len);
ParameterExpression instance = Expression.Variable(t);
ary.Add(Expression.astign(instance, ctor(len)));
MethodInfo method = null;
if (isImplGenerICollec == false)
{
//IColloctionFormatterHelper.Fill_ImplIList(ref t,ref reader,ref context,len)
method = typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.Fill_ImplIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(t);
}
else
{
if (isArray1Type)
{
//IColloctionFormatterHelper.Fill{TypeCodeName}(ref t,ref reader,ref context,len)
method = typeof(Array1FormatterHelper).GetMethod(Array1FormatterHelper.FillPrefix + typeCodeName.ToString().Replace("Code", ""), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(t);
}
else
{
//IColloctionFormatterHelper.Fill_ImplICollection(ref t,ref reader,ref context,len)
method = typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.Fill_ImplICollection), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(new Type[] { t, itemType });
}
}
ary.Add(Expression.Call(null, method, instance, CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext, len));
//context.Depth--;
ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_Decrementastign);
//return t;
ary.Add(Expression.Return(returnTarget, instance));
//label default(T)
ary.Add(Expression.Label(returnTarget, instance));
BlockExpression block = Expression.Block(new ParameterExpression[] { instance, len }, ary);
Deserialize = Expression.Lambda(block, CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext).Compile();
}
public static void GenerateInjectCtor(ConstructorInfo constructor, Type injectType)
{
Deserialize = Expression.Lambda(CommonExpressionMeta.GenerateInjectCtor(typeof(T), constructor, injectType), CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext).Compile();
}
}
}