Пример #1
0
        public void BsDiffCreateFromStreams()
        {
            const int outputSize = 0x2A000;

            foreach (var oldBuffer in GetBuffers(Sizes))
            {
                foreach (var newBuffer in GetBuffers(Sizes))
                {
                    byte[] bytesOut;
                    using (var mmf = MemoryMappedFile.CreateNew(null, outputSize, MemoryMappedFileAccess.ReadWrite))
                    {
                        using (var mmfStream = mmf.CreateViewStream())
                        {
                            BsDiff.Create(oldBuffer, newBuffer, mmfStream);
                        }

                        using (var msA = new MemoryStream(oldBuffer))
                            using (var msOutput = new MemoryStream())
                            {
                                BsPatch.Apply(msA, mmf.CreateViewStream, msOutput);
                                bytesOut = msOutput.ToArray();
                            }
                    }

                    Assert.Equal(newBuffer, bytesOut);
                }
            }
        }
Пример #2
0
        public DeltaqBsDiff()
        {
            using (var outputStream = new MemoryStream())
            {
                BsDiff.Create(Samples.origin1, Samples.target1, outputStream);
                sample1Delta = outputStream.ToArray();
            }

            using (var outputStream = new MemoryStream())
            {
                BsDiff.Create(Samples.origin2, Samples.target2, outputStream);
                sample2Delta = outputStream.ToArray();
            }

            using (var outputStream = new MemoryStream())
            {
                BsDiff.Create(Samples.origin3, Samples.target3, outputStream);
                sample3Delta = outputStream.ToArray();
            }

            using (var outputStream = new MemoryStream())
            {
                BsDiff.Create(Samples.origin4, Samples.target4, outputStream);
                sample4Delta = outputStream.ToArray();
            }

            using (var outputStream = new MemoryStream())
            {
                BsDiff.Create(Samples.origin5, Samples.target5, outputStream);
                sample5Delta = outputStream.ToArray();
            }
        }
Пример #3
0
 public byte[] CreateDelta5()
 {
     using (var outputStream = new MemoryStream())
     {
         BsDiff.Create(Samples.origin5, Samples.target5, outputStream);
         return(outputStream.ToArray());
     }
 }
Пример #4
0
 private static byte[] BsDiffCreate(byte[] oldBuf, byte[] newBuf)
 {
     using (var outputStream = new MemoryStream())
     {
         BsDiff.Create(oldBuf, newBuf, outputStream);
         return(outputStream.ToArray());
     }
 }
Пример #5
0
        public void WritePatchFile(Stream stream)
        {
            using (var io = IoWriter.FromStream(stream, ByteOrder.LITTLE_ENDIAN))
            {
                io.WriteCString("TSOp", 4);
                io.WriteInt32(0); //version

                //generate patches for the files that are the same
                var patches = new List <Tuple <string, byte[]> >();
                Console.Write("Progress: ");
                var progress = 0;
                foreach (var file in SameFiles)
                {
                    Console.Write($"\rProgress: {progress++}/{SameFiles.Count}");

                    var srcDat = File.ReadAllBytes(Path.Combine(SourcePath, file));
                    var dstDat = File.ReadAllBytes(Path.Combine(DestPath, file));

                    var same = srcDat.Length == dstDat.Length && srcDat.SequenceEqual(dstDat);
                    if (!same)
                    {
                        using (var outips = new MemoryStream()) {
                            BsDiff.Create(srcDat, dstDat, outips);
                            patches.Add(new Tuple <string, byte[]>(file, outips.ToArray()));
                        }
                    }
                }
                Console.WriteLine();
                Console.WriteLine($"Done generating patches ({patches.Count}). Inserting additions and deletions...");

                io.WriteCString("IPS_", 4);
                io.WriteInt32(patches.Count);
                foreach (var piff in patches)
                {
                    io.WriteVariableLengthPascalString(piff.Item1);
                    io.WriteInt32(piff.Item2.Length);
                    io.WriteBytes(piff.Item2);
                }

                io.WriteCString("ADD_", 4);
                io.WriteInt32(AddFiles.Count);
                foreach (var add in AddFiles)
                {
                    io.WriteVariableLengthPascalString(add);
                    var data = File.ReadAllBytes(Path.Combine(DestPath, add));
                    io.WriteInt32(data.Length);
                    io.WriteBytes(data);
                }

                io.WriteCString("DEL_", 4);
                io.WriteInt32(RemovedFiles.Count);
                foreach (var del in RemovedFiles)
                {
                    io.WriteVariableLengthPascalString(del);
                }
            }
        }
