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));
        }
示例#2
0
        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);
                    }
            }
        }