mirror of
https://github.com/flutter/packages.git
synced 2025-07-04 01:33:59 +08:00
[bsdiff] Remove package (#502)
bsdiff was landed several years ago to support a tool feature that was removed shortly after. It hasn't been updated in several years (incuding for NNBD), has extremely low usage, and has never had any bug reports or feature requests--notably, including requests for NNBD support. Given that it has essentially no usage, it has been discontinued, and is now being removed.
This commit is contained in:
3
third_party/packages/bsdiff/CHANGELOG.md
vendored
3
third_party/packages/bsdiff/CHANGELOG.md
vendored
@ -1,3 +0,0 @@
|
||||
## 0.1.0
|
||||
|
||||
* Initial Open Source release.
|
23
third_party/packages/bsdiff/LICENSE
vendored
23
third_party/packages/bsdiff/LICENSE
vendored
@ -1,23 +0,0 @@
|
||||
Copyright 2003-2005 Colin Percival. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
29
third_party/packages/bsdiff/README.md
vendored
29
third_party/packages/bsdiff/README.md
vendored
@ -1,29 +0,0 @@
|
||||
# BSDiff
|
||||
|
||||
[](
|
||||
https://pub.dartlang.org/packages/bsdiff)
|
||||
|
||||
Binary diff/patch algorithm based on
|
||||
[bsdiff 4.3](http://www.daemonology.net/bsdiff/) by Colin Percival.
|
||||
It's very effective at compressesing incremental changes in binaries.
|
||||
|
||||
This implementation has the following differences from Colin's code,
|
||||
to make it easier to read and apply patches in Java and Objective C:
|
||||
|
||||
* Using gzip instead of bzip2 because gzip is included in JDK by default
|
||||
* Using big- instead of little-endian serialization to simplify Java code
|
||||
* Using two's complement instead of high-bit coding for negatives numbers
|
||||
|
||||
## Usage
|
||||
To use this package, add `bsdiff` as a
|
||||
[dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/).
|
||||
|
||||
## Example
|
||||
|
||||
Import the library via
|
||||
``` dart
|
||||
import 'package:bsdiff/bsdiff.dart';
|
||||
```
|
||||
|
||||
Then use the `bsdiff` and `bspatch` Dart functions in your code. To see how this is done,
|
||||
check out the [example app](example/main.dart).
|
25
third_party/packages/bsdiff/example/main.dart
vendored
25
third_party/packages/bsdiff/example/main.dart
vendored
@ -1,25 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Example script to illustrate how to use the bsdiff package to generate and apply patches.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bsdiff/bsdiff.dart';
|
||||
|
||||
void main() {
|
||||
final Uint8List originalData =
|
||||
Uint8List.fromList(List<int>.generate(1000, (int index) => index));
|
||||
final Uint8List modifiedData =
|
||||
Uint8List.fromList(List<int>.generate(2000, (int index) => 2 * index));
|
||||
|
||||
print('Original data size ${originalData.length} bytes');
|
||||
print('Modified data size ${modifiedData.length} bytes');
|
||||
|
||||
final Uint8List generatedPatch = bsdiff(originalData, modifiedData);
|
||||
final Uint8List restoredData = bspatch(originalData, generatedPatch);
|
||||
|
||||
print('Generated patch is ${generatedPatch.length} bytes');
|
||||
print('Restored data size ${restoredData.length} bytes');
|
||||
}
|
11
third_party/packages/bsdiff/example/pubspec.yaml
vendored
11
third_party/packages/bsdiff/example/pubspec.yaml
vendored
@ -1,11 +0,0 @@
|
||||
name: main
|
||||
description: A simple example of how to use bsdiff to generate and apply patches.
|
||||
version: 0.1.0
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: ">=2.1.1-dev.2.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
bsdiff:
|
||||
path: ..
|
414
third_party/packages/bsdiff/lib/bsdiff.dart
vendored
414
third_party/packages/bsdiff/lib/bsdiff.dart
vendored
@ -1,414 +0,0 @@
|
||||
// Copyright 2003-2005 Colin Percival. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
void _split(List<int> idata, List<int> vdata, int start, int len, int h) {
|
||||
if (len < 16) {
|
||||
for (int j, k = start; k < start + len; k += j) {
|
||||
j = 1;
|
||||
int x = vdata[idata[k] + h];
|
||||
for (int i = 1; k + i < start + len; i++) {
|
||||
if (vdata[idata[k + i] + h] < x) {
|
||||
x = vdata[idata[k + i] + h];
|
||||
j = 0;
|
||||
}
|
||||
if (vdata[idata[k + i] + h] == x) {
|
||||
final int tmp = idata[k + j];
|
||||
idata[k + j] = idata[k + i];
|
||||
idata[k + i] = tmp;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < j; i++) {
|
||||
vdata[idata[k + i]] = k + j - 1;
|
||||
}
|
||||
if (j == 1) {
|
||||
idata[k] = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final int x = vdata[idata[start + len ~/ 2] + h];
|
||||
int jj = 0;
|
||||
int kk = 0;
|
||||
for (int i = start; i < start + len; i++) {
|
||||
if (vdata[idata[i] + h] < x) {
|
||||
jj++;
|
||||
}
|
||||
if (vdata[idata[i] + h] == x) {
|
||||
kk++;
|
||||
}
|
||||
}
|
||||
jj += start;
|
||||
kk += jj;
|
||||
|
||||
int i = start;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
while (i < jj) {
|
||||
if (vdata[idata[i] + h] < x) {
|
||||
i++;
|
||||
} else if (vdata[idata[i] + h] == x) {
|
||||
final int tmp = idata[i];
|
||||
idata[i] = idata[jj + j];
|
||||
idata[jj + j] = tmp;
|
||||
j++;
|
||||
} else {
|
||||
final int tmp = idata[i];
|
||||
idata[i] = idata[kk + k];
|
||||
idata[kk + k] = tmp;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
while (jj + j < kk) {
|
||||
if (vdata[idata[jj + j] + h] == x) {
|
||||
j++;
|
||||
} else {
|
||||
final int tmp = idata[jj + j];
|
||||
idata[jj + j] = idata[kk + k];
|
||||
idata[kk + k] = tmp;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
if (jj > start) {
|
||||
_split(idata, vdata, start, jj - start, h);
|
||||
}
|
||||
|
||||
for (i = 0; i < kk - jj; i++) {
|
||||
vdata[idata[jj + i]] = kk - 1;
|
||||
}
|
||||
if (jj == kk - 1) {
|
||||
idata[jj] = -1;
|
||||
}
|
||||
|
||||
if (start + len > kk) {
|
||||
_split(idata, vdata, kk, start + len - kk, h);
|
||||
}
|
||||
}
|
||||
|
||||
void _qsufsort(List<int> idata, List<int> vdata, Uint8List olddata) {
|
||||
final int oldsize = olddata.length;
|
||||
final List<int> buckets = List<int>.filled(256, 0);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
buckets[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < oldsize; i++) {
|
||||
buckets[olddata[i]]++;
|
||||
}
|
||||
for (int i = 1; i < 256; i++) {
|
||||
buckets[i] += buckets[i - 1];
|
||||
}
|
||||
|
||||
for (int i = 255; i > 0; i--) {
|
||||
buckets[i] = buckets[i - 1];
|
||||
}
|
||||
buckets[0] = 0;
|
||||
|
||||
for (int i = 0; i < oldsize; i++) {
|
||||
idata[++buckets[olddata[i]]] = i;
|
||||
}
|
||||
idata[0] = oldsize;
|
||||
|
||||
for (int i = 0; i < oldsize; i++) {
|
||||
vdata[i] = buckets[olddata[i]];
|
||||
}
|
||||
vdata[oldsize] = 0;
|
||||
|
||||
for (int i = 1; i < 256; i++) {
|
||||
if (buckets[i] == buckets[i - 1] + 1) {
|
||||
idata[buckets[i]] = -1;
|
||||
}
|
||||
}
|
||||
idata[0] = -1;
|
||||
|
||||
for (int h = 1; idata[0] != -(oldsize + 1); h += h) {
|
||||
int len = 0;
|
||||
int i;
|
||||
for (i = 0; i < oldsize + 1;) {
|
||||
if (idata[i] < 0) {
|
||||
len -= idata[i];
|
||||
i -= idata[i];
|
||||
} else {
|
||||
if (len != 0) {
|
||||
idata[i - len] = -len;
|
||||
}
|
||||
len = vdata[idata[i]] + 1 - i;
|
||||
_split(idata, vdata, i, len, h);
|
||||
i += len;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
if (len != 0) {
|
||||
idata[i - len] = -len;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < oldsize + 1; i++) {
|
||||
idata[vdata[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
int _matchlen(Uint8List olddata, int oldskip, Uint8List newdata, int newskip) {
|
||||
final int n = min(olddata.length - oldskip, newdata.length - newskip);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (olddata[oldskip + i] != newdata[newskip + i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int _memcmp(Uint8List data1, int skip1, Uint8List data2, int skip2) {
|
||||
final int n = min(data1.length - skip1, data2.length - skip2);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (data1[i + skip1] != data2[i + skip2]) {
|
||||
return data1[i + skip1] < data2[i + skip2] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class _Ref<T> {
|
||||
T value;
|
||||
}
|
||||
|
||||
int _search(List<int> idata, Uint8List olddata, Uint8List newdata, int newskip,
|
||||
int start, int end, _Ref<int> pos) {
|
||||
if (end - start < 2) {
|
||||
final int x = _matchlen(olddata, idata[start], newdata, newskip);
|
||||
final int y = _matchlen(olddata, idata[end], newdata, newskip);
|
||||
|
||||
if (x > y) {
|
||||
pos.value = idata[start];
|
||||
return x;
|
||||
} else {
|
||||
pos.value = idata[end];
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
final int x = start + (end - start) ~/ 2;
|
||||
if (_memcmp(olddata, idata[x], newdata, newskip) < 0) {
|
||||
return _search(idata, olddata, newdata, newskip, x, end, pos);
|
||||
} else {
|
||||
return _search(idata, olddata, newdata, newskip, start, x, pos);
|
||||
}
|
||||
}
|
||||
|
||||
List<int> _int64bytes(int i) =>
|
||||
(ByteData(8)..setInt64(0, i)).buffer.asUint8List();
|
||||
|
||||
/// Computes the binary diff between [olddata] and [newdata].
|
||||
Uint8List bsdiff(List<int> olddata, List<int> newdata) {
|
||||
final int oldsize = olddata.length;
|
||||
final int newsize = newdata.length;
|
||||
|
||||
final List<int> idata = List<int>.filled(oldsize + 1, 0);
|
||||
_qsufsort(idata, List<int>.filled(oldsize + 1, 0), olddata);
|
||||
|
||||
final Uint8List db = Uint8List(newsize + 1);
|
||||
final Uint8List eb = Uint8List(newsize + 1);
|
||||
|
||||
int dblen = 0;
|
||||
int eblen = 0;
|
||||
|
||||
BytesBuilder buf = BytesBuilder();
|
||||
final _Ref<int> pos = _Ref<int>();
|
||||
|
||||
for (int scan = 0, len = 0, lastscan = 0, lastpos = 0, lastoffset = 0;
|
||||
scan < newsize;) {
|
||||
int oldscore = 0;
|
||||
|
||||
for (int scsc = scan += len; scan < newsize; scan++) {
|
||||
len = _search(idata, olddata, newdata, scan, 0, oldsize, pos);
|
||||
|
||||
for (; scsc < scan + len; scsc++) {
|
||||
if ((scsc + lastoffset < oldsize) &&
|
||||
(olddata[scsc + lastoffset] == newdata[scsc])) {
|
||||
oldscore++;
|
||||
}
|
||||
}
|
||||
if (((len == oldscore) && (len != 0)) || (len > oldscore + 8)) {
|
||||
break;
|
||||
}
|
||||
if ((scan + lastoffset < oldsize) &&
|
||||
(olddata[scan + lastoffset] == newdata[scan])) {
|
||||
oldscore--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((len != oldscore) || (scan == newsize)) {
|
||||
int lenf = 0;
|
||||
int lenb = 0;
|
||||
|
||||
for (int sf = 0, s = 0, i = 0;
|
||||
(lastscan + i < scan) && (lastpos + i < oldsize);) {
|
||||
if (olddata[lastpos + i] == newdata[lastscan + i]) {
|
||||
s++;
|
||||
}
|
||||
i++;
|
||||
if (s * 2 - i > sf * 2 - lenf) {
|
||||
sf = s;
|
||||
lenf = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (scan < newsize) {
|
||||
for (int sb = 0, s = 0, i = 1;
|
||||
(scan >= lastscan + i) && (pos.value >= i);
|
||||
i++) {
|
||||
if (olddata[pos.value - i] == newdata[scan - i]) {
|
||||
s++;
|
||||
}
|
||||
if (s * 2 - i > sb * 2 - lenb) {
|
||||
sb = s;
|
||||
lenb = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastscan + lenf > scan - lenb) {
|
||||
final int overlap = (lastscan + lenf) - (scan - lenb);
|
||||
int lens = 0;
|
||||
for (int ss = 0, s = 0, i = 0; i < overlap; i++) {
|
||||
if (newdata[lastscan + lenf - overlap + i] ==
|
||||
olddata[lastpos + lenf - overlap + i]) {
|
||||
s++;
|
||||
}
|
||||
if (newdata[scan - lenb + i] == olddata[pos.value - lenb + i]) {
|
||||
s--;
|
||||
}
|
||||
if (s > ss) {
|
||||
ss = s;
|
||||
lens = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
lenf += lens - overlap;
|
||||
lenb -= lens;
|
||||
}
|
||||
|
||||
for (int i = 0; i < lenf; i++) {
|
||||
db[dblen + i] = newdata[lastscan + i] - olddata[lastpos + i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < (scan - lenb) - (lastscan + lenf); i++) {
|
||||
eb[eblen + i] = newdata[lastscan + lenf + i];
|
||||
}
|
||||
|
||||
dblen += lenf;
|
||||
eblen += (scan - lenb) - (lastscan + lenf);
|
||||
|
||||
buf.add(_int64bytes(lenf));
|
||||
buf.add(_int64bytes((scan - lenb) - (lastscan + lenf)));
|
||||
buf.add(_int64bytes((pos.value - lenb) - (lastpos + lenf)));
|
||||
|
||||
lastscan = scan - lenb;
|
||||
lastpos = pos.value - lenb;
|
||||
lastoffset = pos.value - scan;
|
||||
}
|
||||
}
|
||||
|
||||
final BytesBuilder out = BytesBuilder();
|
||||
|
||||
out.add(const AsciiCodec().encode('BZDIFF40').toList());
|
||||
out.add(_int64bytes(0));
|
||||
out.add(_int64bytes(0));
|
||||
out.add(_int64bytes(newsize));
|
||||
|
||||
out.add(gzip.encoder.convert(buf.takeBytes()));
|
||||
|
||||
final int len1 = out.length;
|
||||
|
||||
buf = BytesBuilder();
|
||||
buf.add(db.sublist(0, dblen));
|
||||
out.add(gzip.encoder.convert(buf.takeBytes()));
|
||||
|
||||
final int len2 = out.length;
|
||||
|
||||
buf = BytesBuilder();
|
||||
buf.add(eb.sublist(0, eblen));
|
||||
out.add(gzip.encoder.convert(buf.takeBytes()));
|
||||
|
||||
final Uint8List bytes = Uint8List.fromList(out.takeBytes());
|
||||
final ByteData data = ByteData.view(bytes.buffer);
|
||||
data.setUint64(8, len1 - 32);
|
||||
data.setUint64(16, len2 - len1);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// Returns the result of applying [diffdata] to [olddata].
|
||||
Uint8List bspatch(List<int> olddata, List<int> diffdata) {
|
||||
final List<int> magic = diffdata.sublist(0, 8);
|
||||
if (const AsciiCodec().decode(magic) != 'BZDIFF40') {
|
||||
throw Exception('Invalid magic');
|
||||
}
|
||||
|
||||
final ByteData header =
|
||||
ByteData.view(Uint8List.fromList(diffdata.sublist(0, 32)).buffer);
|
||||
|
||||
final int ctrllen = header.getInt64(8);
|
||||
final int datalen = header.getInt64(16);
|
||||
final int newsize = header.getInt64(24);
|
||||
|
||||
final List<int> cpf =
|
||||
gzip.decoder.convert(diffdata.sublist(32, 32 + ctrllen));
|
||||
final List<int> dpf = gzip.decoder
|
||||
.convert(diffdata.sublist(32 + ctrllen, 32 + ctrllen + datalen));
|
||||
final List<int> epf = gzip.decoder
|
||||
.convert(diffdata.sublist(32 + ctrllen + datalen, diffdata.length));
|
||||
|
||||
final ByteData cpfdata = ByteData.view(Uint8List.fromList(cpf).buffer);
|
||||
|
||||
final Uint8List newdata = Uint8List(newsize);
|
||||
|
||||
int cpfpos = 0;
|
||||
int dpfpos = 0;
|
||||
int epfpos = 0;
|
||||
int oldpos = 0;
|
||||
int newpos = 0;
|
||||
|
||||
while (newpos < newsize) {
|
||||
final List<int> ctrl = List<int>.filled(3, 0);
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
ctrl[i] = cpfdata.getInt64(8 * cpfpos++);
|
||||
}
|
||||
if (newpos + ctrl[0] > newsize) {
|
||||
throw Exception('Invalid ctrl[0]');
|
||||
}
|
||||
|
||||
newdata.setRange(newpos, newpos + ctrl[0], dpf, dpfpos);
|
||||
|
||||
for (int i = 0; i < ctrl[0]; i++) {
|
||||
if ((oldpos + i >= 0) && (oldpos + i < olddata.length)) {
|
||||
newdata[newpos + i] += olddata[oldpos + i];
|
||||
}
|
||||
}
|
||||
|
||||
dpfpos += ctrl[0];
|
||||
newpos += ctrl[0];
|
||||
oldpos += ctrl[0];
|
||||
|
||||
if (newpos + ctrl[1] > newsize) {
|
||||
throw Exception('Invalid ctrl[0]');
|
||||
}
|
||||
|
||||
newdata.setRange(newpos, newpos + ctrl[1], epf, epfpos);
|
||||
|
||||
epfpos += ctrl[1];
|
||||
newpos += ctrl[1];
|
||||
oldpos += ctrl[2];
|
||||
}
|
||||
|
||||
return newdata;
|
||||
}
|
11
third_party/packages/bsdiff/pubspec.yaml
vendored
11
third_party/packages/bsdiff/pubspec.yaml
vendored
@ -1,11 +0,0 @@
|
||||
name: bsdiff
|
||||
description: Binary diff/patch algorithm based on bsdiff by Colin Percival.
|
||||
repository: https://github.com/flutter/packages/tree/master/third_party/packages/bsdiff
|
||||
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+bsdiff%22
|
||||
version: 0.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.1.2 <3.0.0"
|
||||
|
||||
dev_dependencies:
|
||||
test: "^1.3.4"
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:bsdiff/bsdiff.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('roundtrip', () {
|
||||
final Uint8List a = Uint8List.fromList('Hello'.runes.toList());
|
||||
final Uint8List b = Uint8List.fromList('Hello World'.runes.toList());
|
||||
final Uint8List c = bsdiff(a, b);
|
||||
expect(bspatch(a, c), equals(b));
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user