[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()));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.