Skip to content

Commit

Permalink
Merge pull request #174 from ctabin/error-handler-imp
Browse files Browse the repository at this point in the history
Improvement of error handler callback
  • Loading branch information
ctabin authored Dec 10, 2022
2 parents 6be928e + b9e8cef commit d1bf735
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 25 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,12 @@ using namespace libzippp;
int main(int argc, char** argv) {
ZipArchive zf("archive.zip");
zf.setErrorHandlerCallback([](const std::string& message,
const std::string& strerror,
int zip_error_code,
int system_error_code)
{
// Handle error here
fprintf(stderr, message.c_str(), strerror.c_str());
});

zf.open(ZipArchive::Write);
Expand Down
33 changes: 20 additions & 13 deletions src/libzippp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,35 @@ static CompressionMethod convertCompressionFromLibzip(libzippp_uint16 comp) {
}

namespace Helper {
static void callErrorHandlingCallback(zip* zipHandle, const std::string& msg, const ErrorHandlerCallback& callback) {
static void callErrorHandlingCallbackFunc(const std::string& message, int zip_error_code, int system_error_code, ErrorHandlerCallback* callback) {
zip_error_t error;
zip_error_init(&error);
zip_error_set(&error, zip_error_code, system_error_code);
std::string strerror(zip_error_strerror(&error));
(*callback)(message, strerror, zip_error_code, system_error_code);
zip_error_fini(&error);
}

static void callErrorHandlingCallback(zip* zipHandle, const std::string& msg, ErrorHandlerCallback* callback) {
int error_code_zip, error_code_system;
zip_error_get(zipHandle, &error_code_zip, &error_code_system);
callback(msg, error_code_zip, error_code_system);
callErrorHandlingCallbackFunc(msg, error_code_zip, error_code_system, callback);
}

static void callErrorHandlingCallback(zip_error_t* error, const std::string& msg, const ErrorHandlerCallback& callback) {
static void callErrorHandlingCallback(zip_error_t* error, const std::string& msg, ErrorHandlerCallback* callback) {
int error_code_zip, error_code_system;
error_code_zip = zip_error_code_zip(error);
error_code_system = zip_error_code_system(error);
callback(msg, error_code_zip, error_code_system);
callErrorHandlingCallbackFunc(msg, error_code_zip, error_code_system, callback);
}
}

static void defaultErrorHandler(const std::string& message,
const std::string& strerror,
int zip_error_code,
int system_error_code)
{
zip_error_t error;
zip_error_init(&error);
zip_error_set(&error, zip_error_code, system_error_code);
fprintf(stderr, message.c_str(), zip_error_strerror(&error));
zip_error_fini(&error);
fprintf(stderr, message.c_str(), strerror.c_str());
}

ZipEntry::ZipEntry(void) : zipFile(nullptr), index(0), time(0), compressionMethod(ZIP_CM_DEFAULT), encryptionMethod(ZIP_EM_NONE), size(0), sizeComp(0), crc(0) {
Expand Down Expand Up @@ -191,6 +197,7 @@ ZipArchive::~ZipArchive(void) {
zipHandle = nullptr;
zipSource = nullptr;
bufferData = nullptr;
errorHandlingCallback = nullptr;
listeners.clear();
}

Expand Down Expand Up @@ -273,7 +280,7 @@ bool ZipArchive::openSource(zip_source* source, OpenMode om, bool checkConsisten
/* open zip archive from source */
zipHandle = zip_open_from_source(source, zipFlag, &error);
if (zipHandle == nullptr) {
Helper::callErrorHandlingCallback(&error, "can't open zip from source: %s",errorHandlingCallback);
Helper::callErrorHandlingCallback(&error, "can't open zip from source: %s\n", errorHandlingCallback);
zip_error_fini(&error);
return false;
}
Expand Down Expand Up @@ -315,7 +322,7 @@ bool ZipArchive::open(OpenMode om, bool checkConsistency) {
if (errorFlag!=ZIP_ER_OK) {
zip_error_t error;
zip_error_init_with_code(&error, errorFlag);
Helper::callErrorHandlingCallback(&error, "unable to open archive: %s", errorHandlingCallback);
Helper::callErrorHandlingCallback(&error, "unable to open archive: %s\n", errorHandlingCallback);
zip_error_fini(&error);

zipHandle = nullptr;
Expand Down Expand Up @@ -399,7 +406,7 @@ int ZipArchive::close(void) {
zip_int64_t newLength = bufferLength + increment;
sourceBuffer = realloc(sourceBuffer, newLength * sizeof(char));
if(sourceBuffer==nullptr) {
Helper::callErrorHandlingCallback(zipHandle, "can't read back from source: unable to extend buffer", errorHandlingCallback);
Helper::callErrorHandlingCallback(zipHandle, "can't read back from source: unable to extend buffer\n", errorHandlingCallback);
return LIBZIPPP_ERROR_MEMORY_ALLOCATION;
}

Expand All @@ -417,7 +424,7 @@ int ZipArchive::close(void) {
*bufferData = sourceBuffer;
bufferLength = totalRead;
} else {
Helper::callErrorHandlingCallback(zipHandle, "can't read back from source: changes were not pushed in the buffer", errorHandlingCallback);
Helper::callErrorHandlingCallback(zipHandle, "can't read back from source: changes were not pushed in the buffer\n", errorHandlingCallback);
return srcOpen;
}

Expand Down
31 changes: 20 additions & 11 deletions src/libzippp.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ struct zip_source;
#define LIBZIPPP_ERROR_OWRITE_INDEX_FAILURE -36
#define LIBZIPPP_ERROR_UNKNOWN -99

/**
* User-defined error-handler.
* See https://libzip.org/documentation/zip_error_system_type.html
*
* The default handler just print the error by the following way:
* fprintf(stderr, message.c_str(), strerror.c_str());
*
* Parameters are:
* - message: A message, with possible placeholders (%s) for printf.
* - strerror: A description of the error message, issued from libzip (see zip_error_strerror).
* - zip_error_code: the libzip error code.
* - system_error_code: the system error code.
*/
typedef void ErrorHandlerCallback(const std::string& message,
const std::string& strerror,
int zip_error_code,
int system_error_code);

namespace libzippp {
class ZipEntry;
class ZipProgressListener;
Expand Down Expand Up @@ -131,15 +149,6 @@ namespace libzippp {
#define LIBZIPPP_USE_ZSTD
#endif


/**
* User-defined error-handler.
* See https://libzip.org/documentation/zip_error_system_type.html
*/
using ErrorHandlerCallback = std::function<void(const std::string& message,
int zip_error_code,
int system_error_code)>;

/**
* Represents a ZIP archive. This class provides useful methods to handle an archive
* content. It is simply a wrapper around libzip.
Expand Down Expand Up @@ -565,7 +574,7 @@ namespace libzippp {
inline double getProgressPrecision(void) const { return progressPrecision; }
void setProgressPrecision(double p) { progressPrecision = p; }

void setErrorHandlerCallback(const ErrorHandlerCallback& callback) {
void setErrorHandlerCallback(ErrorHandlerCallback* callback) {
errorHandlingCallback = callback;
}

Expand All @@ -588,7 +597,7 @@ namespace libzippp {
libzippp_uint16 compressionMethod;

// User-defined error handler
ErrorHandlerCallback errorHandlingCallback;
ErrorHandlerCallback* errorHandlingCallback;

//open from in-memory data
bool openBuffer(void** buffer, libzippp_uint32 sz, OpenMode mode=ReadOnly, bool checkConsistency=false);
Expand Down
23 changes: 22 additions & 1 deletion tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,12 +871,33 @@ void test23() {
}*/
}

static void myErrorHandler(const std::string& message,
const std::string& strerror,
int zip_error_code,
int system_error_code)
{
fprintf(stderr, "# zip_error_code: %d\n", zip_error_code);
fprintf(stderr, "# system_error_code: %d\n", system_error_code);
fprintf(stderr, message.c_str(), strerror.c_str());
}

void test24() {
cout << "Running test 24...";

ZipArchive z1("non-existent.zip");
z1.setErrorHandlerCallback(myErrorHandler);
z1.open(ZipArchive::ReadOnly);
z1.close();

cout << " done." << endl;
}

int main(int argc, char** argv) {
test1(); test2(); test3(); test4(); test5();
test6(); test7(); test8(); test9(); test10();
test11(); test12(); test13(); test14(); test15();
test16(); test17(); test18(); test19(); test20();
test21(); test22(); test23();
test21(); test22(); test23(); test24();
return 0;
}

Expand Down

0 comments on commit d1bf735

Please sign in to comment.