private static TagData BuildTagDescription(Stream stream, TagInstance tag, out uint dataOffset)
{
var data = new TagData
{
Group = tag.Group,
MainStructOffset = tag.MainStructOffset,
};
foreach (var dependency in tag.Dependencies)
data.Dependencies.Add(dependency);
// Read pointer fixups
var reader = new BinaryReader(stream);
foreach (var pointerOffset in tag.PointerOffsets)
{
reader.BaseStream.Position = tag.HeaderOffset + pointerOffset;
data.PointerFixups.Add(new TagPointerFixup
{
WriteOffset = pointerOffset,
TargetOffset = tag.PointerToOffset(reader.ReadUInt32()),
});
}
// Find the start of the tag's data by finding the offset of the first block which is pointed to by something
// We CAN'T just calculate a header size here because we don't know for sure if there's padding and how big it is
var startOffset = tag.MainStructOffset;
foreach (var fixup in data.PointerFixups)
startOffset = Math.Min(startOffset, Math.Min(fixup.WriteOffset, fixup.TargetOffset));
// Now convert all offsets into relative ones
foreach (var fixup in data.PointerFixups)
{
fixup.WriteOffset -= startOffset;
fixup.TargetOffset -= startOffset;
}
data.ResourcePointerOffsets.AddRange(tag.ResourcePointerOffsets.Select(offset => offset - startOffset));
data.MainStructOffset -= startOffset;
dataOffset = startOffset;
return data;
}