diff --git a/openbr/universal_template.cpp b/openbr/universal_template.cpp index 15ad775..fc72586 100644 --- a/openbr/universal_template.cpp +++ b/openbr/universal_template.cpp @@ -55,44 +55,41 @@ static void callAndFree(br_utemplate_callback callback, br_utemplate t, br_callb free(t); } +static bool read_buffer(FILE *file, char *buffer, size_t bytes, bool eofAllowed) +{ + size_t bytesRemaining = bytes; + while (bytesRemaining) { + const size_t bytesRead = fread(buffer, 1, bytesRemaining, file); + buffer += bytesRead; + bytesRemaining -= bytesRead; + + if (feof(file)) { + if (eofAllowed && (bytesRemaining == bytes)) + return false; + qFatal("Unexpected end of file after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes)); + } + + if (ferror(file)) { + perror(NULL); + qFatal("Error while reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes)); + } + } + return true; +} + void br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel) { QFutureSynchronizer futures; while (true) { br_utemplate t = (br_utemplate) malloc(sizeof(br_universal_template)); - int bytesRemaining = sizeof(br_universal_template); - while (bytesRemaining > 0) { - bytesRemaining -= fread(reinterpret_cast(t) + sizeof(br_universal_template) - bytesRemaining, 1, bytesRemaining, file); - - if (feof(file)) { - if (bytesRemaining == sizeof(br_universal_template)) { - free(t); - return; - } else { - qFatal("Unexpected end of file when reading template metadata."); - } - } - - if (ferror(file)) { - perror(NULL); - qFatal("Error while reading template metadata."); - } + if (!read_buffer(file, (char*) t, sizeof(br_universal_template), true)) { + free(t); + return; } t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->size); - bytesRemaining = t->size; - while (bytesRemaining > 0) { - bytesRemaining -= fread(&t->data[t->size - bytesRemaining], 1, bytesRemaining, file); - - if (feof(file)) - qFatal("Unexpected end of file when reading template data."); - - if (ferror(file)) { - perror(NULL); - qFatal("Error while reading template data."); - } - } + read_buffer(file, (char*) &t->data, t->size, false); if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context)); else callAndFree(callback, t, context);