readBytes method
The entry name's bytes, or null when there is no such entry.
Implementation
Uint8List? readBytes(String name) {
final entry = _entries[name];
if (entry == null) return null;
final data = ByteData.sublistView(_bytes);
final local = entry.localHeaderOffset;
if (local + 30 > _bytes.length ||
data.getUint32(local, Endian.little) != _localHeaderSignature) {
throw FormatException('bad local header for $name', path);
}
// The local header's own name and extra lengths, which may differ from
// the central directory's.
final nameLength = data.getUint16(local + 26, Endian.little);
final extraLength = data.getUint16(local + 28, Endian.little);
final start = local + 30 + nameLength + extraLength;
if (start + entry.compressedSize > _bytes.length) {
// A truncated download, typically.
throw FormatException('$name runs past the end of the file', path);
}
final compressed = Uint8List.sublistView(
_bytes,
start,
start + entry.compressedSize,
);
try {
return switch (entry.method) {
0 => Uint8List.fromList(compressed),
8 => Uint8List.fromList(ZLibDecoder(raw: true).convert(compressed)),
_ => throw FormatException(
'unsupported compression method ${entry.method} for $name',
path,
),
};
} on FileSystemException catch (e) {
// What ZLibDecoder throws for data that does not inflate.
throw FormatException('$name does not inflate: ${e.message}', path);
}
}