private GenDeserializeContext( GenDeserializeContext parent, IExpression instanceShortcut, IExpression memberShortcut) : base(parent.Generator) { DeserializationArgs = parent.DeserializationArgs; Reader = parent.Reader; Instance = instanceShortcut; Member = memberShortcut; Header = parent.Header; IsBaseType = false; }
public void GenerateInnerDeserializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.CreateExpression(g.GetParameter(0)); var args = g.CreateExpression(g.GetParameter(1)); var header = g.DeclareLocal(typeof(BarfObjectHeader)); g.BeginAssign(header); { g.Load(args); g.Call(typeof(BarfDeserializationArgs) .ResolveMethod("BeginObject") .MakeGenericMethod(_def.Type)); } g.EndAssign(); var version = g.CreateExpression(header).AddMember("Version"); g.If(() => { g.Load(header); g.LoadMember("IsNull"); return(BinaryOperator.IsTrue); }); { g.BeginAssign(instance); g.LoadNull(); g.EndAssign(); } g.Else(); { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); g.NewObject(instance.Type); g.EndAssign(); } } g.EndIf(); var partsByVersion = _def.Parts .GroupBy <PartDefinition, int>(part => part.Version) .OrderBy <IGrouping <int, PartDefinition>, int>(group => group.Key); int count = 0; foreach (var versionGroup in partsByVersion) { g.If(() => { g.Load(version); g.Load(versionGroup.Key); return(BinaryOperator.GreaterThanOrEqualTo); }); { foreach (var part in versionGroup) { Trace.WriteLine("\tBuilding Deserialize Part - " + part.FullName); g.BeginScope(); var context = new GenDeserializeContext(g, part, instance, args, header); part.GetCurrentBuilder() .GenerateDeserializePart(context); g.EndScope(); } } count++; } for (; count > 0; --count) { g.EndIf(); } if (_def.IsForwardCompatible) { g.If(() => { g.Load(header).LoadMember("Version"); g.Load(_def.CurrentVersion); return(BinaryOperator.GreaterThan); }); { g.Load(args); g.BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod( "CaptureFutureData", new[] { _def.Type }, typeof(BarfObjectHeader), new GenericParameter(0).MakeByRefType())); { g.Load(header); g.Load(instance, LoadOptions.AnyAsAddress); } g.EndCall(); } g.EndIf(); } } g.EndIf(); g.Load(args).BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod("EndObject", new[] { _def.Type }, typeof(BarfObjectHeader))); { g.Load(header); } g.EndCall(); g.Return(); }