Update bindings to use new output API.
This commit is contained in:
parent
a755b0e122
commit
58aa1f8359
|
@ -41,8 +41,7 @@ static const char *valid_string(const char *input)
|
|||
}
|
||||
|
||||
/** Helper function to convert between map<string, string> and GHashTable */
|
||||
|
||||
static GHashTable *map_to_hash(map<string, string> input)
|
||||
static GHashTable *map_to_hash_string(map<string, string> input)
|
||||
{
|
||||
auto output = g_hash_table_new_full(
|
||||
g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
@ -53,6 +52,19 @@ static GHashTable *map_to_hash(map<string, string> input)
|
|||
return output;
|
||||
}
|
||||
|
||||
/** Helper function to convert between map<string, VariantBase> and GHashTable */
|
||||
static GHashTable *map_to_hash_variant(map<string, Glib::VariantBase> input)
|
||||
{
|
||||
auto output = g_hash_table_new_full(
|
||||
g_variant_hash, g_variant_equal, g_free,
|
||||
(void (*)(void *))g_variant_unref);
|
||||
for (auto entry : input)
|
||||
g_hash_table_insert(output,
|
||||
g_strdup(entry.first.c_str()),
|
||||
entry.second.gobj_copy());
|
||||
return output;
|
||||
}
|
||||
|
||||
Error::Error(int result) : result(result)
|
||||
{
|
||||
}
|
||||
|
@ -85,10 +97,10 @@ Context::Context() :
|
|||
for (int i = 0; input_list[i]; i++)
|
||||
input_formats[input_list[i]->id] =
|
||||
new InputFormat(input_list[i]);
|
||||
struct sr_output_format **output_list = sr_output_list();
|
||||
const struct sr_output_module **output_list = sr_output_list();
|
||||
if (output_list)
|
||||
for (int i = 0; output_list[i]; i++)
|
||||
output_formats[output_list[i]->id] =
|
||||
output_formats[sr_output_id_get(output_list[i])] =
|
||||
new OutputFormat(output_list[i]);
|
||||
}
|
||||
|
||||
|
@ -1116,7 +1128,7 @@ shared_ptr<InputFileDevice> InputFormat::open_file(string filename,
|
|||
map<string, string> options)
|
||||
{
|
||||
auto input = g_new(struct sr_input, 1);
|
||||
input->param = map_to_hash(options);
|
||||
input->param = map_to_hash_string(options);
|
||||
|
||||
/** Run initialisation. */
|
||||
check(structure->init(input, filename.c_str()));
|
||||
|
@ -1147,8 +1159,47 @@ void InputFileDevice::load()
|
|||
check(format->structure->loadfile(input, filename.c_str()));
|
||||
}
|
||||
|
||||
OutputFormat::OutputFormat(struct sr_output_format *structure) :
|
||||
StructureWrapper<Context, struct sr_output_format>(structure)
|
||||
Option::Option(const struct sr_option *structure,
|
||||
shared_ptr<const struct sr_option> structure_array) :
|
||||
structure(structure),
|
||||
structure_array(structure_array)
|
||||
{
|
||||
}
|
||||
|
||||
Option::~Option()
|
||||
{
|
||||
}
|
||||
|
||||
string Option::get_id()
|
||||
{
|
||||
return valid_string(structure->id);
|
||||
}
|
||||
|
||||
string Option::get_name()
|
||||
{
|
||||
return valid_string(structure->name);
|
||||
}
|
||||
|
||||
string Option::get_description()
|
||||
{
|
||||
return valid_string(structure->desc);
|
||||
}
|
||||
|
||||
Glib::VariantBase Option::get_default_value()
|
||||
{
|
||||
return Glib::VariantBase(structure->def, true);
|
||||
}
|
||||
|
||||
vector<Glib::VariantBase> Option::get_values()
|
||||
{
|
||||
vector<Glib::VariantBase> result;
|
||||
for (auto l = structure->values; l; l = l->next)
|
||||
result.push_back(Glib::VariantBase((GVariant *) l->data, true));
|
||||
return result;
|
||||
}
|
||||
|
||||
OutputFormat::OutputFormat(const struct sr_output_module *structure) :
|
||||
StructureWrapper<Context, const struct sr_output_module>(structure)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1158,16 +1209,29 @@ OutputFormat::~OutputFormat()
|
|||
|
||||
string OutputFormat::get_name()
|
||||
{
|
||||
return valid_string(structure->id);
|
||||
return valid_string(sr_output_id_get(structure));
|
||||
}
|
||||
|
||||
string OutputFormat::get_description()
|
||||
{
|
||||
return valid_string(structure->description);
|
||||
return valid_string(sr_output_description_get(structure));
|
||||
}
|
||||
|
||||
map<string, shared_ptr<Option>> OutputFormat::get_options()
|
||||
{
|
||||
const struct sr_option *option = sr_output_options_get(structure);
|
||||
auto option_array = shared_ptr<const struct sr_option>(
|
||||
option, [=](const struct sr_option *) {
|
||||
sr_output_options_free(structure); });
|
||||
map<string, shared_ptr<Option>> result;
|
||||
for (; option->id; option++)
|
||||
result[option->id] = shared_ptr<Option>(
|
||||
new Option(option, option_array), Option::Deleter());
|
||||
return result;
|
||||
}
|
||||
|
||||
shared_ptr<Output> OutputFormat::create_output(
|
||||
shared_ptr<Device> device, map<string, string> options)
|
||||
shared_ptr<Device> device, map<string, Glib::VariantBase> options)
|
||||
{
|
||||
return shared_ptr<Output>(
|
||||
new Output(
|
||||
|
@ -1177,16 +1241,15 @@ shared_ptr<Output> OutputFormat::create_output(
|
|||
}
|
||||
|
||||
Output::Output(shared_ptr<OutputFormat> format,
|
||||
shared_ptr<Device> device, map<string, string> options) :
|
||||
shared_ptr<Device> device, map<string, Glib::VariantBase> options) :
|
||||
structure(sr_output_new(format->structure,
|
||||
map_to_hash(options), device->structure)),
|
||||
map_to_hash_variant(options), device->structure)),
|
||||
format(format), device(device), options(options)
|
||||
{
|
||||
}
|
||||
|
||||
Output::~Output()
|
||||
{
|
||||
g_hash_table_unref(structure->params);
|
||||
check(sr_output_free(structure));
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ class SR_API QuantityFlag;
|
|||
class SR_API InputFileDevice;
|
||||
class SR_API Output;
|
||||
class SR_API DataType;
|
||||
class SR_API Option;
|
||||
|
||||
/** Exception thrown when an error code is returned by any libsigrok call. */
|
||||
class SR_API Error: public exception
|
||||
|
@ -717,19 +718,52 @@ protected:
|
|||
friend class InputFormat;
|
||||
};
|
||||
|
||||
/** An option used by an output format */
|
||||
class SR_API Option
|
||||
{
|
||||
public:
|
||||
/** Short name of this option suitable for command line usage. */
|
||||
string get_id();
|
||||
/** Short name of this option suitable for GUI usage. */
|
||||
string get_name();
|
||||
/** Description of this option in a sentence. */
|
||||
string get_description();
|
||||
/** Default value for this option. */
|
||||
Glib::VariantBase get_default_value();
|
||||
/** Possible values for this option, if a limited set. */
|
||||
vector<Glib::VariantBase> get_values();
|
||||
protected:
|
||||
Option(const struct sr_option *structure,
|
||||
shared_ptr<const struct sr_option> structure_array);
|
||||
~Option();
|
||||
const struct sr_option *structure;
|
||||
shared_ptr<const struct sr_option> structure_array;
|
||||
/** Deleter needed to allow shared_ptr use with protected destructor. */
|
||||
class Deleter
|
||||
{
|
||||
public:
|
||||
void operator()(Option *option) { delete option; }
|
||||
};
|
||||
friend class Deleter;
|
||||
friend class OutputFormat;
|
||||
};
|
||||
|
||||
/** An output format supported by the library */
|
||||
class SR_API OutputFormat :
|
||||
public StructureWrapper<Context, struct sr_output_format>
|
||||
public StructureWrapper<Context, const struct sr_output_module>
|
||||
{
|
||||
public:
|
||||
/** Name of this output format. */
|
||||
string get_name();
|
||||
/** Description of this output format. */
|
||||
string get_description();
|
||||
/** Options supported by this output format. */
|
||||
map<string, shared_ptr<Option> > get_options();
|
||||
/** Create an output using this format. */
|
||||
shared_ptr<Output> create_output(shared_ptr<Device> device, map<string, string> options = {});
|
||||
shared_ptr<Output> create_output(shared_ptr<Device> device,
|
||||
map<string, Glib::VariantBase> options = {});
|
||||
protected:
|
||||
OutputFormat(struct sr_output_format *structure);
|
||||
OutputFormat(const struct sr_output_module *structure);
|
||||
~OutputFormat();
|
||||
friend class Context;
|
||||
friend class Output;
|
||||
|
@ -744,12 +778,12 @@ public:
|
|||
protected:
|
||||
Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
|
||||
Output(shared_ptr<OutputFormat> format,
|
||||
shared_ptr<Device> device, map<string, string> options);
|
||||
shared_ptr<Device> device, map<string, Glib::VariantBase> options);
|
||||
~Output();
|
||||
struct sr_output *structure;
|
||||
const struct sr_output *structure;
|
||||
const shared_ptr<OutputFormat> format;
|
||||
const shared_ptr<Device> device;
|
||||
const map<string, string> options;
|
||||
const map<string, Glib::VariantBase> options;
|
||||
/** Deleter needed to allow shared_ptr use with protected destructor. */
|
||||
class Deleter
|
||||
{
|
||||
|
|
|
@ -236,7 +236,7 @@ typedef guint pyg_flags_type;
|
|||
#include "libsigrok/libsigrok.hpp"
|
||||
|
||||
/* Convert from a Python dict to a std::map<std::string, std::string> */
|
||||
std::map<std::string, std::string> dict_to_map(PyObject *dict)
|
||||
std::map<std::string, std::string> dict_to_map_string(PyObject *dict)
|
||||
{
|
||||
if (!PyDict_Check(dict))
|
||||
throw sigrok::Error(SR_ERR_ARG);
|
||||
|
@ -280,6 +280,51 @@ Glib::VariantBase python_to_variant_by_key(PyObject *input, const sigrok::Config
|
|||
throw sigrok::Error(SR_ERR_ARG);
|
||||
}
|
||||
|
||||
/* Convert from a Python type to Glib::Variant, according to Option data type. */
|
||||
Glib::VariantBase python_to_variant_by_option(PyObject *input,
|
||||
std::shared_ptr<sigrok::Option> option)
|
||||
{
|
||||
GVariantType *type = option->get_default_value().get_type().gobj();
|
||||
|
||||
if (type == G_VARIANT_TYPE_UINT64 && PyInt_Check(input))
|
||||
return Glib::Variant<guint64>::create(PyInt_AsLong(input));
|
||||
if (type == G_VARIANT_TYPE_UINT64 && PyLong_Check(input))
|
||||
return Glib::Variant<guint64>::create(PyLong_AsLong(input));
|
||||
else if (type == G_VARIANT_TYPE_STRING && PyString_Check(input))
|
||||
return Glib::Variant<std::string>::create(PyString_AsString(input));
|
||||
else if (type == G_VARIANT_TYPE_BOOLEAN && PyBool_Check(input))
|
||||
return Glib::Variant<bool>::create(input == Py_True);
|
||||
else if (type == G_VARIANT_TYPE_DOUBLE && PyFloat_Check(input))
|
||||
return Glib::Variant<double>::create(PyFloat_AsDouble(input));
|
||||
else if (type == G_VARIANT_TYPE_INT32 && PyInt_Check(input))
|
||||
return Glib::Variant<gint32>::create(PyInt_AsLong(input));
|
||||
else
|
||||
throw sigrok::Error(SR_ERR_ARG);
|
||||
}
|
||||
|
||||
/* Convert from a Python dict to a std::map<std::string, std::string> */
|
||||
std::map<std::string, Glib::VariantBase> dict_to_map_options(PyObject *dict,
|
||||
std::map<std::string, std::shared_ptr<sigrok::Option> > options)
|
||||
{
|
||||
if (!PyDict_Check(dict))
|
||||
throw sigrok::Error(SR_ERR_ARG);
|
||||
|
||||
std::map<std::string, Glib::VariantBase> output;
|
||||
|
||||
PyObject *py_key, *py_value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
while (PyDict_Next(dict, &pos, &py_key, &py_value)) {
|
||||
if (!PyString_Check(py_key))
|
||||
throw sigrok::Error(SR_ERR_ARG);
|
||||
auto key = PyString_AsString(py_key);
|
||||
auto value = python_to_variant_by_option(py_value, options[key]);
|
||||
output[key] = value;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/* Ignore these methods, we will override them below. */
|
||||
|
@ -327,7 +372,7 @@ Glib::VariantBase python_to_variant_by_key(PyObject *input, const sigrok::Config
|
|||
{
|
||||
std::shared_ptr<sigrok::InputFileDevice> _open_file_kwargs(std::string filename, PyObject *dict)
|
||||
{
|
||||
return $self->open_file(filename, dict_to_map(dict));
|
||||
return $self->open_file(filename, dict_to_map_string(dict));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,7 +390,8 @@ Glib::VariantBase python_to_variant_by_key(PyObject *input, const sigrok::Config
|
|||
std::shared_ptr<sigrok::Output> _create_output_kwargs(
|
||||
std::shared_ptr<sigrok::Device> device, PyObject *dict)
|
||||
{
|
||||
return $self->create_output(device, dict_to_map(dict));
|
||||
return $self->create_output(device,
|
||||
dict_to_map_options(dict, $self->get_options()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ template< class T > class enable_shared_from_this;
|
|||
%shared_ptr(sigrok::Logic);
|
||||
%shared_ptr(sigrok::InputFormat);
|
||||
%shared_ptr(sigrok::InputFileDevice);
|
||||
%shared_ptr(sigrok::Option);
|
||||
%shared_ptr(sigrok::OutputFormat);
|
||||
%shared_ptr(sigrok::Output);
|
||||
%shared_ptr(sigrok::Trigger);
|
||||
|
@ -111,6 +112,16 @@ template< class T > class enable_shared_from_this;
|
|||
%template(ConfigMap)
|
||||
std::map<const sigrok::ConfigKey *, Glib::VariantBase>;
|
||||
|
||||
%template(OptionVector)
|
||||
std::vector<std::shared_ptr<sigrok::Option> >;
|
||||
%template(OptionMap)
|
||||
std::map<std::string, std::shared_ptr<sigrok::Option> >;
|
||||
|
||||
%template(VariantVector)
|
||||
std::vector<Glib::VariantBase>;
|
||||
%template(VariantMap)
|
||||
std::map<std::string, Glib::VariantBase>;
|
||||
|
||||
%template(QuantityFlagVector)
|
||||
std::vector<const sigrok::QuantityFlag *>;
|
||||
|
||||
|
@ -145,6 +156,10 @@ typedef std::map<std::string, std::shared_ptr<sigrok::OutputFormat> >
|
|||
map_string_OutputFormat;
|
||||
typedef std::map<std::string, std::shared_ptr<sigrok::ChannelGroup> >
|
||||
map_string_ChannelGroup;
|
||||
typedef std::map<std::string, std::shared_ptr<sigrok::Option> >
|
||||
map_string_Option;
|
||||
typedef std::map<std::string, Glib::VariantBase>
|
||||
map_string_Variant;
|
||||
typedef std::map<const sigrok::ConfigKey *, Glib::VariantBase>
|
||||
map_ConfigKey_Variant;
|
||||
}
|
||||
|
@ -175,10 +190,24 @@ typedef std::map<const sigrok::ConfigKey *, Glib::VariantBase>
|
|||
%attributestring(sigrok::InputFormat,
|
||||
std::string, description, get_description);
|
||||
|
||||
%attributestring(sigrok::Option,
|
||||
std::string, id, get_id);
|
||||
%attributestring(sigrok::Option,
|
||||
std::string, name, get_name);
|
||||
%attributestring(sigrok::Option,
|
||||
std::string, description, get_description);
|
||||
/* Currently broken on Python due to some issue with variant typemaps. */
|
||||
/* %attributeval(sigrok::Option,
|
||||
Glib::VariantBase, default_value, get_default_value); */
|
||||
%attributeval(sigrok::Option,
|
||||
std::vector<Glib::VariantBase>, values, get_values);
|
||||
|
||||
%attributestring(sigrok::OutputFormat,
|
||||
std::string, name, get_name);
|
||||
%attributestring(sigrok::OutputFormat,
|
||||
std::string, description, get_description);
|
||||
%attributeval(sigrok::OutputFormat,
|
||||
map_string_Option, options, get_options);
|
||||
|
||||
%attributestring(sigrok::Device, std::string, description, get_description);
|
||||
%attributestring(sigrok::Device, std::string, vendor, get_vendor);
|
||||
|
|
Loading…
Reference in New Issue