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);
|
||||
}
|
||||
|
||||
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(
|
||||
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
|
||||
{
|
||||
GVariant *data;
|
||||
|
@ -482,6 +507,29 @@ void Configurable::config_set(const ConfigKey *key, const Glib::VariantBase &val
|
|||
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
|
||||
{
|
||||
GVariant *data;
|
||||
|
@ -491,66 +539,6 @@ Glib::VariantContainerBase Configurable::config_list(const ConfigKey *key) const
|
|||
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) :
|
||||
Configurable(sr_dev_inst_driver_get(structure), structure, nullptr),
|
||||
_structure(structure)
|
||||
|
|
|
@ -315,6 +315,8 @@ private:
|
|||
class SR_API Configurable
|
||||
{
|
||||
public:
|
||||
/** Supported configuration keys. */
|
||||
set<const ConfigKey *> 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<const ConfigKey *, set<const Capability *> > 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<const Capability *> 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<Driver, Context>,
|
||||
public Configurable
|
||||
class SR_API Driver : public ParentOwned<Driver, Context>, 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<const ConfigKey *> scan_options() const;
|
||||
/** Scan for devices and return a list of devices found.
|
||||
* @param options Mapping of (ConfigKey, value) pairs. */
|
||||
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. */
|
||||
|
||||
%typemap(in, numinputs=0) JNIEnv * %{
|
||||
|
|
|
@ -60,20 +60,22 @@ namespace std {
|
|||
for the map instantiation from compiling. */
|
||||
%template(ConfigVector)
|
||||
std::vector<const sigrok::ConfigKey *>;
|
||||
|
||||
%template(ConfigMap)
|
||||
std::map<const sigrok::ConfigKey *, Glib::VariantBase>;
|
||||
|
||||
/* Currently broken on Python. */
|
||||
#ifndef SWIGPYTHON
|
||||
%template(ConfigSet)
|
||||
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)
|
||||
std::set<const sigrok::Capability *>;
|
||||
|
||||
%template(ConfigKeys)
|
||||
std::map<const sigrok::ConfigKey *, std::set<const sigrok::Capability *> >;
|
||||
|
||||
#endif
|
||||
|
||||
%template(OptionVector)
|
||||
std::vector<std::shared_ptr<sigrok::Option> >;
|
||||
%template(OptionMap)
|
||||
|
|
Loading…
Reference in New Issue