Пример #6
0
 private static void CreatePatch(string src, string dst, string patch)
 {
     if (File.Exists(patch))
     {
         File.Delete(patch);
     }
     using (var fh = File.Create(patch)) {
         BsDiff.Create(File.ReadAllBytes(src), File.ReadAllBytes(dst), fh);
     }
 }
Пример #7
0
 private void CheckOriginalList(PatchContainer patchResult)
 {
     foreach (var key in originalList.Keys)
     {
         if (key.TrimStart('\\') == "AUTOEXEC.BAT" || key.TrimStart('\\') == "CONFIG.SYS")
         {
             continue;
         }
         if (key.ToLower().EndsWith(@"\\CONFIG.SYS"))
         {
             continue;
         }
         var file = new PatchedFile {
             Name           = key,
             Action         = PatchAction.Original,
             OriginalMd5Sum = originalList[key]
         };
         if (!translatedList.ContainsKey(key))
         {
             if (form.Ask($"Translated HDI doesn't contain file {key}",
                          $"Delete {key} from source during patching?"))
             {
                 file.Action = PatchAction.Delete;
             }
         }
         else if (originalList[key] != translatedList[key])
         {
             file.Action = PatchAction.Patch;
             using (var ms = new MemoryStream()) {
                 using (var src = originalFs.OpenFile(key, FileMode.Open)) {
                     using (var patched = translatedFs.OpenFile(key, FileMode.Open)) {
                         BsDiff.Create(src, patched, ms);
                         patchResult.TotalSize += patched.Length;
                     }
                 }
                 file.Patch = ms.ToArray();
             }
         }
         else
         {
             var info = originalFs.GetFileInfo(key);
             patchResult.TotalSize += info.Length;
         }
         patchResult.Add(file);
     }
 }
Пример #8
0
        private static void CreateAssetPatch(Settings settings, IBSA original, Fo3File originalRecord, Fo3File resultRecord, RecordAction recordAction)
        {
            string patchName;
            string patchFile;

            // @todo: memory stream and name with md5
            using (var patchStream = new MemoryStream())
            {
                // @todo: lock
                byte[] originalRecordBytes;
                if (original != null)
                {
                    lock (original)
                    {
                        originalRecordBytes = originalRecord.GetData(original.Reader);
                    }
                }
                else
                {
                    originalRecordBytes = originalRecord.GetData();
                }
                var referenceBytes = resultRecord.GetData();
                BsDiff.Create(originalRecordBytes, referenceBytes, patchStream);

                patchStream.Seek(0, SeekOrigin.Begin);
                patchName = new Guid(MD5.Create().ComputeHash(patchStream)).ToString();
                recordAction.PatchName = patchName;
                patchFile = string.Format("{0}\\{1}.patch", settings.GetTempFolder("Patches"), patchName);

                try
                {
                    using (var fileStream = new FileStream(patchFile, FileMode.CreateNew))
                    {
                        patchStream.Seek(0, SeekOrigin.Begin);
                        patchStream.CopyTo(fileStream);
                    }
                }
                catch (IOException exc)
                {
                    // ignored
                }
            }
        }
Пример #9
0
        private static void ProcessESMs(Recipe recipe, Settings settings)
        {
            Console.WriteLine("Processing ESMs ...");
            foreach (var filepair in settings.Files.Where(fp => fp.Type == ContentType.ESP))
            {
                Console.Write("{0} => {1} ... ", filepair.OriginalName, filepair.ResultName);

                string patchName;
                string patchFile;

                // @todo: memory stream and name with md5
                using (var patchStream = new MemoryStream())
                {
                    var originalBytes = File.ReadAllBytes(string.Format("{0}\\{1}", settings.Fo3DataPath, filepair.OriginalName));
                    var resultBytes   = File.ReadAllBytes(string.Format("{0}\\{1}", settings.CurrentDataPath, filepair.ResultName));

                    BsDiff.Create(originalBytes, resultBytes, patchStream);

                    patchStream.Seek(0, SeekOrigin.Begin);
                    patchName = new Guid(MD5.Create().ComputeHash(patchStream)).ToString();
                    patchFile = string.Format("{0}\\{1}.patch", settings.GetTempFolder("Patches"), patchName);

                    if (!File.Exists(patchFile))
                    {
                        using (var fileStream = new FileStream(patchFile, FileMode.CreateNew))
                        {
                            patchStream.Seek(0, SeekOrigin.Begin);
                            patchStream.CopyTo(fileStream);
                        }
                    }
                }

                filepair.PatchName = patchName;
                recipe.Files.Add(filepair);

                Console.WriteLine("Done");
                FlushRecipe(settings, recipe);
            }
            Console.WriteLine("ESMs completed");
        }
