[frameworks/karchive] src: kzip: write data in chunks
George Florea Bănuș <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit f33d70da6ed7afa5d0b7b04542f689297b0a1714 by George Florea Bănuș.
Committed on 30/07/2026 at 15:40.
Pushed by georgefb into branch 'master'.
kzip: write data in chunks
z_stream::avail_in is a uint32_t and only supports input sizes up to UINT32_MAX
a chunk size of "2 * 1024 * 1024" was chosen because it was the fastest
in a simple benchmark that consisted of creating a ZIP archive
containing a single 5 GB file; each chunk size was tested only once
64 * 1024: 82867 ms elapsed
256 * 1024: 82535 ms elapsed
1024 * 1024: 74614 ms elapsed
2 * 1024 * 1024: 72103 ms elapsed
5 * 1024 * 1024: 79815 ms elapsed
1024 * 1024 * 1024: 82510 ms elapsed
M +20 -3 src/kzip.cpp
https://invent.kde.org/frameworks/karchive/-/commit/f33d70da6ed7afa5d0b7b04542f689297b0a1714
diff --git a/src/kzip.cpp b/src/kzip.cpp
index 27e0a2c..2faf812 100644
--- a/src/kzip.cpp
+++ b/src/kzip.cpp
@@ -1526,11 +1526,28 @@ bool KZip::doWriteData(const char *data, qint64 size)
// crc to be calculated over uncompressed stuff...
// and they didn't mention it in their docs...
- d->m_crc = crc32(d->m_crc, (const Bytef *)data, size);
+ quint32 crc = d->m_crc;
+
+ constexpr qint64 chunkSize = 2 * 1024 * 1024;
+ qint64 totalWritten = 0;
+ while (totalWritten < size) {
+ qint64 chunk = std::min(chunkSize, size - totalWritten);
+
+ crc = crc32(crc, reinterpret_cast<const Bytef *>(data + totalWritten), static_cast<quint32>(chunk));
+
+ qint64 currentWritten = d->m_currentDev->write(data + totalWritten, chunk);
+ if (currentWritten != chunk) {
+ setErrorString(tr("Error writing data chunk: %1").arg(d->m_currentDev->errorString()));
+ return false;
+ }
+
+ totalWritten += currentWritten;
+ }
+
+ d->m_crc = crc;
- qint64 written = d->m_currentDev->write(data, size);
// qCDebug(KArchiveLog) << "wrote" << size << "bytes.";
- const bool ok = written == size;
+ const bool ok = totalWritten == size;
if (!ok) {
setErrorString(tr("Error writing data: %1").arg(d->m_currentDev->errorString()));