Merge branch 'genesys-logging-improvements' into 'master'

genesys: Miscellaneous logging improvements

See merge request sane-project/backends!237
merge-requests/237/merge
Povilas Kanapickas 2019-11-10 12:12:41 +00:00
commit a15d960228
5 zmienionych plików z 232 dodań i 219 usunięć

Wyświetl plik

@ -114,7 +114,11 @@ void SaneException::set_msg(const char* format, std::va_list vlist)
const char* status_msg = sane_strstatus(status_);
std::size_t status_msg_len = std::strlen(status_msg);
int msg_len = std::vsnprintf(nullptr, 0, format, vlist);
std::va_list vlist2;
va_copy(vlist2, vlist);
int msg_len = std::vsnprintf(nullptr, 0, format, vlist2);
va_end(vlist2);
if (msg_len < 0) {
const char* formatting_error_msg = "(error formatting arguments)";
msg_.reserve(std::strlen(formatting_error_msg) + 3 + status_msg_len);
@ -178,4 +182,34 @@ void DebugMessageHelper::vstatus(const char* format, ...)
va_end(args);
}
void DebugMessageHelper::log(unsigned level, const char* msg)
{
DBG(level, "%s: %s\n", func_, msg);
}
void DebugMessageHelper::vlog(unsigned level, const char* format, ...)
{
std::string msg;
std::va_list args;
va_start(args, format);
int msg_len = std::vsnprintf(nullptr, 0, format, args);
va_end(args);
if (msg_len < 0) {
DBG(level, "%s: error formatting error message: %s\n", func_, format);
return;
}
msg.resize(msg_len + 1, ' ');
va_start(args, format);
std::vsnprintf(&msg.front(), msg.size(), format, args);
va_end(args);
msg.resize(msg_len, ' '); // strip the null character
DBG(level, "%s: %s\n", func_, msg.c_str());
}
} // namespace genesys

Wyświetl plik

