addFile method
void
addFile(
- ArchiveFile file, {
- bool autoClose = true,
})
inherited
Implementation
void addFile(ArchiveFile file, {bool autoClose = true}) {
final fileData = _ZipFileData();
_data.files.add(fileData);
final lastModMS = file.lastModTime * 1000;
final lastModTime = DateTime.fromMillisecondsSinceEpoch(lastModMS);
fileData.name = file.name;
// If the archive modification time was overwritten, use that, otherwise
// use the lastModTime from the file.
fileData.time = _data.time ?? _getTime(lastModTime)!;
fileData.date = _data.date ?? _getDate(lastModTime)!;
fileData.mode = file.mode;
fileData.isFile = file.isFile;
InputStreamBase? compressedData;
int crc32 = 0;
// If the user want's to store the file without compressing it,
// make sure it's decompressed.
if (!file.compress) {
if (file.isCompressed) {
file.decompress();
}
compressedData = (file.content is InputStreamBase)
? file.content as InputStreamBase
: InputStream(file.content);
if (file.crc32 != null) {
crc32 = file.crc32!;
} else {
crc32 = getFileCrc32(file);
}
} else if (file.isCompressed &&
file.compressionType == ArchiveFile.DEFLATE &&
file.rawContent != null) {
// If the file is already compressed, no sense in uncompressing it and
// compressing it again, just pass along the already compressed data.
compressedData = file.rawContent;
if (file.crc32 != null) {
crc32 = file.crc32!;
} else {
crc32 = getFileCrc32(file);
}
} else if (file.isFile) {
// Otherwise we need to compress it now.
crc32 = getFileCrc32(file);
dynamic bytes = file.content;
if (bytes is InputStreamBase) {
bytes = bytes.toUint8List();
}
bytes = Deflate(bytes as List<int>, level: _data.level).getBytes();
compressedData = InputStream(bytes);
}
final encodedFilename = filenameEncoding.encode(file.name);
final comment =
file.comment != null ? filenameEncoding.encode(file.comment!) : null;
Uint8List? salt;
if (password != null && compressedData != null) {
// https://www.winzip.com/en/support/aes-encryption/#zip-format
//
// The size of the salt value depends on the length of the encryption key,
// as follows:
//
// Key size Salt size
// 128 bits 8 bytes
// 192 bits 12 bytes
// 256 bits 16 bytes
//
salt = _generateSalt(16);
final encryptedBytes =
_encryptCompressedData(compressedData.toUint8List(), salt);
compressedData = InputStream(encryptedBytes);
}
final dataLen = (compressedData?.length ?? 0) +
(salt?.length ?? 0) +
(_mac?.length ?? 0) +
(_pwdVer?.length ?? 0);
_data.localFileSize += 30 + encodedFilename.length + dataLen;
_data.centralDirectorySize +=
46 + encodedFilename.length + (comment != null ? comment.length : 0);
fileData.crc32 = crc32;
fileData.compressedSize = dataLen;
fileData.compressedData = compressedData;
fileData.uncompressedSize = file.size;
fileData.compress = file.compress;
fileData.comment = file.comment;
fileData.position = _output!.length;
_writeFile(fileData, _output!, salt: salt);
fileData.compressedData = null;
if (autoClose) {
file.closeSync();
}
}