From: Martin Ling Date: Mon, 2 Nov 2015 22:05:02 +0000 (+0000) Subject: bindings: New configuration enumeration API. X-Git-Tag: libsigrok-0.4.0~51 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=36bb818d6f10ac1187f160f4c2ab1169aeb4e86f;p=libsigrok.git bindings: New configuration enumeration API. The new methods wrap the new libsigrok C API helper functions and eliminate the need to pass complex types back to the user and wrap them with SWIG. Fixes bugs #479 and #480. --- diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 49c75580..15b94a19 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -406,6 +406,16 @@ string Driver::long_name() const return valid_string(_structure->longname); } +set Driver::scan_options() const +{ + GArray *opts = sr_driver_scan_options(_structure); + set result; + for (guint i = 0; i < opts->len; i++) + result.insert(ConfigKey::get(g_array_index(opts, uint32_t, i))); + g_array_free(opts, TRUE); + return result; +} + vector> Driver::scan( map options) { @@ -466,6 +476,21 @@ Configurable::~Configurable() { } +set Configurable::config_keys() const +{ + GArray *opts; + set result; + + opts = sr_dev_options(config_driver, config_sdi, config_channel_group); + + for (guint i = 0; i < opts->len; i++) + result.insert(ConfigKey::get(g_array_index(opts, uint32_t, i))); + + g_array_free(opts, TRUE); + + return result; +} + Glib::VariantBase Configurable::config_get(const ConfigKey *key) const { GVariant *data; @@ -482,73 +507,36 @@ void Configurable::config_set(const ConfigKey *key, const Glib::VariantBase &val key->id(), const_cast(value.gobj()))); } -Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const +set Configurable::config_capabilities(const ConfigKey *key) const { - GVariant *data; - check(sr_config_list( - config_driver, config_sdi, config_channel_group, - key->id(), &data)); - return Glib::VariantContainerBase(data); -} + int caps = sr_dev_config_capabilities(config_sdi, config_channel_group, + key->id()); -map> Configurable::config_keys(const ConfigKey *key) -{ - GVariant *gvar_opts; - gsize num_opts; - const uint32_t *opts; - map> result; + set result; - check(sr_config_list( - config_driver, config_sdi, config_channel_group, - key->id(), &gvar_opts)); - - opts = static_cast(g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(uint32_t))); - - for (gsize i = 0; i < num_opts; i++) - { - auto key = ConfigKey::get(opts[i] & SR_CONF_MASK); - set capabilities; - if (opts[i] & SR_CONF_GET) - capabilities.insert(Capability::GET); - if (opts[i] & SR_CONF_SET) - capabilities.insert(Capability::SET); - if (opts[i] & SR_CONF_LIST) - capabilities.insert(Capability::LIST); - result[key] = capabilities; - } - - g_variant_unref(gvar_opts); + for (auto cap: Capability::values()) + if (caps & cap->id()) + result.insert(cap); return result; } bool Configurable::config_check(const ConfigKey *key, - const ConfigKey *index_key) const + const Capability *capability) const { - GVariant *gvar_opts; - gsize num_opts; - const uint32_t *opts; - - if (sr_config_list(config_driver, config_sdi, config_channel_group, - index_key->id(), &gvar_opts) != SR_OK) - return false; - - opts = static_cast(g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(uint32_t))); - - for (gsize i = 0; i < num_opts; i++) - { - if ((opts[i] & SR_CONF_MASK) == unsigned(key->id())) - { - g_variant_unref(gvar_opts); - return true; - } - } + int caps = sr_dev_config_capabilities(config_sdi, config_channel_group, + key->id()); - g_variant_unref(gvar_opts); + return (caps & capability->id()); +} - return false; +Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const +{ + GVariant *data; + check(sr_config_list( + config_driver, config_sdi, config_channel_group, + key->id(), &data)); + return Glib::VariantContainerBase(data); } Device::Device(struct sr_dev_inst *structure) : diff --git a/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp b/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp index da2a286e..1db6c7df 100644 --- a/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp +++ b/bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp @@ -315,6 +315,8 @@ private: class SR_API Configurable { public: + /** Supported configuration keys. */ + set config_keys() const; /** Read configuration for the given key. * @param key ConfigKey to read. */ Glib::VariantBase config_get(const ConfigKey *key) const; @@ -325,10 +327,13 @@ public: /** Enumerate available values for the given configuration key. * @param key ConfigKey to enumerate values for. */ Glib::VariantContainerBase config_list(const ConfigKey *key) const; - /** Enumerate available keys, according to a given index key. */ - map > config_keys(const ConfigKey *key); - /** Check for a key in the list from a given index key. */ - bool config_check(const ConfigKey *key, const ConfigKey *index_key) const; + /** Enumerate configuration capabilities for the given configuration key. + * @param key ConfigKey to enumerate capabilities for. */ + set config_capabilities(const ConfigKey *key) const; + /** Check whether a configuration capability is supported for a given key. + * @param key ConfigKey to check. + * @param capability Capability to check for. */ + bool config_check(const ConfigKey *key, const Capability *capability) const; protected: Configurable( struct sr_dev_driver *driver, @@ -341,15 +346,15 @@ protected: }; /** A hardware driver provided by the library */ -class SR_API Driver : - public ParentOwned, - public Configurable +class SR_API Driver : public ParentOwned, public Configurable { public: /** Name of this driver. */ string name() const; /** Long name for this driver. */ string long_name() const; + /** Scan options supported by this driver. */ + set scan_options() const; /** Scan for devices and return a list of devices found. * @param options Mapping of (ConfigKey, value) pairs. */ vector > scan(map diff --git a/bindings/java/org/sigrok/core/classes/classes.i b/bindings/java/org/sigrok/core/classes/classes.i index 1b303464..129654d9 100644 --- a/bindings/java/org/sigrok/core/classes/classes.i +++ b/bindings/java/org/sigrok/core/classes/classes.i @@ -193,42 +193,6 @@ MAP_COMMON(const sigrok::ConfigKey *, Glib::VariantBase, ConfigKey, Variant) } } -/* Specialisation for ConfigKey->set maps */ - -MAP_COMMON(const sigrok::ConfigKey *, std::set, - ConfigKey, java.util.Set) - -%typemap(jni) std::map > "jobject" -%typemap(jtype) std::map > - "java.util.Map>" - -%typemap(out) std::map > { - jclass HashMap = jenv->FindClass("java/util/HashMap"); - jmethodID HashMap_init = jenv->GetMethodID(HashMap, "", "()V"); - jmethodID HashMap_put = jenv->GetMethodID(HashMap, "put", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - jclass HashSet = jenv->FindClass("java/util/HashSet"); - jmethodID HashSet_init = jenv->GetMethodID(HashSet, "", "()V"); - jmethodID HashSet_add = jenv->GetMethodID(HashSet, "add", - "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - jclass ConfigKey = jenv->FindClass("org/sigrok/core/classes/ConfigKey"); - jmethodID ConfigKey_init = jenv->GetMethodID(ConfigKey, "", "(JZ)V"); - jclass Capability = jenv->FindClass("org/sigrok/core/classes/Capability"); - jmethodID Capability_init = jenv->GetMethodID(Capability, "", "(JZ)V"); - $result = jenv->NewObject(HashMap, HashMap_init); - jlong key = 0; - for (auto map_entry : $1) - { - *(const sigrok::ConfigKey **) &key = map_entry.first; - jobject value = jenv->NewObject(HashSet, HashSet_init); - for (auto &set_entry : map_entry.second) - jenv->CallObjectMethod(value, HashSet_add, - jenv->NewObject(Capability, Capability_init, set_entry)); - jenv->CallObjectMethod($result, HashMap_put, - jenv->NewObject(ConfigKey, ConfigKey_init, key, false), value); - } -} - /* Pass JNIEnv parameter to C++ extension methods requiring it. */ %typemap(in, numinputs=0) JNIEnv * %{ diff --git a/bindings/swig/templates.i b/bindings/swig/templates.i index f160866d..1baaf0fe 100644 --- a/bindings/swig/templates.i +++ b/bindings/swig/templates.i @@ -60,20 +60,22 @@ namespace std { for the map instantiation from compiling. */ %template(ConfigVector) std::vector; + %template(ConfigMap) std::map; -/* Currently broken on Python. */ -#ifndef SWIGPYTHON +%template(ConfigSet) + std::set; + +/* Workaround for SWIG bug. The vector template instantiation + isn't needed but somehow fixes a bug that stops the wrapper + for the set instantiation from compiling. */ +%template(CapabilityVector) + std::vector; %template(CapabilitySet) std::set; -%template(ConfigKeys) - std::map >; - -#endif - %template(OptionVector) std::vector >; %template(OptionMap)