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:
Martin Ling 2015-11-02 22:05:02 +00:00 committed by Uwe Hermann
parent 8f3168b89b
commit 36bb818d6f
4 changed files with 69 additions and 110 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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 * %{

View File

@ -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)