예제 #1
0
        public override void PrintTo(ICodePrinter printer, ILogPrinter logPrinter, PrintFlags flags)
        {
            Debug.Assert(printer != null && logPrinter != null);

            base.PrintTo(printer, logPrinter, flags);

            PrintContext context = new PrintContext(printer, logPrinter, flags);

            if (unalignedSizeOrOffsets)
            {
                // the size of the structure or field offsets is "odd" -> need to pragma pack (1) it
                context.SetPack(1, true);
            }
            else
            {
                context.SetPack(DefaultPack, true);
            }

            if (!isUnion)
            {
                printer.PrintLn();

                printer.Print(OutputType.Keyword, "struct");
                PrintIdentifierAndSize(context);

                printer.Print(OutputType.Operator, "{");

                printer.Indent();
            }

            try
            {
                if (!isInvalid)
                {
                    int current_offset = 0;

                    for (int i = 0; i < fields.Length; i++)
                    {
                        if (isExplicitLayout)
                        {
                            // this may in fact print more fields in a union, so i is passed byref
                            PrintExplicitlyLaidOutField(context, ref i, ref current_offset);
                        }
                        else
                        {
                            PrintSequentiallyLaidOutField(context, i, ref current_offset);
                        }
                    }

                    int tmp_offset = current_offset;
                    if (!context.UsedNonDefaultPack)
                    {
                        // if we never used a pack different from the default (8), we are sure
                        // about the implicit padding at the end of the structure
                        AlignSelf(ref tmp_offset);
                    }

                    if (size != tmp_offset)
                    {
                        // add final padding to the end of the structure to make its size exactly as requested
                        context.PrintPadding(size - current_offset, context.UsedNonDefaultPack);
                    }
                }
            }
            finally
            {
                if (!isUnion)
                {
                    printer.Unindent();
                    printer.PrintLn();

                    printer.Print(OutputType.Operator, "};");
                }

                context.SetDefaultPack();
            }
        }