X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2Fclasses.cpp;h=986b2c1e1da3fe60daa96ffbb0b15f9d71434f6d;hb=ca3291e3ee7415c4c4505164ec931b91ea15cefe;hp=285025be356675ee27e5b3b03558a20e24790ff2;hpb=1797a887d7672caa1e0fc1ff87a26de2370a8381;p=libsigrok.git diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 285025be..986b2c1e 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -19,6 +19,8 @@ #include "libsigrok/libsigrok.hpp" +#include + namespace sigrok { @@ -38,16 +40,16 @@ static const char *valid_string(const char *input) return ""; } -/** Helper function to convert between map and GHashTable */ - -static GHashTable *map_to_hash(map input) +/** Helper function to convert between map and GHashTable */ +static GHashTable *map_to_hash_variant(map input) { auto output = g_hash_table_new_full( - g_str_hash, g_str_equal, g_free, g_free); + g_variant_hash, g_variant_equal, g_free, + (void (*)(void *))g_variant_unref); for (auto entry : input) g_hash_table_insert(output, g_strdup(entry.first.c_str()), - g_strdup(entry.second.c_str())); + entry.second.gobj_copy()); return output; } @@ -78,15 +80,15 @@ Context::Context() : for (int i = 0; driver_list[i]; i++) drivers[driver_list[i]->name] = new Driver(driver_list[i]); - struct sr_input_format **input_list = sr_input_list(); + const struct sr_input_module **input_list = sr_input_list(); if (input_list) for (int i = 0; input_list[i]; i++) - input_formats[input_list[i]->id] = + input_formats[sr_input_id_get(input_list[i])] = new InputFormat(input_list[i]); - struct sr_output_format **output_list = sr_output_list(); + const struct sr_output_module **output_list = sr_output_list(); if (output_list) for (int i = 0; output_list[i]; i++) - output_formats[output_list[i]->id] = + output_formats[sr_output_id_get(output_list[i])] = new OutputFormat(output_list[i]); } @@ -225,6 +227,26 @@ shared_ptr Context::create_trigger(string name) new Trigger(shared_from_this(), name), Trigger::Deleter()); } +shared_ptr Context::open_file(string filename) +{ + auto input = sr_input_scan_file(filename.c_str()); + if (!input) + throw Error(SR_ERR_NA); + return shared_ptr( + new Input(shared_from_this(), input), Input::Deleter()); +} + +shared_ptr Context::open_stream(string header) +{ + auto gstr = g_string_new(header.c_str()); + auto input = sr_input_scan_buffer(gstr); + g_string_free(gstr, false); + if (!input) + throw Error(SR_ERR_NA); + return shared_ptr( + new Input(shared_from_this(), input), Input::Deleter()); +} + Driver::Driver(struct sr_dev_driver *structure) : StructureWrapper(structure), initialized(false) @@ -328,13 +350,13 @@ void Configurable::config_set(const ConfigKey *key, Glib::VariantBase value) key->get_id(), value.gobj())); } -Glib::VariantBase Configurable::config_list(const ConfigKey *key) +Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) { GVariant *data; check(sr_config_list( config_driver, config_sdi, config_channel_group, key->get_id(), &data)); - return Glib::VariantBase(data); + return Glib::VariantContainerBase(data); } Device::Device(struct sr_dev_inst *structure) : @@ -346,12 +368,34 @@ Device::Device(struct sr_dev_inst *structure) : auto channel = (struct sr_channel *) entry->data; channels[channel] = new Channel(channel); } + + for (GSList *entry = structure->channel_groups; entry; entry = entry->next) + { + auto group = (struct sr_channel_group *) entry->data; + channel_groups[group->name] = new ChannelGroup(this, group); + } } Device::~Device() { for (auto entry : channels) delete entry.second; + for (auto entry : channel_groups) + delete entry.second; +} + +string Device::get_description() +{ + ostringstream s; + + vector parts = + {get_vendor(), get_model(), get_version()}; + + for (string part : parts) + if (part.length() > 0) + s << part; + + return s.str(); } string Device::get_vendor() @@ -384,6 +428,20 @@ shared_ptr Device::get_channel(struct sr_channel *ptr) channels[ptr]->get_shared_pointer(this)); } +map> +Device::get_channel_groups() +{ + map> result; + for (auto entry: channel_groups) + { + auto name = entry.first; + auto channel_group = entry.second; + result[name] = static_pointer_cast( + channel_group->get_shared_pointer(this)); + } + return result; +} + void Device::open() { check(sr_dev_open(structure)); @@ -398,17 +456,10 @@ HardwareDevice::HardwareDevice(Driver *driver, struct sr_dev_inst *structure) : Device(structure), driver(driver) { - for (GSList *entry = structure->channel_groups; entry; entry = entry->next) - { - auto group = (struct sr_channel_group *) entry->data; - channel_groups[group->name] = new ChannelGroup(this, group); - } } HardwareDevice::~HardwareDevice() { - for (auto entry : channel_groups) - delete entry.second; } shared_ptr HardwareDevice::get_driver() @@ -416,20 +467,6 @@ shared_ptr HardwareDevice::get_driver() return static_pointer_cast(driver->get_shared_pointer(parent)); } -map> -HardwareDevice::get_channel_groups() -{ - map> result; - for (auto entry: channel_groups) - { - auto name = entry.first; - auto channel_group = entry.second; - result[name] = static_pointer_cast( - channel_group->get_shared_pointer(this)); - } - return result; -} - Channel::Channel(struct sr_channel *structure) : StructureWrapper(structure), type(ChannelType::get(structure->type)) @@ -465,9 +502,14 @@ void Channel::set_enabled(bool value) check(sr_dev_channel_enable(parent->structure, structure->index, value)); } -ChannelGroup::ChannelGroup(HardwareDevice *device, +unsigned int Channel::get_index() +{ + return structure->index; +} + +ChannelGroup::ChannelGroup(Device *device, struct sr_channel_group *structure) : - StructureWrapper(structure), + StructureWrapper(structure), Configurable(device->structure->driver, device->structure, structure) { for (GSList *entry = structure->channels; entry; entry = entry->next) @@ -600,7 +642,7 @@ void DatafeedCallbackData::run(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *pkt) { auto device = session->devices[sdi]; - auto packet = shared_ptr(new Packet(pkt), Packet::Deleter()); + auto packet = shared_ptr(new Packet(device, pkt), Packet::Deleter()); callback(device, packet); } @@ -728,7 +770,7 @@ void Session::begin_save(string filename) save_samplerate = 0; } -void Session::append(shared_ptr device, shared_ptr packet) +void Session::append(shared_ptr packet) { if (!saving) throw Error(SR_ERR); @@ -755,8 +797,9 @@ void Session::append(shared_ptr device, shared_ptr packet) { GVariant *samplerate; - check(sr_config_get(device->structure->driver, - device->structure, NULL, SR_CONF_SAMPLERATE, &samplerate)); + check(sr_config_get(packet->device->structure->driver, + packet->device->structure, NULL, SR_CONF_SAMPLERATE, + &samplerate)); save_samplerate = g_variant_get_uint64(samplerate); @@ -767,7 +810,7 @@ void Session::append(shared_ptr device, shared_ptr packet) { vector> save_channels; - for (auto channel : device->get_channels()) + for (auto channel : packet->device->get_channels()) if (channel->structure->enabled && channel->structure->type == SR_CHANNEL_LOGIC) save_channels.push_back(channel); @@ -800,6 +843,12 @@ void Session::append(shared_ptr device, shared_ptr packet) } } +void Session::append(void *data, size_t length, unsigned int unit_size) +{ + check(sr_session_append(structure, save_filename.c_str(), + (uint8_t *) data, unit_size, length)); +} + static void datafeed_callback(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *pkt, void *cb_data) { @@ -893,11 +942,23 @@ void Session::set_trigger(shared_ptr trigger) this->trigger = trigger; } -Packet::Packet(const struct sr_datafeed_packet *structure) : - structure(structure) +Packet::Packet(shared_ptr device, + const struct sr_datafeed_packet *structure) : + structure(structure), + device(device) { switch (structure->type) { + case SR_DF_HEADER: + payload = new Header( + static_cast( + structure->payload)); + break; + case SR_DF_META: + payload = new Meta( + static_cast( + structure->payload)); + break; case SR_DF_LOGIC: payload = new Logic( static_cast( @@ -908,9 +969,6 @@ Packet::Packet(const struct sr_datafeed_packet *structure) : static_cast( structure->payload)); break; - default: - payload = NULL; - break; } } @@ -925,9 +983,9 @@ const PacketType *Packet::get_type() return PacketType::get(structure->type); } -PacketPayload *Packet::get_payload() +shared_ptr Packet::get_payload() { - return payload; + return payload->get_shared_pointer(this); } PacketPayload::PacketPayload() @@ -938,28 +996,77 @@ PacketPayload::~PacketPayload() { } -Logic::Logic(const struct sr_datafeed_logic *structure) : PacketPayload(), - structure(structure), - data(static_cast(structure->data), - static_cast(structure->data) + structure->length) {} +Header::Header(const struct sr_datafeed_header *structure) : + PacketPayload(), + StructureWrapper(structure) +{ +} + +Header::~Header() +{ +} + +int Header::get_feed_version() +{ + return structure->feed_version; +} + +Glib::TimeVal Header::get_start_time() +{ + return Glib::TimeVal( + structure->starttime.tv_sec, + structure->starttime.tv_usec); +} + +Meta::Meta(const struct sr_datafeed_meta *structure) : + PacketPayload(), + StructureWrapper(structure) +{ +} + +Meta::~Meta() +{ +} + +map Meta::get_config() +{ + map result; + for (auto l = structure->config; l; l = l->next) + { + auto config = (struct sr_config *) l->data; + result[ConfigKey::get(config->key)] = Glib::VariantBase(config->data); + } + return result; +} + +Logic::Logic(const struct sr_datafeed_logic *structure) : + PacketPayload(), + StructureWrapper(structure) +{ +} Logic::~Logic() { } -void *Logic::get_data() +void *Logic::get_data_pointer() { return structure->data; } -size_t Logic::get_data_size() +size_t Logic::get_data_length() { return structure->length; } +unsigned int Logic::get_unit_size() +{ + return structure->unitsize; +} + Analog::Analog(const struct sr_datafeed_analog *structure) : PacketPayload(), - structure(structure) + StructureWrapper(structure) { } @@ -967,19 +1074,23 @@ Analog::~Analog() { } -void *Analog::get_data() +float *Analog::get_data_pointer() { return structure->data; } -size_t Analog::get_data_size() +unsigned int Analog::get_num_samples() { - return structure->num_samples * sizeof(float); + return structure->num_samples; } -unsigned int Analog::get_num_samples() +vector> Analog::get_channels() { - return structure->num_samples; + vector> result; + for (auto l = structure->channels; l; l = l->next) + result.push_back(parent->device->get_channel( + (struct sr_channel *)l->data)); + return result; } const Quantity *Analog::get_mq() @@ -997,8 +1108,8 @@ vector Analog::get_mq_flags() return QuantityFlag::flags_from_mask(structure->mqflags); } -InputFormat::InputFormat(struct sr_input_format *structure) : - StructureWrapper(structure) +InputFormat::InputFormat(const struct sr_input_module *structure) : + StructureWrapper(structure) { } @@ -1008,56 +1119,111 @@ InputFormat::~InputFormat() string InputFormat::get_name() { - return valid_string(structure->id); + return valid_string(sr_input_id_get(structure)); } string InputFormat::get_description() { - return valid_string(structure->description); + return valid_string(sr_input_description_get(structure)); +} + +shared_ptr InputFormat::create_input( + map options) +{ + auto input = sr_input_new(structure, map_to_hash_variant(options)); + if (!input) + throw Error(SR_ERR_ARG); + return shared_ptr( + new Input(parent->shared_from_this(), input), Input::Deleter()); } -bool InputFormat::format_match(string filename) +Input::Input(shared_ptr context, const struct sr_input *structure) : + structure(structure), + context(context), + device(nullptr) { - return structure->format_match(filename.c_str()); } -shared_ptr InputFormat::open_file(string filename, - map options) +shared_ptr Input::get_device() { - auto input = g_new(struct sr_input, 1); - input->param = map_to_hash(options); + if (!device) + { + auto sdi = sr_input_dev_inst_get(structure); + if (!sdi) + throw Error(SR_ERR_NA); + device = new InputDevice(shared_from_this(), sdi); + } - /** Run initialisation. */ - check(structure->init(input, filename.c_str())); + return static_pointer_cast( + device->get_shared_pointer(context->shared_from_this())); +} - /** Create virtual device. */ - return shared_ptr(new InputFileDevice( - static_pointer_cast(shared_from_this()), input, filename), - InputFileDevice::Deleter()); +void Input::send(string data) +{ + auto gstr = g_string_new(data.c_str()); + auto ret = sr_input_send(structure, gstr); + g_string_free(gstr, false); + check(ret); } -InputFileDevice::InputFileDevice(shared_ptr format, - struct sr_input *input, string filename) : - Device(input->sdi), - input(input), - format(format), - filename(filename) +Input::~Input() { + if (device) + delete device; + check(sr_input_free(structure)); } -InputFileDevice::~InputFileDevice() +InputDevice::InputDevice(shared_ptr input, struct sr_dev_inst *sdi) : + Device(sdi), + input(input) { - g_hash_table_unref(input->param); - g_free(input); } -void InputFileDevice::load() +InputDevice::~InputDevice() { - check(format->structure->loadfile(input, filename.c_str())); } -OutputFormat::OutputFormat(struct sr_output_format *structure) : - StructureWrapper(structure) +Option::Option(const struct sr_option *structure, + shared_ptr structure_array) : + structure(structure), + structure_array(structure_array) +{ +} + +Option::~Option() +{ +} + +string Option::get_id() +{ + return valid_string(structure->id); +} + +string Option::get_name() +{ + return valid_string(structure->name); +} + +string Option::get_description() +{ + return valid_string(structure->desc); +} + +Glib::VariantBase Option::get_default_value() +{ + return Glib::VariantBase(structure->def, true); +} + +vector Option::get_values() +{ + vector result; + for (auto l = structure->values; l; l = l->next) + result.push_back(Glib::VariantBase((GVariant *) l->data, true)); + return result; +} + +OutputFormat::OutputFormat(const struct sr_output_module *structure) : + StructureWrapper(structure) { } @@ -1067,16 +1233,28 @@ OutputFormat::~OutputFormat() string OutputFormat::get_name() { - return valid_string(structure->id); + return valid_string(sr_output_id_get(structure)); } string OutputFormat::get_description() { - return valid_string(structure->description); + return valid_string(sr_output_description_get(structure)); +} + +map> OutputFormat::get_options() +{ + const struct sr_option **options = sr_output_options_get(structure); + auto option_array = shared_ptr( + options, sr_output_options_free); + map> result; + for (int i = 0; options[i]; i++) + result[options[i]->id] = shared_ptr