using System; using System.Collections.Generic; using Oni.Collections; namespace Oni { internal sealed class DatPacker { private readonly List inputPaths = new List(); private string targetFilePath; private bool targetBigEndian; private long targetTemplateChecksum; public List InputPaths => inputPaths; public string TargetFilePath { get { return targetFilePath; } set { targetFilePath = value; } } public bool TargetBigEndian { get { return targetBigEndian; } set { targetBigEndian = value; } } public long TargetTemplateChecksum { get { return targetTemplateChecksum; } set { targetTemplateChecksum = value; } } public void Pack(InstanceFileManager fileManager, IEnumerable filePaths) { var inputs = new List(); var seenFilePaths = new Set(StringComparer.OrdinalIgnoreCase); foreach (string filePath in filePaths) { if (seenFilePaths.Add(filePath)) inputs.Add(fileManager.OpenFile(filePath)); } inputs.Reverse(); var descriptors = GetImportedDescriptors(inputs); if (descriptors.Count > 0) { var writer = InstanceFileWriter.CreateV31(targetTemplateChecksum, targetBigEndian); writer.AddDescriptors(descriptors, true); Console.WriteLine("Writing {0}", targetFilePath); writer.Write(targetFilePath); } } public void Import(InstanceFileManager fileManager, string[] inputDirPaths) { Console.WriteLine("Reading files from {0}", string.Join(";", inputDirPaths)); var inputsFiles = fileManager.OpenDirectories(inputDirPaths); var descriptors = GetImportedDescriptors(inputsFiles); if (descriptors.Count > 0) { var writer = InstanceFileWriter.CreateV31(targetTemplateChecksum, targetBigEndian); writer.AddDescriptors(descriptors, true); Console.WriteLine("Writing {0}", targetFilePath); writer.Write(targetFilePath); } } private static List GetImportedDescriptors(List inputFiles) { var namedDescriptors = new Set(StringComparer.Ordinal); var ignored = new Set(); foreach (var file in inputFiles) { foreach (var descriptor in file.GetNamedDescriptors()) { if (namedDescriptors.Contains(descriptor.FullName)) { //Console.Error.WriteLine("WARNING: More than one instance has name {0}, ignoring.", descriptor.FullName); ignored.Add(descriptor); } else { namedDescriptors.Add(descriptor.FullName); } } } inputFiles.Sort((x, y) => string.Compare(x.Descriptors[0].FullName, y.Descriptors[0].FullName, StringComparison.Ordinal)); var descriptors = new List(4096); foreach (var file in inputFiles) { foreach (var descriptor in file.Descriptors) { if (ignored.Contains(descriptor)) continue; if (descriptor.HasName) { if (descriptor.IsPlaceholder && namedDescriptors.Contains(descriptor.FullName)) continue; namedDescriptors.Add(descriptor.FullName); } descriptors.Add(descriptor); } } descriptors.Sort((x, y) => x.Template.IsLeaf.CompareTo(y.Template.IsLeaf)); return descriptors; } } }