Use InputStreamBase for ZipDecoder.decodeBuffer
diff --git a/lib/src/io/input_file_stream.dart b/lib/src/io/input_file_stream.dart
index 276d5d2..e6a314e 100644
--- a/lib/src/io/input_file_stream.dart
+++ b/lib/src/io/input_file_stream.dart
@@ -36,6 +36,22 @@
_readBuffer();
}
+ InputFileStream.clone(InputFileStream other, {int? position, int? length})
+ : path = other.path,
+ _file = other._file,
+ byteOrder = other.byteOrder,
+ _fileSize = other._fileSize,
+ _filePosition = other._filePosition,
+ _bufferSize = other._bufferSize,
+ _buffer = Uint8List(other._bufferSize) {
+ if (position != null) {
+ this.position = position;
+ }
+ if (length != null) {
+ _fileSize = this.position + length;
+ }
+ }
+
void close() {
_file.closeSync();
_fileSize = 0;
@@ -48,6 +64,15 @@
int get position => _filePosition;
@override
+ set position(int v) {
+ if (v < _filePosition) {
+ rewind(_filePosition - v);
+ } else if (v > _filePosition) {
+ skip(v - _filePosition);
+ }
+ }
+
+ @override
bool get isEOS =>
(_filePosition >= _fileSize) && (_bufferPosition >= _bufferSize);
@@ -83,6 +108,11 @@
}
}
+ @override
+ InputStreamBase subset([int? position, int? length]) {
+ return InputFileStream.clone(this, position:position, length:length);
+ }
+
/// Read [count] bytes from an [offset] of the current read position, without
/// moving the read position.
@override
diff --git a/lib/src/util/input_stream.dart b/lib/src/util/input_stream.dart
index 051b64f..702718e 100644
--- a/lib/src/util/input_stream.dart
+++ b/lib/src/util/input_stream.dart
@@ -7,6 +7,8 @@
/// The current read position relative to the start of the buffer.
int get position;
+ set position(int v);
+
/// How many bytes are left in the stream.
int get length;
@@ -32,6 +34,8 @@
/// Read [count] bytes from the stream.
InputStream readBytes(int count);
+ InputStreamBase subset([int? position, int? length]);
+
/// Read a null-terminated string, or if [len] is provided, that number of
/// bytes returned as a string.
String readString({int? size, bool utf8 = true});
@@ -84,6 +88,9 @@
@override
int get position => offset - start;
+ @override
+ set position(int v) { offset = start + v; }
+
/// How many bytes are left in the stream.
@override
int get length => _length - (offset - start);
@@ -115,7 +122,8 @@
/// to the start of the buffer. If [position] is not specified, the current
/// read position is used. If [length] is not specified, the remainder of this
/// stream is used.
- InputStream subset([int? position, int? length]) {
+ @override
+ InputStreamBase subset([int? position, int? length]) {
if (position == null) {
position = offset;
} else {
@@ -149,7 +157,7 @@
/// moving the read position.
@override
InputStream peekBytes(int count, [int offset = 0]) {
- return subset((this.offset - start) + offset, count);
+ return subset((this.offset - start) + offset, count) as InputStream;
}
/// Move the read position by [count] bytes.
@@ -169,7 +177,7 @@
InputStream readBytes(int count) {
final bytes = subset(offset - start, count);
offset += bytes.length;
- return bytes;
+ return bytes as InputStream;
}
/// Read a null-terminated string, or if [len] is provided, that number of
diff --git a/lib/src/zip/zip_directory.dart b/lib/src/zip/zip_directory.dart
index 6382914..b60f7f7 100644
--- a/lib/src/zip/zip_directory.dart
+++ b/lib/src/zip/zip_directory.dart
@@ -24,9 +24,9 @@
ZipDirectory();
- ZipDirectory.read(InputStream input, {String? password}) {
+ ZipDirectory.read(InputStreamBase input, {String? password}) {
filePosition = _findSignature(input);
- input.offset = filePosition;
+ input.position = filePosition;
final signature = input.readUint32(); // ignore: unused_local_variable
numberOfThisDisk = input.readUint16();
diskWithTheStartOfTheCentralDirectory = input.readUint16();
@@ -54,8 +54,8 @@
}
}
- void _readZip64Data(InputStream input) {
- final ip = input.offset;
+ void _readZip64Data(InputStreamBase input) {
+ final ip = input.position;
// Check for zip64 data.
// Zip64 end of central directory locator
@@ -76,7 +76,7 @@
var sig = zip64.readUint32();
// If this ins't the signature we're looking for, nothing more to do.
if (sig != ZIP64_EOCD_LOCATOR_SIGNATURE) {
- input.offset = ip;
+ input.position = ip;
return;
}
@@ -84,7 +84,7 @@
final zip64DirOffset = zip64.readUint64();
final numZip64Disks = zip64.readUint32(); // ignore: unused_local_variable
- input.offset = zip64DirOffset;
+ input.position = zip64DirOffset;
// Zip64 end of central directory record
// signature 4 bytes (0x06064b50)
@@ -106,7 +106,7 @@
// zip64 extensible data sector (variable size)
sig = input.readUint32();
if (sig != ZIP64_EOCD_SIGNATURE) {
- input.offset = ip;
+ input.position = ip;
return;
}
@@ -128,25 +128,24 @@
centralDirectorySize = dirSize;
centralDirectoryOffset = dirOffset;
- input.offset = ip;
+ input.position = ip;
}
- int _findSignature(InputStream input) {
- final pos = input.offset;
+ int _findSignature(InputStreamBase input) {
+ final pos = input.position;
final length = input.length;
// The directory and archive contents are written to the end of the zip
- // file. We need to search from the end to find these structures,
+ // file. We need to search from the end to find these structures,
// starting with the 'End of central directory' record (EOCD).
for (var ip = length - 4; ip >= 0; --ip) {
- input.offset = ip;
+ input.position = ip;
final sig = input.readUint32();
if (sig == SIGNATURE) {
- input.offset = pos;
+ input.position = pos;
return ip;
}
}
-
throw ArchiveException('Could not find End of Central Directory Record');
}
}
diff --git a/lib/src/zip/zip_file.dart b/lib/src/zip/zip_file.dart
index 7d5a2e5..2bf07e0 100644
--- a/lib/src/zip/zip_file.dart
+++ b/lib/src/zip/zip_file.dart
@@ -24,7 +24,7 @@
List<int> extraField = []; // 2 bytes length, n-bytes data
ZipFileHeader? header;
- ZipFile([InputStream? input, this.header, String? password]) {
+ ZipFile([InputStreamBase? input, this.header, String? password]) {
if (input != null) {
signature = input.readUint32();
if (signature != SIGNATURE) {
diff --git a/lib/src/zip/zip_file_header.dart b/lib/src/zip/zip_file_header.dart
index 94bfaf5..5a61042 100644
--- a/lib/src/zip/zip_file_header.dart
+++ b/lib/src/zip/zip_file_header.dart
@@ -21,7 +21,8 @@
String fileComment = '';
ZipFile? file;
- ZipFileHeader([InputStream? input, InputStream? bytes, String? password]) {
+ ZipFileHeader([InputStreamBase? input, InputStreamBase? bytes,
+ String? password]) {
if (input != null) {
versionMadeBy = input.readUint16();
versionNeededToExtract = input.readUint16();
@@ -81,7 +82,7 @@
}
if (bytes != null) {
- bytes.offset = localHeaderOffset!;
+ bytes.position = localHeaderOffset!;
file = ZipFile(bytes, this, password);
}
}
diff --git a/lib/src/zip_decoder.dart b/lib/src/zip_decoder.dart
index 84f200e..fa27dc0 100644
--- a/lib/src/zip_decoder.dart
+++ b/lib/src/zip_decoder.dart
@@ -14,7 +14,7 @@
return decodeBuffer(InputStream(data), verify: verify, password: password);
}
- Archive decodeBuffer(InputStream input,
+ Archive decodeBuffer(InputStreamBase input,
{bool verify = false, String? password}) {
directory = ZipDirectory.read(input, password: password);
final archive = Archive();