summaryrefslogtreecommitdiffstats
path: root/src/cc4group.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cc4group.c')
-rw-r--r--src/cc4group.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/src/cc4group.c b/src/cc4group.c
index e126984..48fa931 100644
--- a/src/cc4group.c
+++ b/src/cc4group.c
@@ -411,10 +411,10 @@ static bool cc4group_inflateFillOutput(z_stream* const strm, CC4Group_ReadCallba
return ret == Z_OK || (ret == Z_STREAM_END && strm->avail_in == 0 && eof);
}
-static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback const callback, void* const callbackArg, int const memoryManagement)
+static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback const readCallback, void* const callbackArg, int const memoryManagement, CC4Group_ReadSetupCallback const initCallback, CC4Group_ReadSetupCallback const deinitCallback)
{
assert(this);
- assert(callback);
+ assert(readCallback);
assert(callbackArg);
// only if the group is still empty
@@ -428,6 +428,14 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
CC4Group_CleanupJob tmpCleanup;
uint8_t* mappedTmpFile = NULL;
+ if(initCallback != NULL)
+ {
+ if(!initCallback(callbackArg))
+ {
+ SET_MESSAGE_ERROR("The initCallback failed");
+ return false;
+ }
+ }
size_t totalReadSize = 0;
@@ -447,13 +455,14 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
readData = NULL;
readSize = 0;
- eof = callback((const void**)&readData, &readSize, callbackArg);
+ eof = readCallback((const void**)&readData, &readSize, callbackArg);
if(readSize == 0)
{
continue;
}
+ // TODO: check for success at every call of this
cc4group_applyMemoryManagementStart(memoryManagement, &readData, readSize);
size_t newTotalReadSize = totalReadSize + readSize;
@@ -527,7 +536,7 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
strm.avail_in = totalReadSize - 2;
}
- if(!cc4group_inflateFillOutput(&strm, callback, callbackArg, memoryManagement, &eof, &readData, &ret))
+ if(!cc4group_inflateFillOutput(&strm, readCallback, callbackArg, memoryManagement, &eof, &readData, &ret))
{
if(eof && ret == Z_BUF_ERROR)
{
@@ -587,7 +596,7 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
strm.next_out = (Bytef*)cores;
strm.avail_out = sizeof(C4GroupEntryCore) * header->Entries;
- if(!cc4group_inflateFillOutput(&strm, callback, callbackArg, memoryManagement, &eof, &readData, &ret))
+ if(!cc4group_inflateFillOutput(&strm, readCallback, callbackArg, memoryManagement, &eof, &readData, &ret))
{
if(eof && ret == Z_BUF_ERROR)
{
@@ -615,7 +624,7 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
strm.next_out = data;
strm.avail_out = uncompressedSize;
- if(!cc4group_inflateFillOutput(&strm, callback, callbackArg, memoryManagement, &eof, &readData, &ret))
+ if(!cc4group_inflateFillOutput(&strm, readCallback, callbackArg, memoryManagement, &eof, &readData, &ret))
{
if(eof && ret == Z_BUF_ERROR)
{
@@ -628,6 +637,14 @@ static bool cc4group_uncompressGroup(CC4Group* const this, CC4Group_ReadCallback
goto ret;
}
+ if(deinitCallback != NULL)
+ {
+ if(!deinitCallback(callbackArg))
+ {
+ fprintf(stderr, "WARNING: cc4group_uncompressGroup: the deinitCallback failed\n");
+ }
+ }
+
if(strm.avail_in > 0 || ret != Z_STREAM_END)
{
SET_MALFORMED_MESSAGE_ERROR("The group contents are read completely but more data is left to read");
@@ -684,41 +701,55 @@ static bool cc4group_completeDataReadCallback(const void** const data, size_t* c
return true;
}
-static bool cc4group_readFdReadCallback(const void** const data, size_t* const size, void* callbackArg)
+typedef struct {
+ void* arg;
+ void* buffer;
+} ChunkedReadData;
+
+static bool cc4group_initChunkBufferCallback(void* callbackArg)
{
#define CHUNK_SIZE 1000*1000
- void* readData = malloc(CHUNK_SIZE);
- if(data == NULL)
+ void* buffer = malloc(CHUNK_SIZE);
+
+ if(buffer == NULL)
{
- return true;
+ return false;
}
- ssize_t count = read(*(int*)callbackArg, readData, CHUNK_SIZE);
+ ((ChunkedReadData*)callbackArg)->buffer = buffer;
+ return true;
+}
+
+static bool cc4group_deinitChunkBufferCallback(void* callbackArg)
+{
+ free(((ChunkedReadData*)callbackArg)->buffer);
+ return true;
+}
+
+static bool cc4group_readFdReadCallback(const void** const data, size_t* const size, void* callbackArg)
+{
+ ChunkedReadData* arg = callbackArg;
+ void* buffer = arg->buffer;
+ ssize_t count = read(*(int*)arg->arg, buffer, CHUNK_SIZE);
if(count > 0)
{
- *data = readData;
+ *data = buffer;
*size = count;
return false;
}
return true;
-#undef CHUNK_SIZE
}
static bool cc4group_readFilePointerReadCallback(const void** const data, size_t* const size, void* callbackArg)
{
-#define CHUNK_SIZE 1000*1000
- void* readData = malloc(CHUNK_SIZE);
- if(data == NULL)
- {
- return true;
- }
-
- size_t count = fread(readData, 1, CHUNK_SIZE, callbackArg);
+ ChunkedReadData* arg = callbackArg;
+ void* buffer = arg->buffer;
+ size_t count = fread(buffer, 1, CHUNK_SIZE, arg->arg);
if(count > 0)
{
- *data = readData;
+ *data = buffer;
*size = count;
return false;
}
@@ -733,7 +764,7 @@ static bool cc4group_openMemory(CC4Group* const this, const void* const compress
assert(size);
CompleteDataReadCallbackArg data = {.data = compressedData, .size = size};
- return cc4group_uncompressGroup(this, cc4group_completeDataReadCallback, &data, memoryManagement);
+ return cc4group_uncompressGroup(this, cc4group_completeDataReadCallback, &data, memoryManagement, NULL, NULL);
}
static bool cc4group_setSubRoot(CC4Group* const this, const char* const subPath)
@@ -832,7 +863,7 @@ static bool cc4group_uncompressGroupFromFile(CC4Group* const this, const char* c
}
CompleteDataReadCallbackArg data = {.data = mappedFile, .size = size};
- success = cc4group_uncompressGroup(this, cc4group_completeDataReadCallback, &data, Reference);
+ success = cc4group_uncompressGroup(this, cc4group_completeDataReadCallback, &data, Reference, NULL, NULL);
ret:
if(mappedFile != MAP_FAILED)
@@ -1042,12 +1073,14 @@ static bool cc4group_create(CC4Group* const this)
static bool cc4group_openFd(CC4Group* const this, int fd)
{
- return cc4group_uncompressGroup(this, cc4group_readFdReadCallback, &fd, Take);
+ ChunkedReadData arg = {.arg = &fd};
+ return cc4group_uncompressGroup(this, cc4group_readFdReadCallback, &arg, Reference, cc4group_initChunkBufferCallback, cc4group_deinitChunkBufferCallback);
}
static bool cc4group_openFilePointer(CC4Group* const this, FILE* file)
{
- return cc4group_uncompressGroup(this, cc4group_readFilePointerReadCallback, file, Take);
+ ChunkedReadData arg = {.arg = file};
+ return cc4group_uncompressGroup(this, cc4group_readFilePointerReadCallback, &arg, Reference, cc4group_initChunkBufferCallback, cc4group_deinitChunkBufferCallback);
}
static bool cc4group_openExisting(CC4Group* const this, const char* const path)