private static Expression BuildSizeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(typeof(int), "returnLable"); if (!type.IsValueType) { //if (value==null) // goto label: 1; ary.Add(CommonExpressionMeta.Block_IfNullSize(instance, type, returnTarget)); } ParameterExpression size = Expression.Variable(typeof(int)); SerializeMemberInfo[] mems = serializationInfo.SerializeMemberInfos; if (mems.Length == 0) { ary.Add(Expression.Assign(size, Expression.Constant(Array3Cache.Empty.Length))); } else { int maxLen = mems[mems.Length - 1].KeyIndex + 1; ary.Add(Expression.Assign(size, Expression.Constant(BssomBinaryPrimitives.Array3HeaderSize(maxLen)))); FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); int nullNumber = 0; int realIndex = 0; for (int i = 0; i < maxLen; i++) { if (mems[realIndex].KeyIndex != i) { nullNumber++; } else { //Size(mem.Value) ary.Add(SpecialCodeGenExpression.SizeValues(mems[realIndex], instance, size, memFormatters)); realIndex++; } } if (nullNumber > 0) { ary.Add(Expression.AddAssign(size, Expression.Constant(nullNumber * BssomBinaryPrimitives.NullSize))); } } ary.Add(Expression.Label(returnTarget, size)); return(Expression.Block(new ParameterExpression[] { size }, ary)); }
private static Expression BuildDeserializeCore(Type t, ObjectSerializationInfo serializationInfo) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(t, "returnLable"); //int num; ParameterExpression num = Expression.Variable(typeof(int), "num"); //int for-i; ParameterExpression forVariable = Expression.Variable(typeof(int), "i"); //context.option.Security.DepthStep(ref reader); ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep); //if(reader.TryReadNullWithEnsureBuildInType(BssomType.Array3)) // return default(t); ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureBuildInType(BssomType.Array3), Expression.Return(returnTarget, Expression.Default(t)))); //T t = new T(); ParameterExpression instance = Expression.Parameter(t, "instance"); if (serializationInfo.IsDefaultNoArgsCtor) { ary.Add(Expression.Assign(instance, Expression.New(t))); } else { ParameterInfo[] parInfos = serializationInfo.BestmatchConstructor.GetParameters(); Expression[] pars = new Expression[parInfos.Length]; if (serializationInfo.ConstructorParametersIsDefaultValue) { for (int i = 0; i < parInfos.Length; i++) { pars[i] = Expression.Default(parInfos[i].ParameterType); } ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars))); } else { object[] cps = serializationInfo.ConstructorParameters; for (int i = 0; i < parInfos.Length; i++) { pars[i] = Expression.Constant(cps[i], parInfos[i].ParameterType); } ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars))); } } //reader.SkipVariableNumber() ary.Add(CommonExpressionMeta.Call_Reader_SkipVariableNumber); //num = reader.ReadVariableNumber() ary.Add(Expression.Assign(num, CommonExpressionMeta.Call_Reader_ReadVariableNumber)); //i = 0; ary.Add(Expression.Assign(forVariable, Expression.Constant(0))); var members = serializationInfo.SerializeMemberInfos; if (members.Length > 0) { //reader.Buffer.Seek(offsetSegment, Current) ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Convert(Expression.Multiply(num, Expression.Constant(BssomBinaryPrimitives.FixUInt32NumberSize)), typeof(Int64)), BssomSeekOrgin.Current)); //switch(i) // case 0: instance.Key0 = readValue(); // case 3: instance.Key1 = readValue(); // case 5: instance.Key2 = readValue(); // default: skipObj(); FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); SwitchCase[] switchCases = new SwitchCase[members.Length]; for (int i = 0; i < members.Length; i++) { switchCases[i] = Expression.SwitchCase(SpecialCodeGenExpression.ReadValues(members[i], instance, memFormatters), Expression.Constant(members[i].KeyIndex)); } Expression content = Expression.Switch( typeof(void), forVariable, CommonExpressionMeta.Call_Reader_SkipObject, null, switchCases ); ary.Add(For(forVariable, Expression.LessThan(forVariable, num), Expression.Assign(forVariable, Expression.Add(forVariable, Expression.Constant(1))), content)); } //context.Depth--; ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign); ary.Add(Expression.Return(returnTarget, instance)); ary.Add(Expression.Label(returnTarget, instance)); return(Expression.Block(new ParameterExpression[] { instance, num, forVariable, }, ary)); }
private static Expression BuildSerializeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(typeof(void), "returnLable"); if (!type.IsValueType) { //if (value==null) // writer.WriteNull(); goto label; ary.Add(CommonExpressionMeta.Block_IfNullWriteNullWithReturn(instance, type, returnTarget)); } ParameterExpression[] variables = null; var keys = serializationInfo.SerializeMemberInfos; if (keys.Length == 0) { //writer.WriteRaw(Array3Cache._EmptyBuffer); ary.Add(CommonExpressionMeta.Call_WriteRaw(Expression.Field(null, Array3Cache._EmptyBuffer))); } else { int maxLen = keys[keys.Length - 1].KeyIndex + 1; Type stackallocBlockType = StackallocBlockProvider.GetOrCreateType(maxLen * sizeof(uint)); //long position; //Block{size} block; //IntPtr blockPtr; variables = new ParameterExpression[3]; variables[0] = Expression.Variable(typeof(long), "elementOffPosition"); variables[1] = Expression.Variable(stackallocBlockType, "block"); variables[2] = Expression.Variable(typeof(IntPtr), "blockPtr"); //position = writer.WriteArray3Header(keys.Length); ary.Add(Expression.Assign(variables[0], CommonExpressionMeta.Call_WriteArray3Header(maxLen))); //block = new Block{size}(); ary.Add(Expression.Assign(variables[1], Expression.New(stackallocBlockType))); //blockPtr = AsPointer(ref block); ary.Add(Expression.Assign(variables[2], ExpressionTreeAux.AsPointerExpression(variables[1]))); //0,3,5 --> maxLen = 6 FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); int realIndex = 0; for (int i = 0; i < maxLen; i++) { //StackallocBlockHelper.WriteUInt(blockPtr, 0, (uint)(writer.Position - position)); ary.Add(Expression.Call(null, StackallocBlockHelper._WriteUIntMethodInfo, variables[2], Expression.Constant(i), Expression.Convert(Expression.Subtract(CommonExpressionMeta.Field_WriterPos, variables[0]), typeof(uint)))); if (keys[realIndex].KeyIndex != i) { //WriteNull() ary.Add(CommonExpressionMeta.Call_Writer_WriteNull); } else { //Writer(mem.Value) ary.Add(SpecialCodeGenExpression.WriteValues(keys[realIndex], instance, memFormatters)); realIndex++; } } //writer.WriteBackArray3Header(blockPtr) ary.Add(CommonExpressionMeta.Call_WriteBackArray3Header(variables[0], variables[2], maxLen)); } ary.Add(Expression.Label(returnTarget)); if (variables != null) { return(Expression.Block(variables, ary)); } return(Expression.Block(ary)); }