summaryrefslogtreecommitdiff
path: root/bsdiff.c
diff options
context:
space:
mode:
authorMatthew Endsley <mendsley@gmail.com>2012-05-13 14:52:06 -0700
committerMatthew Endsley <mendsley@gmail.com>2012-05-14 01:04:24 -0700
commit7631dd5d4007990b95ae8f1741bff3f190579447 (patch)
tree3d11cceb61d2bd6bac52bd1146013850d2628538 /bsdiff.c
parent588cd9af702eb2eb047bc51cf24308fa1e0c5bb0 (diff)
downloadbsdiff-7631dd5d4007990b95ae8f1741bff3f190579447.tar.gz
handling large file requests by breaking up calls to compressor->write
Diffstat (limited to 'bsdiff.c')
-rw-r--r--bsdiff.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/bsdiff.c b/bsdiff.c
index 1093241..8c373cb 100644
--- a/bsdiff.c
+++ b/bsdiff.c
@@ -49,6 +49,7 @@ struct bsdiff_compressor
#if !defined(BSDIFF_HEADER_ONLY)
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -207,6 +208,27 @@ static void offtout(int64_t x,uint8_t *buf)
if(x<0) buf[7]|=0x80;
}
+static int64_t writecompressed(struct bsdiff_compressor* compressor, const void* buffer, int64_t length)
+{
+ int64_t result = 0;
+
+ while (length > 0)
+ {
+ const int smallsize = (int)MIN(length, INT_MAX);
+ const int writeresult = compressor->write(compressor, buffer, smallsize);
+ if (writeresult == -1)
+ {
+ return -1;
+ }
+
+ result += writeresult;
+ length -= smallsize;
+ buffer = (uint8_t*)buffer + smallsize;
+ }
+
+ return result;
+}
+
struct bsdiff_request
{
const uint8_t* old;
@@ -327,7 +349,7 @@ static int bsdiff_internal(const struct bsdiff_request req)
offtout((scan-lenb)-(lastscan+lenf),buf+8);
offtout((pos-lenb)-(lastpos+lenf),buf+16);
- compresslen = req.compressor->write(req.compressor, buf, sizeof(buf));
+ compresslen = writecompressed(req.compressor, buf, sizeof(buf));
if (compresslen == -1)
return -1;
filelen += compresslen;
@@ -346,7 +368,7 @@ static int bsdiff_internal(const struct bsdiff_request req)
req.header->ctrl_block_length = filelen;
/* Write compressed diff data */
- compresslen = req.compressor->write(req.compressor, db, dblen);
+ compresslen = writecompressed(req.compressor, db, dblen);
if (compresslen == -1)
return -1;
filelen += compresslen;
@@ -359,7 +381,7 @@ static int bsdiff_internal(const struct bsdiff_request req)
req.header->diff_block_length = filelen - req.header->ctrl_block_length;
/* Write compressed extra data */
- compresslen = req.compressor->write(req.compressor, eb, eblen);
+ compresslen = writecompressed(req.compressor, eb, eblen);
if (compresslen == -1)
return -1;
compresslen = req.compressor->finish(req.compressor);