Ejemplo n.º 1
0
        public static void Process(Context ctx)
        {
            using (IStorage deltaFile = new LocalStorage(ctx.Options.InFile, FileAccess.Read))
            {
                IStorage    deltaStorage = deltaFile;
                Span <byte> magic        = stackalloc byte[4];
                deltaFile.Read(0, magic).ThrowIfFailure();

                if (MemoryMarshal.Read <uint>(magic) != Ndv0Magic)
                {
                    try
                    {
                        var         nca = new Nca(ctx.Keyset, deltaStorage);
                        IFileSystem fs  = nca.OpenFileSystem(0, IntegrityCheckLevel.ErrorOnInvalid);

                        if (!fs.FileExists(FragmentFileName))
                        {
                            throw new FileNotFoundException("Specified NCA does not contain a delta fragment");
                        }

                        fs.OpenFile(out IFile deltaFragmentFile, FragmentFileName.ToU8String(), OpenMode.Read).ThrowIfFailure();

                        deltaStorage = deltaFragmentFile.AsStorage();
                    }
                    catch (InvalidDataException) { } // Ignore non-NCA3 files
                }

                var delta = new Delta(deltaStorage);

                if (ctx.Options.BaseFile != null)
                {
                    using (IStorage baseFile = new LocalStorage(ctx.Options.BaseFile, FileAccess.Read))
                    {
                        delta.SetBaseStorage(baseFile);

                        if (ctx.Options.OutFile != null)
                        {
                            using (var outFile = new FileStream(ctx.Options.OutFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                            {
                                IStorage patchedStorage = delta.GetPatchedStorage();
                                patchedStorage.GetSize(out long patchedStorageSize).ThrowIfFailure();

                                patchedStorage.CopyToStream(outFile, patchedStorageSize, ctx.Logger);
                            }
                        }
                    }
                }

                ctx.Logger.LogMessage(delta.Print());
            }
        }