readBytes method

Uint8List? readBytes(
  1. String name
)

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);
  }
}