extractEntry method
Extracts the content of the specified entry from the RAR archive.
Returns a list of bytes representing the unpacked content of the entry. Throws a RarException if the extraction fails or the entry is compressed using an unsupported compression method.
Implementation
@override
Future<List<int>> extractEntry({required RarArchiveEntry entry}) async {
if (entry.isDirectory) {
return const [];
}
if (entry.compressionMethod != 0 && entry.compressionMethod != 0x33) {
final err =
'Unsupported compression method: 0x${entry.compressionMethod.toRadixString(16)}. '
'Only stored (uncompressed) entries and RAR4 normal (0x33) compression are supported.';
stderr.writeln(err);
throw RarException(err);
}
try {
final raf = await _file.open(mode: FileMode.read);
try {
await raf.setPosition(entry.dataOffset);
final data = await raf.read(entry.packedSize);
if (data.length < entry.packedSize) {
throw RarException(
'Truncated file data for "${entry.name}": Read ${data.length} bytes, expected ${entry.packedSize}.',
);
}
if (entry.compressionMethod == 0x33) {
final bstream = _RarBitStream(data);
final decompressor = _Rar4Decompressor();
return decompressor.decompress(bstream, entry.size);
} else {
return data;
}
} finally {
await raf.close();
}
} catch (e, stackTrace) {
stderr.writeln(
'Error extracting RAR entry "${entry.name}": $e\n$stackTrace');
if (e is RarException) {
rethrow;
}
throw RarException('Failed to extract RAR entry "${entry.name}"', e);
}
}