X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2Fclasses.cpp;h=af10e8eaf7693e04b05206344c440ebb48e7809b;hb=2c3c9b999cd5c1130afeeee4094400592c9e1bde;hp=3298ce34d0cb1549f7420e8c2b8de547f67e792a;hpb=1b40fdb88108699cf9d912f3d7aadffb4dc04050;p=libsigrok.git diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 3298ce34..af10e8ea 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -17,7 +17,13 @@ * along with this program. If not, see . */ -#include "libsigrok/libsigrokcxx.hpp" +/* Needed for isascii(), as used in the GNU libstdc++ headers */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#include +#include #include #include @@ -66,6 +72,50 @@ Error::~Error() throw() { } +ResourceReader::~ResourceReader() +{ +} + +SR_PRIV int ResourceReader::open_callback(struct sr_resource *res, + const char *name, void *cb_data) +{ + try { + auto *const reader = static_cast(cb_data); + reader->open(res, name); + } catch (const Error &err) { + return err.result; + } catch (...) { + return SR_ERR; + } + return SR_OK; +} + +SR_PRIV int ResourceReader::close_callback(struct sr_resource *res, void *cb_data) +{ + try { + auto *const reader = static_cast(cb_data); + reader->close(res); + } catch (const Error &err) { + return err.result; + } catch (...) { + return SR_ERR; + } + return SR_OK; +} + +SR_PRIV ssize_t ResourceReader::read_callback(const struct sr_resource *res, + void *buf, size_t count, void *cb_data) +{ + try { + auto *const reader = static_cast(cb_data); + return reader->read(res, buf, count); + } catch (const Error &err) { + return err.result; + } catch (...) { + return SR_ERR; + } +} + shared_ptr Context::create() { return shared_ptr(new Context(), Context::Deleter()); @@ -77,7 +127,7 @@ Context::Context() : { check(sr_init(&_structure)); - struct sr_dev_driver **driver_list = sr_driver_list(); + struct sr_dev_driver **driver_list = sr_driver_list(_structure); if (driver_list) for (int i = 0; driver_list[i]; i++) _drivers[driver_list[i]->name] = @@ -161,16 +211,6 @@ void Context::set_log_level(const LogLevel *level) check(sr_log_loglevel_set(level->id())); } -string Context::log_domain() -{ - return valid_string(sr_log_logdomain_get()); -} - -void Context::set_log_domain(string value) -{ - check(sr_log_logdomain_set(value.c_str())); -} - static int call_log_callback(void *cb_data, int loglevel, const char *format, va_list args) { va_list args_copy; @@ -200,13 +240,26 @@ void Context::set_log_callback(LogCallbackFunction callback) { _log_callback = callback; check(sr_log_callback_set(call_log_callback, &_log_callback)); -} +} void Context::set_log_callback_default() { check(sr_log_callback_set_default()); _log_callback = nullptr; -} +} + +void Context::set_resource_reader(ResourceReader *reader) +{ + if (reader) { + check(sr_resource_set_hooks(_structure, + &ResourceReader::open_callback, + &ResourceReader::close_callback, + &ResourceReader::read_callback, reader)); + } else { + check(sr_resource_set_hooks(_structure, + nullptr, nullptr, nullptr, nullptr)); + } +} shared_ptr Context::create_session() { @@ -652,8 +705,7 @@ string Channel::name() void Channel::set_name(string name) { - check(sr_dev_channel_name_set(_parent->_structure, - _structure->index, name.c_str())); + check(sr_dev_channel_name_set(_structure, name.c_str())); } const ChannelType *Channel::type() @@ -668,7 +720,7 @@ bool Channel::enabled() void Channel::set_enabled(bool value) { - check(sr_dev_channel_enable(_parent->_structure, _structure->index, value)); + check(sr_dev_channel_enable(_structure, value)); } unsigned int Channel::index() @@ -820,55 +872,6 @@ void DatafeedCallbackData::run(const struct sr_dev_inst *sdi, _callback(device, packet); } -SourceCallbackData::SourceCallbackData(shared_ptr source) : - _source(source) -{ -} - -bool SourceCallbackData::run(int revents) -{ - return _source->_callback((Glib::IOCondition) revents); -} - -shared_ptr EventSource::create(int fd, Glib::IOCondition events, - int timeout, SourceCallbackFunction callback) -{ - auto result = new EventSource(timeout, callback); - result->_type = EventSource::SOURCE_FD; - result->_fd = fd; - result->_events = events; - return shared_ptr(result, EventSource::Deleter()); -} - -shared_ptr EventSource::create(Glib::PollFD pollfd, int timeout, - SourceCallbackFunction callback) -{ - auto result = new EventSource(timeout, callback); - result->_type = EventSource::SOURCE_POLLFD; - result->_pollfd = pollfd; - return shared_ptr(result, EventSource::Deleter()); -} - -shared_ptr EventSource::create(Glib::RefPtr channel, - Glib::IOCondition events, int timeout, SourceCallbackFunction callback) -{ - auto result = new EventSource(timeout, callback); - result->_type = EventSource::SOURCE_IOCHANNEL; - result->_channel = channel; - result->_events = events; - return shared_ptr(result, EventSource::Deleter()); -} - -EventSource::EventSource(int timeout, SourceCallbackFunction callback) : - _timeout(timeout), - _callback(callback) -{ -} - -EventSource::~EventSource() -{ -} - SessionDevice::SessionDevice(struct sr_dev_inst *structure) : ParentOwned(structure), Device(structure) @@ -886,20 +889,18 @@ shared_ptr SessionDevice::get_shared_from_this() Session::Session(shared_ptr context) : UserOwned(_structure), - _context(context), - _saving(false) + _context(context) { - check(sr_session_new(&_structure)); + check(sr_session_new(context->_structure, &_structure)); _context->_session = this; } Session::Session(shared_ptr context, string filename) : UserOwned(_structure), _context(context), - _filename(filename), - _saving(false) + _filename(filename) { - check(sr_session_load(filename.c_str(), &_structure)); + check(sr_session_load(context->_structure, filename.c_str(), &_structure)); GSList *dev_list; check(sr_session_dev_list(_structure, &dev_list)); for (GSList *dev = dev_list; dev; dev = dev->next) @@ -917,9 +918,6 @@ Session::~Session() for (auto callback : _datafeed_callbacks) delete callback; - for (auto entry : _source_callbacks) - delete entry.second; - for (auto entry : _owned_devices) delete entry.second; } @@ -975,91 +973,29 @@ void Session::stop() check(sr_session_stop(_structure)); } -void Session::begin_save(string filename) +bool Session::is_running() const { - _saving = true; - _save_initialized = false; - _save_filename = filename; - _save_samplerate = 0; + const int ret = sr_session_is_running(_structure); + if (ret < 0) + throw Error{ret}; + return (ret != 0); } -void Session::append(shared_ptr packet) +static void session_stopped_callback(void *data) { - if (!_saving) - throw Error(SR_ERR); - - switch (packet->_structure->type) - { - case SR_DF_META: - { - auto meta = (const struct sr_datafeed_meta *) - packet->_structure->payload; - - for (auto l = meta->config; l; l = l->next) - { - auto config = (struct sr_config *) l->data; - if (config->key == SR_CONF_SAMPLERATE) - _save_samplerate = g_variant_get_uint64(config->data); - } - - break; - } - case SR_DF_LOGIC: - { - if (_save_samplerate == 0) - { - GVariant *samplerate; - - check(sr_config_get(sr_dev_inst_driver_get(packet->_device->_structure), - packet->_device->_structure, NULL, SR_CONF_SAMPLERATE, - &samplerate)); - - _save_samplerate = g_variant_get_uint64(samplerate); - - g_variant_unref(samplerate); - } - - if (!_save_initialized) - { - vector> save_channels; - - for (auto channel : packet->_device->channels()) - if (channel->_structure->enabled && - channel->_structure->type == SR_CHANNEL_LOGIC) - save_channels.push_back(channel); - - auto channels = g_new(char *, save_channels.size()); - - int i = 0; - for (auto channel : save_channels) - channels[i++] = channel->_structure->name; - channels[i] = NULL; - - int ret = sr_session_save_init(_structure, _save_filename.c_str(), - _save_samplerate, channels); - - g_free(channels); - - if (ret != SR_OK) - throw Error(ret); - - _save_initialized = true; - } - - auto logic = (const struct sr_datafeed_logic *) - packet->_structure->payload; - - check(sr_session_append(_structure, _save_filename.c_str(), - (uint8_t *) logic->data, logic->unitsize, - logic->length / logic->unitsize)); - } - } + auto *const callback = static_cast(data); + (*callback)(); } -void Session::append(void *data, size_t length, unsigned int unit_size) +void Session::set_stopped_callback(SessionStoppedCallback callback) { - check(sr_session_append(_structure, _save_filename.c_str(), - (uint8_t *) data, unit_size, length)); + _stopped_callback = move(callback); + if (_stopped_callback) + check(sr_session_stopped_callback_set(_structure, + &session_stopped_callback, &_stopped_callback)); + else + check(sr_session_stopped_callback_set(_structure, + nullptr, nullptr)); } static void datafeed_callback(const struct sr_dev_inst *sdi, @@ -1085,66 +1021,6 @@ void Session::remove_datafeed_callbacks(void) _datafeed_callbacks.clear(); } -static int source_callback(int fd, int revents, void *cb_data) -{ - (void) fd; - auto callback = (SourceCallbackData *) cb_data; - return callback->run(revents); -} - -void Session::add_source(shared_ptr source) -{ - if (_source_callbacks.count(source) == 1) - throw Error(SR_ERR_ARG); - - auto cb_data = new SourceCallbackData(source); - - switch (source->_type) - { - case EventSource::SOURCE_FD: - check(sr_session_source_add(_structure, source->_fd, source->_events, - source->_timeout, source_callback, cb_data)); - break; - case EventSource::SOURCE_POLLFD: - check(sr_session_source_add_pollfd(_structure, - source->_pollfd.gobj(), source->_timeout, source_callback, - cb_data)); - break; - case EventSource::SOURCE_IOCHANNEL: - check(sr_session_source_add_channel(_structure, - source->_channel->gobj(), source->_events, source->_timeout, - source_callback, cb_data)); - break; - } - - _source_callbacks[source] = cb_data; -} - -void Session::remove_source(shared_ptr source) -{ - if (_source_callbacks.count(source) == 0) - throw Error(SR_ERR_ARG); - - switch (source->_type) - { - case EventSource::SOURCE_FD: - check(sr_session_source_remove(_structure, source->_fd)); - break; - case EventSource::SOURCE_POLLFD: - check(sr_session_source_remove_pollfd(_structure, - source->_pollfd.gobj())); - break; - case EventSource::SOURCE_IOCHANNEL: - check(sr_session_source_remove_channel(_structure, - source->_channel->gobj())); - break; - } - - delete _source_callbacks[source]; - - _source_callbacks.erase(source); -} - shared_ptr Session::trigger() { return _trigger; @@ -1385,15 +1261,27 @@ string InputFormat::description() return valid_string(sr_input_description_get(_structure)); } +vector InputFormat::extensions() +{ + vector exts; + for (const char *const *e = sr_input_extensions_get(_structure); + e && *e; e++) + exts.push_back(*e); + return exts; +} + map> InputFormat::options() { const struct sr_option **options = sr_input_options_get(_structure); - auto option_array = shared_ptr( - options, sr_input_options_free); map> result; - for (int i = 0; options[i]; i++) - result[options[i]->id] = shared_ptr