From: Martin Ling Date: Sun, 24 Aug 2014 00:40:19 +0000 (+0100) Subject: Update bindings for new input API. X-Git-Tag: libsigrok-0.4.0~1098 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=ca3291e3ee7415c4c4505164ec931b91ea15cefe;p=libsigrok.git Update bindings for new input API. --- diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 8e5874ca..986b2c1e 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -40,18 +40,6 @@ static const char *valid_string(const char *input) return ""; } -/** Helper function to convert between map and GHashTable */ -static GHashTable *map_to_hash_string(map input) -{ - auto output = g_hash_table_new_full( - g_str_hash, g_str_equal, g_free, g_free); - for (auto entry : input) - g_hash_table_insert(output, - g_strdup(entry.first.c_str()), - g_strdup(entry.second.c_str())); - return output; -} - /** Helper function to convert between map and GHashTable */ static GHashTable *map_to_hash_variant(map input) { @@ -92,10 +80,10 @@ 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]); const struct sr_output_module **output_list = sr_output_list(); if (output_list) @@ -239,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) @@ -1100,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) { } @@ -1111,52 +1119,68 @@ 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_string(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())); } Option::Option(const struct sr_option *structure, diff --git a/bindings/cxx/include/libsigrok/libsigrok.hpp b/bindings/cxx/include/libsigrok/libsigrok.hpp index ad683218..546a4502 100644 --- a/bindings/cxx/include/libsigrok/libsigrok.hpp +++ b/bindings/cxx/include/libsigrok/libsigrok.hpp @@ -108,7 +108,8 @@ class SR_API PacketType; class SR_API Quantity; class SR_API Unit; class SR_API QuantityFlag; -class SR_API InputFileDevice; +class SR_API Input; +class SR_API InputDevice; class SR_API Output; class SR_API DataType; class SR_API Option; @@ -214,6 +215,12 @@ public: /** Create a new trigger. * @param name Name string for new trigger. */ shared_ptr create_trigger(string name); + /** Open an input file. + * @param filename File name string. */ + shared_ptr open_file(string filename); + /** Open an input stream based on header data. + * @param header Initial data from stream. */ + shared_ptr open_stream(string header); protected: struct sr_context *structure; map drivers; @@ -724,51 +731,68 @@ protected: /** An input format supported by the library */ class SR_API InputFormat : - public StructureWrapper + public StructureWrapper { public: /** Name of this input format. */ string get_name(); /** Description of this input format. */ string get_description(); - /** Check whether a given file matches this input format. - * @param filename File name string. */ - bool format_match(string filename); - /** Open a file using this input format. - * @param filename File name string. - * @param options Mapping of (option name, value) strings. */ - shared_ptr open_file(string filename, - map options = {}); + /** Options supported by this input format. */ + map > get_options(); + /** Create an input using this input format. + * @param options Mapping of (option name, value) pairs. */ + shared_ptr create_input(map options = {}); protected: - InputFormat(struct sr_input_format *structure); + InputFormat(const struct sr_input_module *structure); ~InputFormat(); friend class Context; - friend class InputFileDevice; + friend class InputDevice; }; -/** A virtual device associated with an input file */ -class SR_API InputFileDevice : public Device +/** An input instance (an input format applied to a file or stream) */ +class SR_API Input : public enable_shared_from_this { public: - /** Load data from file. */ - void load(); + /** Virtual device associated with this input. */ + shared_ptr get_device(); + /** Send next stream data. + * @param data Next stream data. */ + void send(string data); protected: - InputFileDevice(shared_ptr format, - struct sr_input *input, string filename); - ~InputFileDevice(); - struct sr_input *input; - shared_ptr format; - string filename; + Input(shared_ptr context, const struct sr_input *structure); + ~Input(); + const struct sr_input *structure; + shared_ptr context; + InputDevice *device; /** Deleter needed to allow shared_ptr use with protected destructor. */ class Deleter { public: - void operator()(InputFileDevice *device) { delete device; } + void operator()(Input *input) { delete input; } }; friend class Deleter; + friend class Context; friend class InputFormat; }; +/** A virtual device associated with an input */ +class SR_API InputDevice : public Device +{ +protected: + InputDevice(shared_ptr input, struct sr_dev_inst *sdi); + ~InputDevice(); + shared_ptr input; + /** Deleter needed to allow shared_ptr use with protected destructor. */ + class Deleter + { + public: + void operator()(InputDevice *device) { delete device; } + }; + friend class Deleter; + friend class Input; +}; + /** An option used by an output format */ class SR_API Option { diff --git a/bindings/java/org/sigrok/core/classes/classes.i b/bindings/java/org/sigrok/core/classes/classes.i index 25e5c387..c7173e4a 100644 --- a/bindings/java/org/sigrok/core/classes/classes.i +++ b/bindings/java/org/sigrok/core/classes/classes.i @@ -224,6 +224,15 @@ MAP_COMMON(const sigrok::ConfigKey *, Glib::VariantBase, ConfigKey, Variant) } } +/* Support InputFormat.create_input() with no options. */ +%extend sigrok::InputFormat { + std::shared_ptr create_input() + { + std::map options; + return $self->create_input(options); + } +} + /* Support OutputFormat.create_output(device) with no options. */ %extend sigrok::OutputFormat { std::shared_ptr create_output( diff --git a/bindings/python/sigrok/core/classes.i b/bindings/python/sigrok/core/classes.i index 015011ea..b7552890 100644 --- a/bindings/python/sigrok/core/classes.i +++ b/bindings/python/sigrok/core/classes.i @@ -354,7 +354,7 @@ std::map dict_to_map_options(PyObject *dict, /* Ignore these methods, we will override them below. */ %ignore sigrok::Driver::scan; -%ignore sigrok::InputFormat::open_file; +%ignore sigrok::InputFormat::create_input; %ignore sigrok::OutputFormat::create_output; %include "doc.i" @@ -394,21 +394,22 @@ std::map dict_to_map_options(PyObject *dict, Driver.scan = _Driver_scan } -/* Support InputFormat.open_file() with keyword arguments. */ +/* Support InputFormat.create_input() with keyword arguments. */ %extend sigrok::InputFormat { - std::shared_ptr _open_file_kwargs(std::string filename, PyObject *dict) + std::shared_ptr _create_input_kwargs(PyObject *dict) { - return $self->open_file(filename, dict_to_map_string(dict)); + return $self->create_input( + dict_to_map_options(dict, $self->get_options())); } } %pythoncode { - def _InputFormat_open_file(self, filename, **kwargs): - return self._open_file_kwargs(filename, kwargs) + def _InputFormat_create_input(self, **kwargs): + return self._create_input(kwargs) - InputFormat.open_file = _InputFormat_open_file + InputFormat.create_input = _InputFormat_create_input } /* Support OutputFormat.create_output() with keyword arguments. */ diff --git a/bindings/swig/classes.i b/bindings/swig/classes.i index fd9da099..cc4aa742 100644 --- a/bindings/swig/classes.i +++ b/bindings/swig/classes.i @@ -75,7 +75,8 @@ template< class T > class enable_shared_from_this; %shared_ptr(sigrok::Analog); %shared_ptr(sigrok::Logic); %shared_ptr(sigrok::InputFormat); -%shared_ptr(sigrok::InputFileDevice); +%shared_ptr(sigrok::Input); +%shared_ptr(sigrok::InputDevice); %shared_ptr(sigrok::Option); %shared_ptr(sigrok::OutputFormat); %shared_ptr(sigrok::Output); @@ -190,6 +191,9 @@ typedef std::map %attributestring(sigrok::InputFormat, std::string, description, get_description); +%attributestring(sigrok::Input, + std::shared_ptr, device, get_device); + %attributestring(sigrok::Option, std::string, id, get_id); %attributestring(sigrok::Option,