예제 #1
0
        private Header ReadHeader()
        {
            var header = new Header();

            header.version        = InputReader.ReadUInt32();
            header.fileSize       = InputReader.ReadUInt32();
            header.crc            = InputReader.ReadUInt32();
            header.sectionsOffset = InputReader.ReadUInt32();
            header.numSections    = InputReader.ReadUInt32();
            header.rootType       = ReadSectionReferenceUnchecked();
            header.rootNode       = ReadSectionReferenceUnchecked();
            header.tag            = InputReader.ReadUInt32();
            header.extraTags      = new UInt32[Header.ExtraTagCount];
            for (int i = 0; i < Header.ExtraTagCount; i++)
            {
                header.extraTags[i] = InputReader.ReadUInt32();
            }

            if (header.version >= 7)
            {
                header.stringTableCrc = InputReader.ReadUInt32();
                header.reserved1      = InputReader.ReadUInt32();
                header.reserved2      = InputReader.ReadUInt32();
                header.reserved3      = InputReader.ReadUInt32();
            }

            if (header.version < 6 || header.version > 7)
            {
                throw new ParsingException(String.Format("Unsupported GR2 version; file is version {0}, supported versions are 6 and 7", header.version));
            }

            // if (header.tag != Header.Tag)
            //    throw new ParsingException(String.Format("Incorrect header tag; expected {0:X8}, got {1:X8}", Header.Tag, header.tag));

            Debug.Assert(header.fileSize <= InputStream.Length);
            Debug.Assert(header.CalculateCRC(InputStream) == header.crc);
            Debug.Assert(header.sectionsOffset == header.Size());
            Debug.Assert(header.rootType.Section < header.numSections);
            // TODO: check rootTypeOffset after serialization
            Debug.Assert(header.stringTableCrc == 0);
            Debug.Assert(header.reserved1 == 0);
            Debug.Assert(header.reserved2 == 0);
            Debug.Assert(header.reserved3 == 0);

#if DEBUG_GR2_SERIALIZATION
            System.Console.WriteLine(" ===== GR2 Header ===== ");
            System.Console.WriteLine(String.Format("Version {0}, Size {1}, CRC {2:X8}", header.version, header.fileSize, header.crc));
            System.Console.WriteLine(String.Format("Offset of sections: {0}, num sections: {1}", header.sectionsOffset, header.numSections));
            System.Console.WriteLine(String.Format("Root type section {0}, Root type offset {1:X8}", header.rootType.Section, header.rootType.Offset));
            System.Console.WriteLine(String.Format("Root node section {0} {1:X8}", header.rootNode.Section, header.rootNode.Offset));
            System.Console.WriteLine(String.Format("Tag: {0:X8}, Strings CRC: {1:X8}", header.tag, header.stringTableCrc));
            System.Console.WriteLine(String.Format("Extra tags: {0:X8} {1:X8} {2:X8} {3:X8}", header.extraTags[0], header.extraTags[1], header.extraTags[2], header.extraTags[3]));
            System.Console.WriteLine(String.Format("Reserved: {0:X8} {1:X8} {2:X8}", new object[] { header.reserved1, header.reserved2, header.reserved3 }));
#endif

            return(header);
        }
예제 #2
0
        private Header InitHeader()
        {
            var header = new Header();

            header.version        = Header.Version;
            header.fileSize       = 0;                      // Set after serialization is finished
            header.crc            = 0;                      // Set after serialization is finished
            header.sectionsOffset = header.Size();
            header.rootType       = new SectionReference(); // Updated after serialization is finished
            header.rootNode       = new SectionReference(); // Updated after serialization is finished
            header.numSections    = (UInt32)SectionType.Max + 1;
            header.tag            = VersionTag;
            header.extraTags      = new UInt32[Header.ExtraTagCount];
            for (int i = 0; i < Header.ExtraTagCount; i++)
            {
                header.extraTags[i] = 0;
            }
            header.stringTableCrc = 0;
            header.reserved1      = 0;
            header.reserved2      = 0;
            header.reserved3      = 0;

            return(header);
        }
예제 #3
0
        public byte[] Write(object root)
        {
            using (this.Writer = new BinaryWriter(Stream))
            {
                this.Magic = InitMagic();
                WriteMagic(Magic);

                this.Header = InitHeader();
                WriteHeader(Header);

                for (int i = 0; i < Header.numSections; i++)
                {
                    var section = new WritableSection((SectionType)i, this);
                    WriteSectionHeader(section.Header);
                    Sections.Add(section);
                }

                Magic.headersSize = (UInt32)Stream.Position;

                CurrentSection = Sections[(int)SectionType.Main];
                CurrentSection.WriteStruct(root);

                while (ArrayWrites.Count > 0 || StructWrites.Count > 0 || StringWrites.Count > 0)
                {
                    FlushPendingWrites();
                }

                foreach (var defn in Types.Values)
                {
                    Sections[(int)SectionType.Discardable].WriteStructDefinition(defn);
                }

                // We need to do this again to flush strings written by WriteMemberDefinition()
                FlushPendingWrites();

                FinalizeOffsets();

                foreach (var section in Sections)
                {
                    section.Header.first16bit = (UInt32)section.MainStream.Length;
                    section.Header.first8bit  = (UInt32)section.MainStream.Length;
                    section.Finish();
                }

                var relocSection = Sections[(int)SectionType.Discardable];
                foreach (var section in Sections)
                {
                    relocSection.WriteSectionRelocations(section);
                }

                foreach (var section in Sections)
                {
                    relocSection.WriteSectionMixedMarshallingRelocations(section);
                }

                foreach (var section in Sections)
                {
                    // Pad section size to a multiple of the section alignment
                    while ((section.MainStream.Position % section.Header.alignment) > 0)
                    {
                        section.Writer.Write((Byte)0);
                    }

                    section.MainStream.Flush();
                    section.Header.offsetInFile     = (UInt32)Stream.Position;
                    section.Header.uncompressedSize = (UInt32)section.MainStream.Length;
                    section.Header.compressedSize   = (UInt32)section.MainStream.Length;
                    Writer.Write(section.MainStream.ToArray());
                }

                foreach (var section in Sections)
                {
                    section.Header.relocationsOffset          += relocSection.Header.offsetInFile;
                    section.Header.mixedMarshallingDataOffset += relocSection.Header.offsetInFile;
                }

                var rootStruct = LookupStructDefinition(root.GetType(), root);
                Header.rootType = ObjectOffsets[rootStruct];
                Header.rootNode = new SectionReference(SectionType.Main, 0);
                Header.fileSize = (UInt32)Stream.Length;

                Stream.Seek(Magic.MagicSize + Header.Size(), SeekOrigin.Begin);

                foreach (var section in Sections)
                {
                    WriteSectionHeader(section.Header);
                }

                Header.crc = Header.CalculateCRC(Stream);
                Stream.Seek(0, SeekOrigin.Begin);
                WriteMagic(Magic);
                WriteHeader(Header);

                return(Stream.ToArray());
            }
        }