Beispiel #1
0
        public static async Task <long> CreatePatchCached(Stream srcStream, Hash srcHash, Stream destStream, Hash destHash,
                                                          Stream?patchOutStream = null)
        {
            var key   = PatchKey(srcHash, destHash);
            var patch = _patchCache !.Get(key);

            if (patch != null)
            {
                if (patchOutStream == null)
                {
                    return(patch.Length);
                }

                await patchOutStream.WriteAsync(patch);

                return(patch.Length);
            }

            Utils.Status("Creating Patch");
            await using var sigStream   = new MemoryStream();
            await using var patchStream = new MemoryStream();
            OctoDiff.Create(srcStream, destStream, sigStream, patchStream);
            _patchCache.Put(key, patchStream.ToArray());

            if (patchOutStream == null)
            {
                return(patchStream.Position);
            }

            patchStream.Position = 0;
            await patchStream.CopyToAsync(patchOutStream);

            return(patchStream.Position);
        }
Beispiel #2
0
        public static async Task CreatePatchCached(byte[] a, byte[] b, Stream output)
        {
            await using var cmd = new SQLiteCommand(_conn);
            cmd.CommandText     = @"INSERT INTO PatchCache (FromHash, ToHash, PatchSize, Patch) 
                  VALUES (@fromHash, @toHash, @patchSize, @patch)";

            var dataA = a.xxHash();
            var dataB = b.xxHash();

            cmd.Parameters.AddWithValue("@fromHash", (long)dataA);
            cmd.Parameters.AddWithValue("@toHash", (long)dataB);

            await using var patch = new MemoryStream();

            Utils.Status("Creating Patch");
            OctoDiff.Create(a, b, patch);
            patch.Position = 0;

            cmd.Parameters.AddWithValue("@patchSize", patch.Length);
            cmd.Parameters.AddWithValue("@patch", patch.ToArray());
            try
            {
                await cmd.ExecuteNonQueryAsync();
            }
            catch (SQLiteException ex)
            {
                if (!ex.Message.StartsWith("constraint failed"))
                {
                    throw;
                }
            }
            await patch.CopyToAsync(output);
        }
Beispiel #3
0
        public static void ApplyPatch(Stream input, Func <Stream> openPatchStream, Stream output)
        {
            using var ps = openPatchStream();
            using var br = new BinaryReader(ps);
            var bytes = br.ReadBytes(8);
            var str   = Encoding.ASCII.GetString(bytes);

            switch (str)
            {
            case "BSDIFF40":
                BSDiff.Apply(input, openPatchStream, output);
                return;

            case "OCTODELT":
                OctoDiff.Apply(input, openPatchStream, output);
                return;

            default:
                throw new Exception($"No diff dispatch for: {str}");
            }
        }
Beispiel #4
0
        public static async Task CreatePatchCached(byte[] a, byte[] b, Stream output)
        {
            var dataA = a.xxHash();
            var dataB = b.xxHash();
            var key   = PatchKey(dataA, dataB);
            var found = _patchCache !.Get(key);

            if (found != null)
            {
                await output.WriteAsync(found);

                return;
            }

            await using var patch = new MemoryStream();

            Utils.Status("Creating Patch");
            OctoDiff.Create(a, b, patch);

            _patchCache.Put(key, patch.ToArray());
            patch.Position = 0;

            await patch.CopyToAsync(output);
        }
Beispiel #5
0
        public static async Task <long> CreatePatchCached(Stream srcStream, Hash srcHash, Stream destStream, Hash destHash,
                                                          Stream?patchOutStream = null)
        {
            if (patchOutStream == null)
            {
                await using var rcmd = new SQLiteCommand(_conn);
                rcmd.CommandText     = "SELECT PatchSize FROM PatchCache WHERE FromHash = @fromHash AND ToHash = @toHash";
                rcmd.Parameters.AddWithValue("@fromHash", (long)srcHash);
                rcmd.Parameters.AddWithValue("@toHash", (long)destHash);

                await using var rdr = await rcmd.ExecuteReaderAsync();

                while (await rdr.ReadAsync())
                {
                    return(rdr.GetInt64(0));
                }
            }
            else
            {
                if (TryGetPatch(srcHash, destHash, out var entry))
                {
                    await patchOutStream !.WriteAsync(await entry.GetData());
                    return(entry.PatchSize);
                }
            }

            await using var cmd = new SQLiteCommand(_conn);
            cmd.CommandText     = @"INSERT INTO PatchCache (FromHash, ToHash, PatchSize, Patch) 
                  VALUES (@fromHash, @toHash, @patchSize, @patch)";

            cmd.Parameters.AddWithValue("@fromHash", (long)srcHash);
            cmd.Parameters.AddWithValue("@toHash", (long)destHash);

            Utils.Status("Creating Patch");
            await using var sigStream   = new MemoryStream();
            await using var patchStream = new MemoryStream();
            OctoDiff.Create(srcStream, destStream, sigStream, patchStream);

            cmd.Parameters.AddWithValue("@patchSize", patchStream.Length);
            cmd.Parameters.AddWithValue("@patch", patchStream.ToArray());
            try
            {
                await cmd.ExecuteNonQueryAsync();
            }
            catch (SQLiteException ex)
            {
                if (!ex.Message.StartsWith("constraint failed"))
                {
                    throw;
                }
            }

            if (patchOutStream == null)
            {
                return(patchStream.Position);
            }

            patchStream.Position = 0;
            await patchStream.CopyToAsync(patchOutStream);

            return(patchStream.Position);
        }