private static Stream CreateCoolArchiveStream(Stream input) { input.Seek(0, SeekOrigin.Begin); var isCoolArchive = CoolArchiveFile.CheckHeader(input); input.Seek(0, SeekOrigin.Begin); if (isCoolArchive == false) { return(null); } var archive = new CoolArchiveFile(); archive.Deserialize(input); return(new CoolStream(archive, input)); }
public static void Main(string[] args) { var endian = Endian.Little; bool verbose = false; bool compress = false; bool showHelp = false; var options = new OptionSet { { "v|verbose", "be verbose (list files)", v => verbose = v != null }, { "l|little-endian", "write in little endian mode", v => SetOption(v, ref endian, Endian.Little) }, { "b|big-endian", "write in big endian mode", v => SetOption(v, ref endian, Endian.Big) }, { "c|compress", "compress small archive with zlib.", v => compress = v != null }, { "h|help", "show this message and exit", v => showHelp = v != null } }; List <string> extra; try { extra = options.Parse(args); } catch (OptionException e) { Console.Write("{0}: ", GetExecutableName()); Console.WriteLine(e.Message); Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName()); return; } if (extra.Count < 1 || extra.Count > 2 || showHelp == true) { Console.WriteLine("Usage: {0} [OPTIONS]+ input_directory [output_sarc]", GetExecutableName()); Console.WriteLine("Pack specified directory."); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return; } var inputPath = Path.GetFullPath(extra[0]); if (Directory.Exists(inputPath)) // create the AAF file from a folder { string xmlPath; if (Directory.Exists(inputPath) == true) { xmlPath = Path.Combine(inputPath, "@files.xml"); } else { xmlPath = inputPath; inputPath = Path.GetDirectoryName(inputPath); } var outputPath = extra.Count > 1 ? extra[1] : inputPath + ".aaf"; var pendingEntries = new List <PendingEntry>(); using (var xml = File.OpenRead(xmlPath)) { var doc = new XPathDocument(xml); var nav = doc.CreateNavigator(); var root = nav.SelectSingleNode("/files"); var rawFiles = root.Select("file"); foreach (XPathNavigator rawFile in rawFiles) { if (rawFile.MoveToAttribute("name", "") == false) { throw new FormatException(); } var entryName = rawFile.Value; rawFile.MoveToParent(); if (rawFile.MoveToAttribute("size", "") == true) { uint entrySize; if (uint.TryParse(rawFile.Value, out entrySize) == false) { throw new FormatException(); } pendingEntries.Add(new PendingEntry() { Name = entryName, Size = entrySize, }); rawFile.MoveToParent(); continue; } string entryPath; if (Path.IsPathRooted(rawFile.Value) == false) { entryPath = Path.Combine(inputPath, rawFile.Value); } else { entryPath = rawFile.Value; } pendingEntries.Add(new PendingEntry() { Name = entryName, Path = entryPath, }); } } using (var aafOutput = File.Create(outputPath)) using (var output = new MemoryStream()) { var headerSize = SmallArchiveFile.EstimateHeaderSize(pendingEntries.Select(pe => pe.Name)); var smallArchive = new SmallArchiveFile(); output.Position = headerSize; foreach (var pendingEntry in pendingEntries) { if (pendingEntry.Size != null) { smallArchive.Entries.Add(new SmallArchiveFile.Entry(pendingEntry.Name, 0, pendingEntry.Size.Value)); continue; } using (var input = File.OpenRead(pendingEntry.Path)) { output.Position = output.Position.Align(4); smallArchive.Entries.Add(new SmallArchiveFile.Entry(pendingEntry.Name, (uint)output.Position, (uint)input.Length)); output.WriteFromStream(input, input.Length); } } output.Position = 0; smallArchive.Endian = endian; smallArchive.Serialize(output); // create the AAF file CoolArchiveFile cool = new CoolArchiveFile(); // infos cool.BlockSize = (uint)output.Length; cool.Endian = Endian.Little; // create a single chunk output.Position = 0; cool.ChunkInfos.Add(new CoolArchiveFile.ChunkInfo(output.ReadBytes((uint)output.Length))); // serialize cool.Serialize(aafOutput); } } else // input file IS SARC { Console.WriteLine("Will create a cool archive"); var outputPath = extra.Count == 2 ? extra[1] : Path.ChangeExtension(inputPath, "aaf"); using (var input = File.OpenRead(inputPath)) using (var outputFile = File.Create(outputPath)) { CoolArchiveFile cool = new CoolArchiveFile(); // infos cool.BlockSize = (uint)input.Length; cool.Endian = Endian.Little; // create a single chunk input.Position = 0; cool.ChunkInfos.Add(new CoolArchiveFile.ChunkInfo(input.ReadBytes((uint)input.Length))); // serialize cool.Serialize(outputFile); } } }