public void Commit(EndianWriterEx writer) { if (!hasChanged) { return; } if (BlockRef != null && EntryCount != BlockRef.Count) { stream.ResizeTagBlock(writer, ref blockRef, EntrySize, EntryCount); //we dont know if our parent has already been written (or even will be) //just to be sure, we need to go back and update it with the new reference var refOffset = ParentBlock.EntrySize * ParentEntryIndex + OffsetInParent; writer.Seek(ParentBlock.PhysicalAddress + refOffset, SeekOrigin.Begin); BlockRef.Write(writer, null); } var rootAddress = BlockRef?.Pointer.Address ?? OffsetInParent; if (EntryCount > 0) { writer.Seek(rootAddress, SeekOrigin.Begin); writer.Write(data); //this writes our virtual pointers to disk (fix them below) } //the block references in our data array currently use virtual pointers //this restores the original pointers that got overwritten above foreach (var child in ChildBlocks) { writer.Seek(rootAddress + EntrySize * child.ParentEntryIndex + child.OffsetInParent + 4, SeekOrigin.Begin); writer.Write(child.BlockRef.Pointer.Value); } hasChanged = false; }
public static EndianWriterEx CreateWriter(this ICacheFile cache, Stream stream, bool leaveOpen) { var writer = new EndianWriterEx(stream, cache.ByteOrder, leaveOpen); if (cache.CacheType >= CacheType.Halo2Xbox) { writer.RegisterType <Matrix4x4>((m, v) => { writer.Write(m.M11); writer.Write(m.M12); writer.Write(m.M13); writer.Write(m.M21); writer.Write(m.M22); writer.Write(m.M23); writer.Write(m.M31); writer.Write(m.M32); writer.Write(m.M33); writer.Write(m.M41); writer.Write(m.M42); writer.Write(m.M43); }); } return(writer); }