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);
relocSection.WriteSectionMixedMarshallingRelocations(section);
}
foreach (var section in Sections)
{
// Pad section size to a multiple of 4
while (section.MainStream.Position % 4 > 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());
Header.rootType = ObjectOffsets[rootStruct];
Header.rootNode = new SectionReference(SectionType.Main, 0);
Header.fileSize = (UInt32)Stream.Length;
Stream.Seek(Magic.MagicSize + Header.HeaderSize, 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();
}
}