@ -98,7 +98,7 @@ private:
do { \
SANE_Status tmp_status = function; \
if (tmp_status != SANE_STATUS_GOOD) { \
throw SaneException(tmp_status); \
throw ::genesys::SaneException(tmp_status); \
} \
} while (false)
@ -124,24 +124,43 @@ public:
void clear() { msg_[0] = '\n'; }
void log(unsigned level, const char* msg);
void vlog(unsigned level, const char* format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 3, 4)))
#endif
;
private:
const char* func_ = nullptr;
char msg_[MAX_BUF_SIZE];
unsigned num_exceptions_on_enter_ = 0;
};
#define DBG_HELPER(var) DebugMessageHelper var(__func__)
#define DBG_HELPER_ARGS(var, ...) DebugMessageHelper var(__func__, __VA_ARGS__)
#if defined(__GNUC__) || defined(__clang__)
#define GENESYS_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
#define GENESYS_CURRENT_FUNCTION __FUNCSIG__
#else
#define GENESYS_CURRENT_FUNCTION __func__
#endif
#define DBG_HELPER(var) DebugMessageHelper var(GENESYS_CURRENT_FUNCTION)
#define DBG_HELPER_ARGS(var, ...) DebugMessageHelper var(GENESYS_CURRENT_FUNCTION, __VA_ARGS__)
template<class F>
SANE_Status wrap_exceptions_to_status_code(const char* func, F&& function)
{
try {
return function();
function();
return SANE_STATUS_GOOD;
} catch (const SaneException& exc) {
DBG(DBG_error, "%s: got error: %s\n", func, exc.what());
return exc.status();
} catch (const std::bad_alloc& exc) {
(void) exc;
DBG(DBG_error, "%s: failed to allocate memory\n", func);
return SANE_STATUS_NO_MEM;
} catch (const std::exception& exc) {
DBG(DBG_error, "%s: got uncaught exception: %s\n", func, exc.what());

Wyświetl plik

@ -182,6 +182,7 @@ static const SANE_Range expiration_range = {
const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev)
{
DBG_HELPER(dbg);
for (const auto& sensor : *s_sensors) {
if (dev->model->sensor_id == sensor.sensor_id) {
return sensor;
@ -193,6 +194,8 @@ const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev)
Genesys_Sensor* find_sensor_impl(Genesys_Device* dev, unsigned dpi, unsigned channels,
ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
static_cast<unsigned>(scan_method));
for (auto& sensor : *s_sensors) {
if (dev->model->sensor_id == sensor.sensor_id && sensor.resolutions.matches(dpi) &&
sensor.matches_channel_count(channels) && sensor.method == scan_method)
@ -206,12 +209,16 @@ Genesys_Sensor* find_sensor_impl(Genesys_Device* dev, unsigned dpi, unsigned cha
bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels,
ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
static_cast<unsigned>(scan_method));
return find_sensor_impl(dev, dpi, channels, scan_method) != nullptr;
}
const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels,
ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
static_cast<unsigned>(scan_method));
const auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method);
if (sensor)
return *sensor;
@ -222,6 +229,8 @@ Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigne
unsigned channels,
ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
static_cast<unsigned>(scan_method));
auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method);
if (sensor)
return *sensor;
@ -232,6 +241,7 @@ Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigne
std::vector<std::reference_wrapper<const Genesys_Sensor>>
sanei_genesys_find_sensors_all(Genesys_Device* dev, ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "scan_method: %d", static_cast<unsigned>(scan_method));
std::vector<std::reference_wrapper<const Genesys_Sensor>> ret;
for (const Genesys_Sensor& sensor : sanei_genesys_find_sensors_all_for_write(dev, scan_method)) {
ret.push_back(sensor);
@ -242,6 +252,7 @@ std::vector<std::reference_wrapper<const Genesys_Sensor>>
std::vector<std::reference_wrapper<Genesys_Sensor>>
sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method)
{
DBG_HELPER_ARGS(dbg, "scan_method: %d", static_cast<unsigned>(scan_method));
std::vector<std::reference_wrapper<Genesys_Sensor>> ret;
for (auto& sensor : *s_sensors) {
if (dev->model->sensor_id == sensor.sensor_id && sensor.method == scan_method) {
@ -251,9 +262,10 @@ std::vector<std::reference_wrapper<Genesys_Sensor>>
return ret;
}
void
sanei_genesys_init_structs (Genesys_Device * dev)
void sanei_genesys_init_structs (Genesys_Device * dev)
{
DBG_HELPER(dbg);
bool gpo_ok = false;
bool motor_ok = false;
bool fe_ok = false;
@ -917,7 +929,7 @@ static void genesys_send_offset_and_shading(Genesys_Device* dev, const Genesys_S
void sanei_genesys_init_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor,
int pixels_per_line)
{
DBG_HELPER(dbg);
DBG_HELPER_ARGS(dbg, "pixels_per_line: %d", pixels_per_line);
if (dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE) {
return;
@ -1647,6 +1659,7 @@ static void genesys_dummy_dark_shading(Genesys_Device* dev, const Genesys_Sensor
static void genesys_repark_sensor_before_shading(Genesys_Device* dev)
{
DBG_HELPER(dbg);
if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) {
// rewind keeps registers and slopes table intact from previous scan but is not
// available on all supported chipsets (or may cause scan artifacts, see #7)
@ -1666,6 +1679,7 @@ static void genesys_repark_sensor_before_shading(Genesys_Device* dev)
static void genesys_repark_sensor_after_white_shading(Genesys_Device* dev)
{
DBG_HELPER(dbg);
if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) {
dev->cmd_set->slow_back_home(dev, true);
}
@ -4346,29 +4360,20 @@ check_present (SANE_String_Const devname) noexcept
return SANE_STATUS_GOOD;
}
static SANE_Status
attach (SANE_String_Const devname, Genesys_Device ** devp, bool may_wait)
static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may_wait)
{
DBG_HELPER_ARGS(dbg, "devp %s nullptr, may_wait = %d", devp ? "!=" : "==", may_wait);
DBG_HELPER_ARGS(dbg, " devname: %s, may_wait = %d", devname, may_wait);
Genesys_Device *dev = nullptr;
if (devp) {
*devp = nullptr;
}
if (!devname)
{
DBG(DBG_error, "%s: devname == nullptr\n", __func__);
return SANE_STATUS_INVAL;
if (!devname) {
throw SaneException("devname must not be nullptr");
}
for (auto& dev : *s_devices) {
if (dev.file_name == devname) {
if (devp)
*devp = &dev;
DBG(DBG_info, "%s: device `%s' was already in device list\n", __func__, devname);
return SANE_STATUS_GOOD;
return &dev;
}
}
@ -4405,9 +4410,8 @@ attach (SANE_String_Const devname, Genesys_Device ** devp, bool may_wait)
}
if (found_usb_dev == nullptr) {
DBG(DBG_error, "%s: vendor 0x%xd product 0x%xd is not supported by this backend\n", __func__,
throw SaneException("vendor 0x%xd product 0x%xd is not supported by this backend",
vendor, product);
return SANE_STATUS_INVAL;
}
s_devices->emplace_back();
@ -4423,31 +4427,17 @@ attach (SANE_String_Const devname, Genesys_Device ** devp, bool may_wait)
DBG(DBG_info, "%s: found %s flatbed scanner %s at %s\n", __func__, dev->model->vendor,
dev->model->model, dev->file_name.c_str());
if (devp) {
*devp = dev;
}
usb_dev.close();
return SANE_STATUS_GOOD;
return dev;
}
static SANE_Status
attach_one_device_impl(SANE_String_Const devname)
{
Genesys_Device *dev;
SANE_Status status = attach(devname, &dev, false);
if (status != SANE_STATUS_GOOD) {
DBG(DBG_info, "%s: failed to attach: %s\n", __func__, sane_strstatus(status));
return status;
}
return status;
}
static SANE_Status attach_one_device(SANE_String_Const devname)
// this function is passed to C API and must not throw
static SANE_Status attach_one_device(SANE_String_Const devname) noexcept
{
DBG_HELPER(dbg);
return wrap_exceptions_to_status_code(__func__, [=]()
{
return attach_one_device_impl(devname);
attach_device_by_name(devname, false);
});
}
@ -4466,24 +4456,19 @@ config_attach_genesys(SANEI_Config __sane_unused__ *config, const char *devname)
}
/* probes for scanner to attach to the backend */
static SANE_Status
probe_genesys_devices (void)
static void probe_genesys_devices (void)
{
DBG_HELPER(dbg);
SANEI_Config config;
SANE_Status status = SANE_STATUS_GOOD;
// set configuration options structure : no option for this backend
config.descriptors = nullptr;
config.values = nullptr;
config.count = 0;
/* generic configure and attach function */
status = sanei_configure_attach (GENESYS_CONFIG_FILE, &config,
config_attach_genesys);
TIE(sanei_configure_attach(GENESYS_CONFIG_FILE, &config, config_attach_genesys));
DBG(DBG_info, "%s: %zu devices currently attached\n", __func__, s_devices->size());
return status;
}
/**
@ -4672,8 +4657,7 @@ static void genesys_buffer_image(Genesys_Scanner *s)
/* -------------------------- SANE API functions ------------------------- */
SANE_Status
sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
void sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
{
DBG_INIT ();
DBG_HELPER_ARGS(dbg, "authorize %s null", authorize ? "!=" : "==");
@ -4716,7 +4700,7 @@ sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize)
);
// cold-plug case :detection of allready connected scanners
return probe_genesys_devices ();
probe_genesys_devices();
}
@ -4724,7 +4708,7 @@ extern "C" SANE_Status sane_init(SANE_Int * version_code, SANE_Auth_Callback aut
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_init_impl(version_code, authorize);
sane_init_impl(version_code, authorize);
});
}
@ -4743,8 +4727,7 @@ extern "C" void sane_exit()
catch_all_exceptions(__func__, [](){ sane_exit_impl(); });
}
SANE_Status
sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only)
void sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only)
{
DBG_HELPER_ARGS(dbg, "local_only = %s", local_only ? "true" : "false");
@ -4781,20 +4764,17 @@ sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only)
s_sane_devices_ptrs->push_back(nullptr);
*const_cast<SANE_Device***>(device_list) = s_sane_devices_ptrs->data();
return SANE_STATUS_GOOD;
}
extern "C" 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_get_devices_impl(device_list, local_only);
});
}
SANE_Status
sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
{
DBG_HELPER_ARGS(dbg, "devicename = %s", devicename);
Genesys_Device* dev = nullptr;
@ -4812,20 +4792,16 @@ sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
}
}
if (!dev)
{
DBG(DBG_info, "%s: couldn't find `%s' in devlist, trying attach\n", __func__, devicename);
SANE_Status status = attach(devicename, &dev, true);
if (status != SANE_STATUS_GOOD) {
DBG(DBG_info, "%s: failed to attach: %s\n", __func__, sane_strstatus(status));
return status;
}
}
else
if (!dev) {
DBG(DBG_info, "%s: couldn't find `%s' in devlist, trying attach\n", __func__,
devicename);
dbg.status("attach_device_by_name");
dev = attach_device_by_name(devicename, true);
dbg.clear();
} else {
DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->model->name);
}
else
{
} else {
// empty devicename or "genesys" -> use first device
if (!s_devices->empty()) {
dev = &s_devices->front();
@ -4833,8 +4809,9 @@ sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
}
}
if (!dev)
return SANE_STATUS_INVAL;
if (!dev) {
throw SaneException("could not find the device to open: %s", devicename);
}
if (dev->model->flags & GENESYS_FLAG_UNTESTED)
{
@ -4892,15 +4869,13 @@ sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
sanei_genesys_read_calibration(s->dev->calibration_cache, s->dev->calib_file);
});
}
return SANE_STATUS_GOOD;
}
extern "C" SANE_Status sane_open(SANE_String_Const devicename, SANE_Handle* handle)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_open_impl(devicename, handle);
sane_open_impl(devicename, handle);
});
}
@ -4977,6 +4952,7 @@ extern "C" void sane_close(SANE_Handle handle)
const SANE_Option_Descriptor *
sane_get_option_descriptor_impl(SANE_Handle handle, SANE_Int option)
{
DBG_HELPER(dbg);
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
if (static_cast<unsigned>(option) >= NUM_OPTIONS) {
@ -4999,16 +4975,37 @@ sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
return ret;
}
/* gets an option , called by sane_control_option */
static SANE_Status
get_option_value (Genesys_Scanner * s, int option, void *val)
static void print_option(DebugMessageHelper& dbg, const Genesys_Scanner& s, int option, void* val)
{
DBG_HELPER(dbg);
switch (s.opt[option].type) {
case SANE_TYPE_INT: {
dbg.vlog(DBG_proc, "value: %d", *reinterpret_cast<SANE_Word*>(val));
return;
}
case SANE_TYPE_BOOL: {
dbg.vlog(DBG_proc, "value: %s", *reinterpret_cast<SANE_Bool*>(val) ? "true" : "false");
return;
}
case SANE_TYPE_FIXED: {
dbg.vlog(DBG_proc, "value: %f", SANE_UNFIX(*reinterpret_cast<SANE_Word*>(val)));
return;
}
case SANE_TYPE_STRING: {
dbg.vlog(DBG_proc, "value: %s", reinterpret_cast<char*>(val));
return;
}
default: break;
}
dbg.log(DBG_proc, "value: (non-printable)");
}
static void get_option_value(Genesys_Scanner* s, int option, void* val)
{
DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option);
unsigned int i;
SANE_Word* table = nullptr;
std::vector<uint16_t> gamma_table;
unsigned option_size = 0;
SANE_Status status = SANE_STATUS_GOOD;
const Genesys_Sensor* sensor = nullptr;
if (sanei_genesys_has_sensor(s->dev, s->dev->settings.xres, s->dev->settings.get_channels(),
@ -5199,7 +5196,7 @@ get_option_value (Genesys_Scanner * s, int option, void *val)
default:
DBG(DBG_warn, "%s: can't get unknown option %d\n", __func__, option);
}
return status;
print_option(dbg, *s, option, val);
}
/** @brief set calibration file value
@ -5229,12 +5226,11 @@ static void set_calibration_value(Genesys_Scanner* s, const char* val)
}
/* sets an option , called by sane_control_option */
static SANE_Status
set_option_value (Genesys_Scanner * s, int option, void *val,
SANE_Int * myinfo)
static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int* myinfo)
{
DBG_HELPER(dbg);
SANE_Status status = SANE_STATUS_GOOD;
DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option);
print_option(dbg, *s, option, val);
SANE_Word *table;
unsigned int i;
unsigned option_size = 0;
@ -5562,13 +5558,11 @@ set_option_value (Genesys_Scanner * s, int option, void *val,
default:
DBG(DBG_warn, "%s: can't set unknown option %d\n", __func__, option);
}
return status;
}
/* sets and gets scanner option values */
SANE_Status
sane_control_option_impl(SANE_Handle handle, SANE_Int option,
void sane_control_option_impl(SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
{
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
@ -5578,75 +5572,52 @@ sane_control_option_impl(SANE_Handle handle, SANE_Int option,
DBG_HELPER_ARGS(dbg, "action = %s, option = %s (%d)", action_str,
s->opt[option].name, option);
SANE_Status status = SANE_STATUS_GOOD;
SANE_Word cap;
SANE_Int myinfo = 0;
if (info)
if (info) {
*info = 0;
if (s->scanning)
{
DBG(DBG_warn, "%s: don't call this function while scanning (option = %s (%d))\n", __func__,
s->opt[option].name, option);
return SANE_STATUS_DEVICE_BUSY;
}
if (option >= NUM_OPTIONS || option < 0)
{
DBG(DBG_warn, "%s: option %d >= NUM_OPTIONS || option < 0\n", __func__, option);
return SANE_STATUS_INVAL;
if (s->scanning) {
throw SaneException(SANE_STATUS_DEVICE_BUSY,
"don't call this function while scanning (option = %s (%d))",
s->opt[option].name, option);
}
if (option >= NUM_OPTIONS || option < 0) {
throw SaneException("option %d >= NUM_OPTIONS || option < 0", option);
}
cap = s->opt[option].cap;
if (!SANE_OPTION_IS_ACTIVE (cap))
{
DBG(DBG_warn, "%s: option %d is inactive\n", __func__, option);
return SANE_STATUS_INVAL;
if (!SANE_OPTION_IS_ACTIVE (cap)) {
throw SaneException("option %d is inactive", option);
}
switch (action)
{
switch (action) {
case SANE_ACTION_GET_VALUE:
status = get_option_value (s, option, val);
get_option_value(s, option, val);
break;
case SANE_ACTION_SET_VALUE:
if (!SANE_OPTION_IS_SETTABLE (cap))
{
DBG(DBG_warn, "%s: option %d is not settable\n", __func__, option);
return SANE_STATUS_INVAL;
if (!SANE_OPTION_IS_SETTABLE (cap)) {
throw SaneException("option %d is not settable", option);
}
status = sanei_constrain_value (s->opt + option, val, &myinfo);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_warn, "%s: sanei_constrain_value returned %s\n", __func__,
sane_strstatus(status));
return status;
}
TIE(sanei_constrain_value(s->opt + option, val, &myinfo));
status = set_option_value (s, option, val, &myinfo);
set_option_value(s, option, val, &myinfo);
break;
case SANE_ACTION_SET_AUTO:
DBG(DBG_error,
"%s: SANE_ACTION_SET_AUTO unsupported since no option has SANE_CAP_AUTOMATIC\n",
__func__);
status = SANE_STATUS_INVAL;
break;
throw SaneException("SANE_ACTION_SET_AUTO unsupported since no option "
"has SANE_CAP_AUTOMATIC");
default:
DBG(DBG_warn, "%s: unknown action %d for option %d\n", __func__, action, option);
status = SANE_STATUS_INVAL;
break;
throw SaneException("unknown action %d for option %d", action, option);
}
if (info)
*info = myinfo;
return status;
}
extern "C" SANE_Status sane_control_option(SANE_Handle handle, SANE_Int option,
@ -5654,11 +5625,11 @@ extern "C" SANE_Status sane_control_option(SANE_Handle handle, SANE_Int option,
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_control_option_impl(handle, option, action, val, info);
sane_control_option_impl(handle, option, action, val, info);
});
}
SANE_Status sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
void sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
{
DBG_HELPER(dbg);
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
@ -5682,33 +5653,27 @@ SANE_Status sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params
params->lines = -1;
}
}
return SANE_STATUS_GOOD;
debug_dump(DBG_proc, *params);
}
extern "C" 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_get_parameters_impl(handle, params);
});
}
SANE_Status sane_start_impl(SANE_Handle handle)
void sane_start_impl(SANE_Handle handle)
{
DBG_HELPER(dbg);
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
SANE_Status status=SANE_STATUS_GOOD;
if (s->pos_top_left_x >= s->pos_bottom_right_x)
{
DBG(DBG_error0, "%s: top left x >= bottom right x --- exiting\n", __func__);
return SANE_STATUS_INVAL;
if (s->pos_top_left_x >= s->pos_bottom_right_x) {
throw SaneException("top left x >= bottom right x");
}
if (s->pos_top_left_y >= s->pos_bottom_right_y)
{
DBG(DBG_error0, "%s: top left y >= bottom right y --- exiting\n", __func__);
return SANE_STATUS_INVAL;
if (s->pos_top_left_y >= s->pos_bottom_right_y) {
throw SaneException("top left y >= bottom right y");
}
/* First make sure we have a current parameter set. Some of the
@ -5738,16 +5703,18 @@ SANE_Status sane_start_impl(SANE_Handle handle)
/* check if we need to skip this page, sheetfed scanners
* can go to next doc while flatbed ones can't */
if (s->swskip > 0 && IS_ACTIVE(OPT_SWSKIP)) {
status = sanei_magic_isBlank(&s->params,
auto status = sanei_magic_isBlank(&s->params,
s->dev->img_buffer.data(),
SANE_UNFIX(s->swskip));
if(status == SANE_STATUS_NO_DOCS)
{
if (s->dev->model->is_sheetfed) {
if (status == SANE_STATUS_NO_DOCS && s->dev->model->is_sheetfed) {
DBG(DBG_info, "%s: blank page, recurse\n", __func__);
return sane_start(handle);
sane_start(handle);
return;
}
return status;
if (status != SANE_STATUS_GOOD) {
throw SaneException(status);
}
}
@ -5770,57 +5737,45 @@ SANE_Status sane_start_impl(SANE_Handle handle)
catch_all_exceptions(__func__, [&](){ genesys_derotate(s); });
}
}
return status;
}
extern "C" SANE_Status sane_start(SANE_Handle handle)
{
return wrap_exceptions_to_status_code(__func__, [=]()
{
return sane_start_impl(handle);
sane_start_impl(handle);
});
}
SANE_Status
sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len)
void sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len)
{
DBG_HELPER(dbg);
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
Genesys_Device *dev;
size_t local_len;
if (!s)
{
DBG(DBG_error, "%s: handle is null!\n", __func__);
return SANE_STATUS_INVAL;
if (!s) {
throw SaneException("handle is nullptr");
}
dev=s->dev;
if (!dev)
{
DBG(DBG_error, "%s: dev is null!\n", __func__);
return SANE_STATUS_INVAL;
if (!dev) {
throw SaneException("dev is nullptr");
}
if (!buf)
{
DBG(DBG_error, "%s: buf is null!\n", __func__);
return SANE_STATUS_INVAL;
if (!buf) {
throw SaneException("buf is nullptr");
}
if (!len)
{
DBG(DBG_error, "%s: len is null!\n", __func__);
return SANE_STATUS_INVAL;
if (!len) {
throw SaneException("len is nullptr");
}
*len = 0;
if (!s->scanning)
{
DBG(DBG_warn, "%s: scan was cancelled, is over or has not been initiated yet\n", __func__);
return SANE_STATUS_CANCELLED;
if (!s->scanning) {
throw SaneException(SANE_STATUS_CANCELLED,
"scan was cancelled, is over or has not been initiated yet");
}
DBG(DBG_proc, "%s: start, %d maximum bytes required\n", __func__, max_len);
@ -5839,7 +5794,7 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int*
dev->cmd_set->slow_back_home(dev, false);
dev->parking = true;
}
return SANE_STATUS_EOF;
throw SaneException(SANE_STATUS_EOF);
}
local_len = max_len;
@ -5903,14 +5858,13 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int*
fprintf (stderr, "[genesys] sane_read: returning incorrect length!!\n");
}
DBG(DBG_proc, "%s: %d bytes returned\n", __func__, *len);
return SANE_STATUS_GOOD;
}
extern "C" 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);
sane_read_impl(handle, buf, max_len, len);
});
}
@ -5955,50 +5909,44 @@ extern "C" void sane_cancel(SANE_Handle handle)
catch_all_exceptions(__func__, [=]() { sane_cancel_impl(handle); });
}
SANE_Status
sane_set_io_mode_impl(SANE_Handle handle, SANE_Bool non_blocking)
void sane_set_io_mode_impl(SANE_Handle handle, SANE_Bool non_blocking)
{
DBG_HELPER_ARGS(dbg, "handle = %p, non_blocking = %s", handle,
non_blocking == SANE_TRUE ? "true" : "false");
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
if (!s->scanning)
{
DBG(DBG_error, "%s: not scanning\n", __func__);
return SANE_STATUS_INVAL;
if (!s->scanning) {
throw SaneException("not scanning");
}
if (non_blocking) {
throw SaneException(SANE_STATUS_UNSUPPORTED);
}
if (non_blocking)
return SANE_STATUS_UNSUPPORTED;
return SANE_STATUS_GOOD;
}
extern "C" SANE_Status 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_set_io_mode_impl(handle, non_blocking);
});
}
SANE_Status
sane_get_select_fd_impl(SANE_Handle handle, SANE_Int * fd)
void sane_get_select_fd_impl(SANE_Handle handle, SANE_Int* fd)
{
DBG_HELPER_ARGS(dbg, "handle = %p, fd = %p", handle, reinterpret_cast<void*>(fd));
Genesys_Scanner *s = (Genesys_Scanner*) handle;
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
if (!s->scanning)
{
DBG(DBG_error, "%s: not scanning\n", __func__);
return SANE_STATUS_INVAL;
if (!s->scanning) {
throw SaneException("not scanning");
}
return SANE_STATUS_UNSUPPORTED;
throw SaneException(SANE_STATUS_UNSUPPORTED);
}
extern "C" 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);
sane_get_select_fd_impl(handle, fd);
});
}

Wyświetl plik

@ -2660,4 +2660,15 @@ void debug_dump(unsigned level, const Genesys_Sensor& sensor)
DBG(level, " gamma.blue : %f\n", sensor.gamma[2]);
}
void debug_dump(unsigned level, const SANE_Parameters& params)
{
DBG(level, "params:\n");
DBG(level, " format: %d:\n", static_cast<unsigned>(params.format));
DBG(level, " last_frame: %d:\n", params.last_frame);
DBG(level, " bytes_per_line: %d:\n", params.bytes_per_line);
DBG(level, " pixels_per_line: %d:\n", params.pixels_per_line);
DBG(level, " lines: %d:\n", params.lines);
DBG(level, " depth: %d:\n", params.depth);
}
} // namespace genesys

Wyświetl plik

@ -620,6 +620,7 @@ void debug_dump(unsigned level, const Genesys_Current_Setup& setup);
void debug_dump(unsigned level, const Genesys_Register_Set& regs);
void debug_dump(unsigned level, const GenesysRegisterSettingSet& regs);
void debug_dump(unsigned level, const Genesys_Sensor& sensor);
void debug_dump(unsigned level, const SANE_Parameters& params);
} // namespace genesys