コード例 #1
0
        public static void Main(string[] args)
        {
            bool showHelp       = false;
            bool overwriteFiles = false;
            bool verbose        = false;

            var options = new OptionSet()
            {
                {
                    "o|overwrite",
                    "overwrite existing files",
                    v => overwriteFiles = v != null
                },
                {
                    "v|verbose",
                    "be verbose",
                    v => verbose = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extras;

            try
            {
                extras = 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 (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_dir [output_rcf]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var inputPaths = new List <string>();

            inputPaths.Add(Path.GetFullPath(extras[0]));

            var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(extras[0], ".rcf");

            var paths = new SortedDictionary <string, string>();

            if (verbose == true)
            {
                Console.WriteLine("Finding files...");
            }

            foreach (var relPath in inputPaths)
            {
                string inputPath = Path.GetFullPath(relPath);

                if (inputPath.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture)) == true)
                {
                    inputPath = inputPath.Substring(0, inputPath.Length - 1);
                }

                foreach (string path in Directory.GetFiles(inputPath, "*", SearchOption.AllDirectories))
                {
                    string fullPath = Path.GetFullPath(path);
                    string partPath = fullPath.Substring(inputPath.Length + 1).ToLowerInvariant();

                    if (paths.ContainsKey(partPath) == true)
                    {
                        Console.WriteLine("Ignoring {0} duplicate.", partPath);
                        continue;
                    }

                    paths[partPath] = fullPath;
                }
            }

            using (var output = File.Create(outputPath))
            {
                var cement = new CementFile();
                cement.Endian = Endian.Little;

                cement.Entries.Clear();
                cement.Metadatas.Clear();

                foreach (var kv in paths)
                {
                    var entry = new Cement.Entry();
                    entry.NameHash = kv.Key.HashFileName(0);
                    entry.Offset   = 0;
                    entry.Size     = 0;

                    var metadata = new Cement.Metadata();
                    metadata.TypeHash  = 0;
                    metadata.Alignment = 2048;
                    metadata.Name      = kv.Key;

                    cement.Entries.Add(entry);
                    cement.Metadatas.Add(metadata);
                }

                var preestimatedHeaderSize = cement.EstimateHeaderSize();
                output.Seek(preestimatedHeaderSize, SeekOrigin.Begin);

                cement.Entries.Clear();
                cement.Metadatas.Clear();

                const uint fileAlignment = 2048;

                if (verbose == true)
                {
                    Console.WriteLine("Writing files to archive...");
                }

                foreach (var kvp in paths)
                {
                    if (verbose == true)
                    {
                        Console.WriteLine(kvp.Key);
                    }

                    using (var input = File.OpenRead(kvp.Value))
                    {
                        var entry = new Cement.Entry();
                        entry.NameHash = kvp.Key.HashFileName(0);
                        entry.Offset   = (uint)output.Position;
                        entry.Size     = (uint)input.Length;

                        /*var extension = Path.GetExtension(kvp.Key);
                         * if (extension != null &&
                         *  extension.StartsWith(".") == true)
                         * {
                         *  extension = extension.Substring(1);
                         * }*/

                        var metadata = new Cement.Metadata();
                        metadata.TypeHash  = 0;//extension == null ? 0 : extension.HashFileName(0);
                        metadata.Alignment = fileAlignment;
                        metadata.Name      = kvp.Key;

                        cement.Entries.Add(entry);
                        cement.Metadatas.Add(metadata);

                        output.WriteFromStream(input, entry.Size);
                        output.Seek(output.Position.Align(fileAlignment), SeekOrigin.Begin);
                    }
                }

                var estimatedHeaderSize = cement.EstimateHeaderSize();
                if (preestimatedHeaderSize != estimatedHeaderSize)
                {
                    throw new InvalidOperationException();
                }

                if (verbose == true)
                {
                    Console.WriteLine("Writing header...");
                }

                output.Seek(0, SeekOrigin.Begin);
                cement.Serialize(output);

                if (output.Position != estimatedHeaderSize)
                {
                    throw new InvalidOperationException();
                }
            }
        }