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.
This commit is contained in:
parent
8f3168b89b
commit
36bb818d6f
|
@ -406,6 +406,16 @@ string Driver::long_name() const
|
||||||
return valid_string(_structure->longname);
|
return valid_string(_structure->longname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<const ConfigKey *> Driver::scan_options() const
|
||||||
|
{
|
||||||
|
GArray *opts = sr_driver_scan_options(_structure);
|
||||||
|
set<const ConfigKey *> 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<shared_ptr<HardwareDevice>> Driver::scan(
|
vector<shared_ptr<HardwareDevice>> Driver::scan(
|
||||||
map<const ConfigKey *, Glib::VariantBase> options)
|
map<const ConfigKey *, Glib::VariantBase> options)
|
||||||
{
|
{
|
||||||
|
@ -466,6 +476,21 @@ Configurable::~Configurable()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<const ConfigKey *> Configurable::config_keys() const
|
||||||
|
{
|
||||||
|
GArray *opts;
|
||||||
|
set<const ConfigKey *> 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
|
Glib::VariantBase Configurable::config_get(const ConfigKey *key) const
|
||||||
{
|
{
|
||||||
GVariant *data;
|
GVariant *data;
|
||||||
|
@ -482,6 +507,29 @@ void Configurable::config_set(const ConfigKey *key, const Glib::VariantBase &val
|
||||||
key->id(), const_cast<GVariant*>(value.gobj())));
|
key->id(), const_cast<GVariant*>(value.gobj())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<const Capability *> Configurable::config_capabilities(const ConfigKey *key) const
|
||||||
|
{
|
||||||
|
int caps = sr_dev_config_capabilities(config_sdi, config_channel_group,
|
||||||
|
key->id());
|
||||||
|
|
||||||
|
set<const Capability *> result;
|
||||||
|
|
||||||
|
for (auto cap: Capability::values())
|
||||||
|
if (caps & cap->id())
|
||||||
|
result.insert(cap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Configurable::config_check(const ConfigKey *key,
|
||||||
|
const Capability *capability) const
|
||||||
|
{
|
||||||
|
int caps = sr_dev_config_capabilities(config_sdi, config_channel_group,
|
||||||
|
key->id());
|
||||||
|
|
||||||
|
return (caps & capability->id());
|
||||||
|
}
|
||||||
|
|
||||||
Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const
|
Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const
|
||||||
{
|
{
|
||||||
GVariant *data;
|
GVariant *data;
|
||||||
|
@ -491,66 +539,6 @@ Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const
|
||||||
return Glib::VariantContainerBase(data);
|
return Glib::VariantContainerBase(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<const ConfigKey *, set<const Capability *>> Configurable::config_keys(const ConfigKey *key)
|
|
||||||
{
|
|
||||||
GVariant *gvar_opts;
|
|
||||||
gsize num_opts;
|
|
||||||
const uint32_t *opts;
|
|
||||||
map<const ConfigKey *, set<const Capability *>> result;
|
|
||||||
|
|
||||||
check(sr_config_list(
|
|
||||||
config_driver, config_sdi, config_channel_group,
|
|
||||||
key->id(), &gvar_opts));
|
|
||||||
|
|
||||||
opts = static_cast<const uint32_t *>(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<const Capability *> 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);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Configurable::config_check(const ConfigKey *key,
|
|
||||||
const ConfigKey *index_key) 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<const uint32_t *>(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_variant_unref(gvar_opts);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Device::Device(struct sr_dev_inst *structure) :
|
Device::Device(struct sr_dev_inst *structure) :
|
||||||
Configurable(sr_dev_inst_driver_get(structure), structure, nullptr),
|
Configurable(sr_dev_inst_driver_get(structure), structure, nullptr),
|
||||||
_structure(structure)
|
_structure(structure)
|
||||||
|
|
|
@ -315,6 +315,8 @@ private:
|
||||||
class SR_API Configurable
|
class SR_API Configurable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/** Supported configuration keys. */
|
||||||
|
set<const ConfigKey *> config_keys() const;
|
||||||
/** Read configuration for the given key.
|
/** Read configuration for the given key.
|
||||||
* @param key ConfigKey to read. */
|
* @param key ConfigKey to read. */
|
||||||
Glib::VariantBase config_get(const ConfigKey *key) const;
|
Glib::VariantBase config_get(const ConfigKey *key) const;
|
||||||
|
@ -325,10 +327,13 @@ public:
|
||||||
/** Enumerate available values for the given configuration key.
|
/** Enumerate available values for the given configuration key.
|
||||||
* @param key ConfigKey to enumerate values for. */
|
* @param key ConfigKey to enumerate values for. */
|
||||||
Glib::VariantContainerBase config_list(const ConfigKey *key) const;
|
Glib::VariantContainerBase config_list(const ConfigKey *key) const;
|
||||||
/** Enumerate available keys, according to a given index key. */
|
/** Enumerate configuration capabilities for the given configuration key.
|
||||||
map<const ConfigKey *, set<const Capability *> > config_keys(const ConfigKey *key);
|
* @param key ConfigKey to enumerate capabilities for. */
|
||||||
/** Check for a key in the list from a given index key. */
|
set<const Capability *> config_capabilities(const ConfigKey *key) const;
|
||||||
bool config_check(const ConfigKey *key, const ConfigKey *index_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:
|
protected:
|
||||||
Configurable(
|
Configurable(
|
||||||
struct sr_dev_driver *driver,
|
struct sr_dev_driver *driver,
|
||||||
|
@ -341,15 +346,15 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A hardware driver provided by the library */
|
/** A hardware driver provided by the library */
|
||||||
class SR_API Driver :
|
class SR_API Driver : public ParentOwned<Driver, Context>, public Configurable
|
||||||
public ParentOwned<Driver, Context>,
|
|
||||||
public Configurable
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Name of this driver. */
|
/** Name of this driver. */
|
||||||
string name() const;
|
string name() const;
|
||||||
/** Long name for this driver. */
|
/** Long name for this driver. */
|
||||||
string long_name() const;
|
string long_name() const;
|
||||||
|
/** Scan options supported by this driver. */
|
||||||
|
set<const ConfigKey *> scan_options() const;
|
||||||
/** Scan for devices and return a list of devices found.
|
/** Scan for devices and return a list of devices found.
|
||||||
* @param options Mapping of (ConfigKey, value) pairs. */
|
* @param options Mapping of (ConfigKey, value) pairs. */
|
||||||
vector<shared_ptr<HardwareDevice> > scan(map<const ConfigKey *, Glib::VariantBase>
|
vector<shared_ptr<HardwareDevice> > scan(map<const ConfigKey *, Glib::VariantBase>
|
||||||
|
|
|
@ -193,42 +193,6 @@ MAP_COMMON(const sigrok::ConfigKey *, Glib::VariantBase, ConfigKey, Variant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Specialisation for ConfigKey->set<Capability> maps */
|
|
||||||
|
|
||||||
MAP_COMMON(const sigrok::ConfigKey *, std::set<const sigrok::Capability *>,
|
|
||||||
ConfigKey, java.util.Set<Capability>)
|
|
||||||
|
|
||||||
%typemap(jni) std::map<const sigrok::ConfigKey *, std::set<const sigrok::Capability *> > "jobject"
|
|
||||||
%typemap(jtype) std::map<const sigrok::ConfigKey *, std::set<const sigrok::Capability *> >
|
|
||||||
"java.util.Map<ConfigKey,java.util.Set<Capability>>"
|
|
||||||
|
|
||||||
%typemap(out) std::map<const sigrok::ConfigKey *, std::set<const sigrok::Capability *> > {
|
|
||||||
jclass HashMap = jenv->FindClass("java/util/HashMap");
|
|
||||||
jmethodID HashMap_init = jenv->GetMethodID(HashMap, "<init>", "()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, "<init>", "()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, "<init>", "(JZ)V");
|
|
||||||
jclass Capability = jenv->FindClass("org/sigrok/core/classes/Capability");
|
|
||||||
jmethodID Capability_init = jenv->GetMethodID(Capability, "<init>", "(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. */
|
/* Pass JNIEnv parameter to C++ extension methods requiring it. */
|
||||||
|
|
||||||
%typemap(in, numinputs=0) JNIEnv * %{
|
%typemap(in, numinputs=0) JNIEnv * %{
|
||||||
|
|
|
@ -60,20 +60,22 @@ namespace std {
|
||||||
for the map instantiation from compiling. */
|
for the map instantiation from compiling. */
|
||||||
%template(ConfigVector)
|
%template(ConfigVector)
|
||||||
std::vector<const sigrok::ConfigKey *>;
|
std::vector<const sigrok::ConfigKey *>;
|
||||||
|
|
||||||
%template(ConfigMap)
|
%template(ConfigMap)
|
||||||
std::map<const sigrok::ConfigKey *, Glib::VariantBase>;
|
std::map<const sigrok::ConfigKey *, Glib::VariantBase>;
|
||||||
|
|
||||||
/* Currently broken on Python. */
|
%template(ConfigSet)
|
||||||
#ifndef SWIGPYTHON
|
std::set<const sigrok::ConfigKey *>;
|
||||||
|
|
||||||
|
/* 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<const sigrok::Capability *>;
|
||||||
|
|
||||||
%template(CapabilitySet)
|
%template(CapabilitySet)
|
||||||
std::set<const sigrok::Capability *>;
|
std::set<const sigrok::Capability *>;
|
||||||
|
|
||||||
%template(ConfigKeys)
|
|
||||||
std::map<const sigrok::ConfigKey *, std::set<const sigrok::Capability *> >;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
%template(OptionVector)
|
%template(OptionVector)
|
||||||
std::vector<std::shared_ptr<sigrok::Option> >;
|
std::vector<std::shared_ptr<sigrok::Option> >;
|
||||||
%template(OptionMap)
|
%template(OptionMap)
|
||||||
|
|
Loading…
Reference in New Issue