Пример #10
0
        public void BsPatchFlushesOutput()
        {
            var oldBuffer = GetRandomFilledBuffer(0x123);
            var newBuffer = GetRandomFilledBuffer(0x4567);

            //can't use MemoryStream directly as Flush has no effect
            var patchMs        = new MemoryStream();
            var wrappedPatchMs = new BufferedStream(patchMs);

            BsDiff.Create(oldBuffer, newBuffer, wrappedPatchMs);

            var patchBuffer = patchMs.ToArray();

            var reconstructMs        = new MemoryStream();
            var wrappedReconstructMs = new BufferedStream(reconstructMs);

            BsPatch.Apply(oldBuffer, patchBuffer, wrappedReconstructMs);

            var reconstructedBuffer = reconstructMs.ToArray();

            Assert.Equal(newBuffer, reconstructedBuffer);
        }
Пример #11
0
 public void BsDiffCreateBadStreams(byte[] oldData, byte[] newData, Stream outStream)
 {
     Assert.Throws <ArgumentException>(() => BsDiff.Create(oldData, newData, outStream));
 }
Пример #12
0
        private static List <RepoFile> AddFiles(string repoPath, SemVersion version, string path, string previousVersionNumber = null, RepoVersion previousVersion = null)
        {
            string previousVersionPath = null;

            if (previousVersionNumber != null)
            {
                previousVersionPath = Path.Combine(repoPath, previousVersionNumber);
            }

            Console.WriteLine("Adding files from " + path + ((previousVersionPath != null) ? " | Comparing them to: " + previousVersionPath : ""));
            List <RepoFile> files = new List <RepoFile>();

            var fileList = new List <string>();

            FileUtil.GetFiles(path, ref fileList);

            foreach (var file in fileList)
            {
                var repoFile = new RepoFile
                {
                    Path     = FileUtil.GetRelativePath(path, file).Replace("\\", "/"),
                    Checksum = Checksum.GetSHA1Sum(file)
                };

                string exportPath = Path.Combine(repoPath, version.ToString(), repoFile.Path);

                if (previousVersion != null)
                {
                    var oldRepoFile = previousVersion.GetFile(repoFile.Path);

                    if (oldRepoFile?.Checksum == repoFile.Checksum)
                    {
                        // Flag the file as unchanged to consolidate repo space
                        repoFile.UnchangedSince = oldRepoFile.UnchangedSince ?? previousVersionNumber;
                    }
                    else
                    {
                        Console.WriteLine("\tAdding file " + repoFile.Path);

                        // Copy the entire file if a previous version doesn't exist.
                        Directory.CreateDirectory(Path.GetDirectoryName(exportPath));
                        File.Copy(file, exportPath);

                        // Generate patches
                        string prevPath;
                        if (oldRepoFile?.UnchangedSince != null)
                        {
                            Console.WriteLine("\t\tUnchanged since " + oldRepoFile.UnchangedSince);
                            prevPath = Path.Combine(Path.Combine(repoPath, oldRepoFile.UnchangedSince), repoFile.Path);
                        }
                        else
                        {
                            prevPath = Path.Combine(previousVersionPath, repoFile.Path);
                        }

                        if (File.Exists(prevPath))
                        {
                            var origChecksum = Checksum.GetSHA1Sum(prevPath);
                            // Don't generate a patch for an unchanged file
                            if (origChecksum != repoFile.Checksum)
                            {
                                Console.WriteLine("\t\tGenerating patch...");

                                repoFile.PatchSourceChecksum = origChecksum;
                                // Create the BsDiff patch
                                using (FileStream patchFileStream =
                                           new FileStream(exportPath + ".patch", FileMode.Create))
                                    BsDiff.Create(File.ReadAllBytes(exportPath), File.ReadAllBytes(prevPath),
                                                  patchFileStream);
                                // Get checksum of the patch
                                repoFile.PatchChecksum = Checksum.GetSHA1Sum(exportPath + ".patch");
                            }
                        }
                    }
                }
                else
                {
                    Console.WriteLine("\tAdding file " + repoFile.Path);
                    // Copy the entire file if a previous version doesn't exist.
                    Directory.CreateDirectory(Path.GetDirectoryName(exportPath));
                    File.Copy(file, exportPath);
                }


                files.Add(repoFile);
            }

            return(files);
        }