Ejemplo n.º 1
0
 public override CodeNode VisitUnconverterShell(UnconverterShellNode node)
 {
     _Writer.WriteStartElement("UnconverterShell");
     Visit(node.Block);
     _Writer.WriteEndElement();
     return(node);
 }
Ejemplo n.º 2
0
        //unconverter node visiting
        public virtual CodeNode VisitUnconverterShell(UnconverterShellNode node)
        {
            var visitedBlock = Visit(node.Block);

            if (visitedBlock == node.Block)
            {
                return(node);
            }
            else
            {
                return(new UnconverterShellNode(visitedBlock as BlockNode ?? new BlockNode(visitedBlock)));
            }
        }
Ejemplo n.º 3
0
        public void GenerateUnconverter()
        {
            _Fields = GetFieldLayoutsAndAssignments();

            var node = new UnconverterShellNode(
                new BlockNode(
                    from pair in _Fields.AsEnumerable().Reverse()
                    //don't generate code for dependency properties
                    where !(pair.Key is DependencyProperty)
                    //this call through reflection is icky, but marginally better than the hard-coded table
                    //we're just binding to the generic GenerateAssignment method for the field's type
                    select GenerateAssignment(pair)));

            new UnconverterEmittingVisitor {
                ConcreteType = _Type,
                ILGen        = _ILGen,
            }.Visit(node);
        }
Ejemplo n.º 4
0
        public override CodeNode VisitUnconverterShell(UnconverterShellNode node)
        {
            Log($"Unconverter for {ConcreteType}");
            //initialize the concrete record and cast the arg to it
            Log($"Creating instance");
            _ConcreteRecordLocal = ILGen.DeclareLocal(ConcreteType);
            ILGen.Ldarg_0();
            ILGen.Castclass(ConcreteType);
            ILGen.Stloc(_ConcreteRecordLocal);

            //initialize _StartedWriting
            _StartedWriting = ILGen.DeclareLocal <bool>();
            ILGen.Ldc_I4_0();
            ILGen.Stloc(_StartedWriting);

            //create a memory stream for writing
            Log($"Generating writer over stream");
            LocalBuilder memoryStream = ILGen.DeclareLocal <MemoryStream>();

            ILGen.Newobj <MemoryStream>();
            ILGen.Stloc(memoryStream);
            ILGen.BeginExceptionBlock();

            //create a binary writer
            _Writer = ILGen.DeclareLocal <BinaryWriter>();
            //load args for binary writer .ctor
            ILGen.Ldloc(memoryStream);
            ILGen.Ldarg_1();  //the endianness
            ILGen.Ldc_I4_1(); //true for writing backwards
            ILGen.Newobj <BinaryWriter>(typeof(MemoryStream), typeof(Endian), typeof(bool));
            ILGen.Stloc(_Writer);
            //nothing on the stack

            //visit the children and let them emit
            Visit(node.Block);

            //at this point, the memory stream should have all the bytes for the content in it, but backwards

            //get the content
            Log($"Getting data and reversing");
            ILGen.Ldloc(memoryStream);
            ILGen.Callvirt(typeof(MemoryStream).GetMethod("ToArray"));
            var content = ILGen.DeclareLocal <byte[]>();

            ILGen.Stloc(content);
            ILGen.Ldloc(content);
            ILGen.Call(typeof(Array).GetMethod("Reverse", typeof(Array)));

            ILGen.BeginFinallyBlock();
            //dispose the memorystream
            Log($"Cleaning up");
            ILGen.Ldloc(memoryStream);
            ILGen.Callvirt(typeof(Stream).GetMethod("Dispose"));
            ILGen.EndExceptionBlock();

            //get the record type
            ILGen.Ldarg_0();
            ILGen.Callvirt(typeof(StdfRecord).GetProperty("RecordType").GetGetMethod());

            //load the content
            ILGen.Ldloc(content);

            //get the endian
            ILGen.Ldarg_1();

            //new up a new UnknownRecord!
            Log($"returning the populated UnknownRecord");
            ILGen.Newobj <UnknownRecord>(typeof(RecordType), typeof(byte[]), typeof(Endian));

            ILGen.Ret();

            return(node);
        }