genesys: Wrap exported functions to always catch exceptions

merge-requests/75/head
Povilas Kanapickas 2019-05-25 10:03:14 +03:00
rodzic 5d7fc4e0ed
commit 23f3ebf612
2 zmienionych plików z 175 dodań i 19 usunięć

Wyświetl plik

@ -64,6 +64,7 @@
#include "../include/sane/sanei_config.h"
#include "../include/sane/sanei_magic.h"
#include "genesys_devices.cc"
#include <exception>
static SANE_Int num_devices = 0;
static Genesys_Device *first_dev = 0;
@ -6444,7 +6445,7 @@ genesys_buffer_image(Genesys_Scanner *s)
/* -------------------------- SANE API functions ------------------------- */
SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
{
SANE_Status status;
@ -6491,8 +6492,17 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
return status;
}
extern "C" SANE_Status sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_init_impl(version_code, authorize);
});
}
void
sane_exit (void)
sane_exit_impl(void)
{
Genesys_Device *dev, *next;
@ -6516,8 +6526,13 @@ sane_exit (void)
DBGCOMPLETED;
}
void sane_exit()
{
catch_all_exceptions(__func__, [](){ sane_exit_impl(); });
}
SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)
sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only)
{
Genesys_Device *dev, *prev;
SANE_Int index;
@ -6605,8 +6620,16 @@ sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)
return SANE_STATUS_GOOD;
}
SANE_Status sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_get_devices_impl(device_list, local_only);
});
}
SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
{
Genesys_Device *dev;
SANE_Status status;
@ -6731,8 +6754,16 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
return SANE_STATUS_GOOD;
}
SANE_Status sane_open(SANE_String_Const devicename, SANE_Handle* handle)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_open_impl(devicename, handle);
});
}
void
sane_close (SANE_Handle handle)
sane_close_impl(SANE_Handle handle)
{
Genesys_Scanner *prev, *s;
Genesys_Calibration_Cache *cache, *next_cache;
@ -6840,8 +6871,16 @@ sane_close (SANE_Handle handle)
DBGCOMPLETED;
}
void sane_close(SANE_Handle handle)
{
catch_all_exceptions(__func__, [=]()
{
sane_close_impl(handle);
});
}
const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
sane_get_option_descriptor_impl(SANE_Handle handle, SANE_Int option)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
@ -6851,6 +6890,19 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
return s->opt + option;
}
const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
{
const SANE_Option_Descriptor* ret = NULL;
catch_all_exceptions(__func__, [&]()
{
ret = sane_get_option_descriptor_impl(handle, option);
});
return ret;
}
/* gets an option , called by sane_control_option */
static SANE_Status
get_option_value (Genesys_Scanner * s, int option, void *val)
@ -7368,8 +7420,8 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
/* sets and gets scanner option values */
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
sane_control_option_impl(SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
SANE_Status status = SANE_STATUS_GOOD;
@ -7449,10 +7501,16 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return status;
}
SANE_Status sane_control_option(SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_control_option_impl(handle, option, action, val, info);
});
}
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
SANE_Status sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
SANE_Status status;
@ -7486,8 +7544,15 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
return SANE_STATUS_GOOD;
}
SANE_Status
sane_start (SANE_Handle handle)
SANE_Status sane_get_parameters(SANE_Handle handle, SANE_Parameters* params)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_get_parameters_impl(handle, params);
});
}
SANE_Status sane_start_impl(SANE_Handle handle)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
SANE_Status status=SANE_STATUS_GOOD;
@ -7577,9 +7642,16 @@ sane_start (SANE_Handle handle)
return status;
}
SANE_Status sane_start(SANE_Handle handle)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_start_impl(handle);
});
}
SANE_Status
sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
SANE_Int * len)
sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
Genesys_Device *dev;
@ -7711,8 +7783,15 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
return status;
}
void
sane_cancel (SANE_Handle handle)
SANE_Status sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_read_impl(handle, buf, max_len, len);
});
}
void sane_cancel_impl(SANE_Handle handle)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
SANE_Status status = SANE_STATUS_GOOD;
@ -7786,8 +7865,13 @@ sane_cancel (SANE_Handle handle)
return;
}
void sane_cancel(SANE_Handle handle)
{
catch_all_exceptions(__func__, [=]() { sane_cancel_impl(handle); });
}
SANE_Status
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
sane_set_io_mode_impl(SANE_Handle handle, SANE_Bool non_blocking)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
@ -7805,7 +7889,16 @@ sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
}
SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_set_io_mode_impl(handle, non_blocking);
});
}
SANE_Status
sane_get_select_fd_impl(SANE_Handle handle, SANE_Int * fd)
{
Genesys_Scanner *s = (Genesys_Scanner*) handle;
@ -7819,4 +7912,13 @@ sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
return SANE_STATUS_UNSUPPORTED;
}
SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_get_select_fd_impl(handle, fd);
});
}
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */

Wyświetl plik

@ -81,6 +81,9 @@
#include "../include/_stdint.h"
#include <memory>
#include <stdexcept>
#define DBG_error0 0 /* errors/warnings printed even with devuglevel 0 */
#define DBG_error 1 /* fatal errors */
#define DBG_init 2 /* initialization and scanning time messages */
@ -1263,4 +1266,55 @@ extern void* sanei_gl_vector_get_element(Genesys_Vector* v, size_t i);
extern void sanei_gl_vector_set_element(Genesys_Vector* v, void* data, size_t i);
extern void sanei_gl_vector_destroy(Genesys_Vector* v);
class SaneException : std::exception {
public:
SaneException(SANE_Status status) : status_(status) {}
SANE_Status status() const { return status_; }
virtual const char* what() const noexcept override { return sane_strstatus(status_); }
private:
SANE_Status status_;
};
template<class F>
SANE_Status wrap_exceptions_to_status_code(const char* func, F&& function)
{
try {
return function();
} catch (const SaneException& exc) {
return exc.status();
} catch (const std::bad_alloc& exc) {
return SANE_STATUS_NO_MEM;
} catch (const std::exception& exc) {
DBG(DBG_error, "%s: got uncaught exception: %s", func, exc.what());
return SANE_STATUS_INVAL;
} catch (...) {
DBG(DBG_error, "%s: got unknown uncaught exception", func);
return SANE_STATUS_INVAL;
}
}
template<class F>
void catch_all_exceptions(const char* func, F&& function)
{
try {
function();
} catch (const SaneException& exc) {
// ignore, this will already be logged
} catch (const std::bad_alloc& exc) {
// ignore, this will already be logged
} catch (const std::exception& exc) {
DBG(DBG_error, "%s: got uncaught exception: %s", func, exc.what());
} catch (...) {
DBG(DBG_error, "%s: got unknown uncaught exception", func);
}
}
inline void wrap_status_code_to_exception(SANE_Status status)
{
if (status == SANE_STATUS_GOOD)
return;
throw SaneException(status);
}
#endif /* not GENESYS_LOW_H */