public static IffFile GeneratePiff(IffFile iff, HashSet<Type> allowedTypes, HashSet<Type> disallowedTypes)
{
var piffFile = new IffFile();
var piff = new PIFF();
piff.SourceIff = iff.Filename;
var entries = new List<PIFFEntry>();
var chunks = iff.ListAll();
//write removals first
foreach (var c in iff.RemovedOriginal)
{
lock (c)
{
if ((allowedTypes == null || allowedTypes.Contains(c.GetType()))
&& (disallowedTypes == null || !disallowedTypes.Contains(c.GetType())))
{
entries.Add(new PIFFEntry {
Type = c.ChunkType, ChunkID = c.OriginalID, Delete = true,
ChunkLabel = c.ChunkLabel, ChunkFlags = c.ChunkFlags
});
}
}
}
foreach (var c in chunks)
{
lock (c)
{
if ((allowedTypes == null || allowedTypes.Contains(c.GetType()))
&& (disallowedTypes == null || !disallowedTypes.Contains(c.GetType())))
{
if (c.AddedByPatch)
{
//this chunk has been newly added.
var oldParent = c.ChunkParent;
piffFile.AddChunk(c);
c.ChunkParent = oldParent;
}
else if ((c.RuntimeInfo == ChunkRuntimeState.Modified || c.RuntimeInfo == ChunkRuntimeState.Patched))
{
var chunkD = MakeChunkDiff(c);
if (chunkD != null && (chunkD.Patches.Length > 0 || c.OriginalLabel != c.ChunkLabel || c.OriginalID != c.ChunkID))
{
entries.Add(chunkD);
}
c.RuntimeInfo = ChunkRuntimeState.Patched;
}
}
}
}
if (entries.Count == 0) return null; //no patch data...
piff.Entries = entries.ToArray();
piff.ChunkID = 256;
piff.ChunkLabel = (piff.SourceIff + " patch");
piff.ChunkProcessed = true;
piffFile.AddChunk(piff);
piffFile.Filename = piff.SourceIff.Substring(0, piff.SourceIff.Length - 4)+".piff";
return piffFile;
}