class SR_API Quantity;
class SR_API Unit;
class SR_API QuantityFlag;
-class SR_API InputFileDevice;
+class SR_API Input;
+class SR_API InputDevice;
class SR_API Output;
class SR_API DataType;
class SR_API Option;
const char *what() const throw();
};
-/* Base template for most classes which wrap a struct type from libsigrok. */
-template <class Parent, typename Struct> class SR_API StructureWrapper :
- public enable_shared_from_this<StructureWrapper<Parent, Struct> >
+/* Base template for classes whose resources are owned by a parent object. */
+template <class Class, class Parent, typename Struct>
+class SR_API ParentOwned
{
protected:
/* Parent object which owns this child object's underlying structure.
references to both the parent and all its children are gone. */
shared_ptr<Parent> parent;
+ /* Weak pointer for shared_from_this() implementation. */
+ weak_ptr<Class> weak_this;
+
public:
- shared_ptr<StructureWrapper<Parent, Struct> >
- get_shared_pointer(Parent *parent)
+ /* Note, this implementation will create a new smart_ptr if none exists. */
+ shared_ptr<Class> shared_from_this()
{
- this->parent = static_pointer_cast<Parent>(parent->shared_from_this());
- return shared_ptr<StructureWrapper<Parent, Struct> >(
- this, reset_parent);
+ shared_ptr<Class> shared;
+
+ if (!(shared = weak_this.lock()))
+ {
+ shared = shared_ptr<Class>((Class *) this, reset_parent);
+ weak_this = shared;
+ }
+
+ return shared;
}
- shared_ptr<StructureWrapper<Parent, Struct> >
- get_shared_pointer(shared_ptr<Parent> parent)
+
+ shared_ptr<Class> get_shared_pointer(shared_ptr<Parent> parent)
{
+ if (!parent)
+ throw Error(SR_ERR_BUG);
this->parent = parent;
- return shared_ptr<StructureWrapper<Parent, Struct> >(
- this, reset_parent);
+ return shared_from_this();
+ }
+
+ shared_ptr<Class> get_shared_pointer(Parent *parent)
+ {
+ if (!parent)
+ throw Error(SR_ERR_BUG);
+ return get_shared_pointer(parent->shared_from_this());
}
protected:
- static void reset_parent(StructureWrapper<Parent, Struct> *object)
+ static void reset_parent(Class *object)
{
+ if (!object->parent)
+ throw Error(SR_ERR_BUG);
object->parent.reset();
}
Struct *structure;
- StructureWrapper<Parent, Struct>(Struct *structure) :
+ ParentOwned<Class, Parent, Struct>(Struct *structure) :
structure(structure)
{
}
};
+/* Base template for classes whose resources are owned by the user. */
+template <class Class, typename Struct>
+class SR_API UserOwned : public enable_shared_from_this<Class>
+{
+public:
+ shared_ptr<Class> shared_from_this()
+ {
+ auto shared = enable_shared_from_this<Class>::shared_from_this();
+ if (!shared)
+ throw Error(SR_ERR_BUG);
+ return shared;
+ }
+protected:
+ Struct *structure;
+
+ UserOwned<Class, Struct>(Struct *structure) :
+ structure(structure)
+ {
+ }
+
+ /* Deleter needed to allow shared_ptr use with protected destructor. */
+ class Deleter
+ {
+ public:
+ void operator()(Class *object) { delete object; }
+ };
+};
+
/** Type of log callback */
typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
/** The global libsigrok context */
-class SR_API Context : public enable_shared_from_this<Context>
+class SR_API Context : public UserOwned<Context, struct sr_context>
{
public:
/** Create new context */
map<string, shared_ptr<OutputFormat> > get_output_formats();
/** Current log level. */
const LogLevel *get_log_level();
- /** Set the log level. */
+ /** Set the log level.
+ * @param level LogLevel to use. */
void set_log_level(const LogLevel *level);
/** Current log domain. */
string get_log_domain();
- /** Set the log domain. */
+ /** Set the log domain.
+ * @param value Log domain prefix string. */
void set_log_domain(string value);
- /** Set the log callback. */
+ /** Set the log callback.
+ * @param callback Callback of the form callback(LogLevel, string). */
void set_log_callback(LogCallbackFunction callback);
/** Set the log callback to the default handler. */
void set_log_callback_default();
/** Create a new session. */
shared_ptr<Session> create_session();
- /** Load a saved session. */
+ /** Load a saved session.
+ * @param filename File name string. */
shared_ptr<Session> load_session(string filename);
- /** Create a new trigger. */
+ /** Create a new trigger.
+ * @param name Name string for new trigger. */
shared_ptr<Trigger> create_trigger(string name);
+ /** Open an input file.
+ * @param filename File name string. */
+ shared_ptr<Input> open_file(string filename);
+ /** Open an input stream based on header data.
+ * @param header Initial data from stream. */
+ shared_ptr<Input> open_stream(string header);
protected:
- struct sr_context *structure;
map<string, Driver *> drivers;
map<string, InputFormat *> input_formats;
map<string, OutputFormat *> output_formats;
LogCallbackFunction log_callback;
Context();
~Context();
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(Context *context) { delete context; }
- };
friend class Deleter;
friend class Session;
friend class Driver;
};
+/** An object that can be configured. */
+class SR_API Configurable
+{
+public:
+ /** Read configuration for the given key.
+ * @param key ConfigKey to read. */
+ Glib::VariantBase config_get(const ConfigKey *key);
+ /** Set configuration for the given key to a specified value.
+ * @param key ConfigKey to set.
+ * @param value Value to set. */
+ void config_set(const ConfigKey *key, Glib::VariantBase value);
+ /** Enumerate available values for the given configuration key.
+ * @param key ConfigKey to enumerate values for. */
+ Glib::VariantContainerBase config_list(const ConfigKey *key);
+ /** Enumerate available keys, according to a given index key. */
+ vector<const ConfigKey *> 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);
+protected:
+ Configurable(
+ struct sr_dev_driver *driver,
+ struct sr_dev_inst *sdi,
+ struct sr_channel_group *channel_group);
+ virtual ~Configurable();
+ struct sr_dev_driver *config_driver;
+ struct sr_dev_inst *config_sdi;
+ struct sr_channel_group *config_channel_group;
+};
+
/** A hardware driver provided by the library */
-class SR_API Driver : public StructureWrapper<Context, struct sr_dev_driver>
+class SR_API Driver :
+ public ParentOwned<Driver, Context, struct sr_dev_driver>,
+ public Configurable
{
public:
/** Name of this driver. */
string get_name();
/** Long name for this driver. */
string get_long_name();
- /** 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. */
vector<shared_ptr<HardwareDevice> > scan(
map<const ConfigKey *, Glib::VariantBase> options = {});
protected:
friend class ChannelGroup;
};
-/** An object that can be configured. */
-class SR_API Configurable
-{
-public:
- /** Read configuration for the given key. */
- Glib::VariantBase config_get(const ConfigKey *key);
- /** Set configuration for the given key to a specified value. */
- void config_set(const ConfigKey *key, Glib::VariantBase value);
- /** Enumerate available values for the given configuration key. */
- Glib::VariantContainerBase config_list(const ConfigKey *key);
-protected:
- Configurable(
- struct sr_dev_driver *driver,
- struct sr_dev_inst *sdi,
- struct sr_channel_group *channel_group);
- virtual ~Configurable();
- struct sr_dev_driver *config_driver;
- struct sr_dev_inst *config_sdi;
- struct sr_channel_group *config_channel_group;
-};
-
/** A generic device, either hardware or virtual */
-class SR_API Device :
- public Configurable,
- public StructureWrapper<Context, struct sr_dev_inst>
+class SR_API Device : public Configurable
{
public:
/** Description identifying this device. */
protected:
Device(struct sr_dev_inst *structure);
~Device();
+ virtual shared_ptr<Device> get_shared_from_this() = 0;
shared_ptr<Channel> get_channel(struct sr_channel *ptr);
+ struct sr_dev_inst *structure;
map<struct sr_channel *, Channel *> channels;
map<string, ChannelGroup *> channel_groups;
/** Deleter needed to allow shared_ptr use with protected destructor. */
};
/** A real hardware device, connected via a driver */
-class SR_API HardwareDevice : public Device
+class SR_API HardwareDevice :
+ public ParentOwned<HardwareDevice, Context, struct sr_dev_inst>,
+ public Device
{
public:
/** Driver providing this device. */
protected:
HardwareDevice(Driver *driver, struct sr_dev_inst *structure);
~HardwareDevice();
+ shared_ptr<Device> get_shared_from_this();
Driver *driver;
friend class Driver;
friend class ChannelGroup;
};
/** A channel on a device */
-class SR_API Channel : public StructureWrapper<Device, struct sr_channel>
+class SR_API Channel :
+ public ParentOwned<Channel, Device, struct sr_channel>
{
public:
/** Current name of this channel. */
string get_name();
- /** Set the name of this channel. */
+ /** Set the name of this channel. *
+ * @param name Name string to set. */
void set_name(string name);
/** Type of this channel. */
const ChannelType *get_type();
/** Enabled status of this channel. */
bool get_enabled();
- /** Set the enabled status of this channel. */
+ /** Set the enabled status of this channel.
+ * @param value Boolean value to set. */
void set_enabled(bool value);
/** Get the index number of this channel. */
unsigned int get_index();
/** A group of channels on a device, which share some configuration */
class SR_API ChannelGroup :
- public StructureWrapper<Device, struct sr_channel_group>,
+ public ParentOwned<ChannelGroup, Device, struct sr_channel_group>,
public Configurable
{
public:
};
/** A trigger configuration */
-class SR_API Trigger : public enable_shared_from_this<Trigger>
+class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
{
public:
+ /** Name of this trigger configuration. */
string get_name();
+ /** List of the stages in this trigger. */
vector<shared_ptr<TriggerStage> > get_stages();
+ /** Add a new stage to this trigger. */
shared_ptr<TriggerStage> add_stage();
protected:
Trigger(shared_ptr<Context> context, string name);
~Trigger();
- struct sr_trigger *structure;
shared_ptr<Context> context;
vector<TriggerStage *> stages;
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(Trigger *trigger) { delete trigger; }
- };
+ friend class Deleter;
friend class Context;
friend class Session;
};
/** A stage in a trigger configuration */
-class SR_API TriggerStage : public StructureWrapper<Trigger, struct sr_trigger_stage>
+class SR_API TriggerStage :
+ public ParentOwned<TriggerStage, Trigger, struct sr_trigger_stage>
{
public:
+ /** Index number of this stage. */
int get_number();
+ /** List of match conditions on this stage. */
vector<shared_ptr<TriggerMatch> > get_matches();
+ /** Add a new match condition to this stage.
+ * @param channel Channel to match on.
+ * @param type TriggerMatchType to apply. */
void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
+ /** Add a new match condition to this stage.
+ * @param channel Channel to match on.
+ * @param type TriggerMatchType to apply.
+ * @param value Threshold value. */
void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
protected:
vector<TriggerMatch *> matches;
};
/** A match condition in a trigger configuration */
-class SR_API TriggerMatch : public StructureWrapper<TriggerStage, struct sr_trigger_match>
+class SR_API TriggerMatch :
+ public ParentOwned<TriggerMatch, TriggerStage, struct sr_trigger_match>
{
public:
+ /** Channel this condition matches on. */
shared_ptr<Channel> get_channel();
+ /** Type of match. */
const TriggerMatchType *get_type();
+ /** Threshold value. */
float get_value();
protected:
TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
class SR_API EventSource
{
public:
- /** Create an event source from a file descriptor. */
+ /** Create an event source from a file descriptor.
+ * @param fd File descriptor.
+ * @param events GLib IOCondition event mask.
+ * @param timeout Timeout in milliseconds.
+ * @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(int fd, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
- /** Create an event source from a Glib::PollFD */
+ /** Create an event source from a GLib PollFD
+ * @param pollfd GLib PollFD
+ * @param timeout Timeout in milliseconds.
+ * @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(Glib::PollFD pollfd, int timeout,
SourceCallbackFunction callback);
- /** Create an event source from a Glib::IOChannel */
+ /** Create an event source from a GLib IOChannel
+ * @param channel GLib IOChannel.
+ * @param events GLib IOCondition event mask.
+ * @param timeout Timeout in milliseconds.
+ * @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(
Glib::RefPtr<Glib::IOChannel> channel, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
};
/** A sigrok session */
-class SR_API Session
+class SR_API Session : public UserOwned<Session, struct sr_session>
{
public:
- /** Add a device to this session. */
+ /** Add a device to this session.
+ * @param device Device to add. */
void add_device(shared_ptr<Device> device);
/** List devices attached to this session. */
vector<shared_ptr<Device> > get_devices();
/** Remove all devices from this session. */
void remove_devices();
- /** Add a datafeed callback to this session. */
+ /** Add a datafeed callback to this session.
+ * @param callback Callback of the form callback(Device, Packet). */
void add_datafeed_callback(DatafeedCallbackFunction callback);
/** Remove all datafeed callbacks from this session. */
void remove_datafeed_callbacks();
- /** Add an event source. */
+ /** Add an I/O event source.
+ * @param source EventSource to add. */
void add_source(shared_ptr<EventSource> source);
- /** Remove an event source. */
+ /** Remove an event source.
+ * @param source EventSource to remove. */
void remove_source(shared_ptr<EventSource> source);
/** Start the session. */
void start();
void run();
/** Stop the session. */
void stop();
- /** Begin saving session to a file. */
+ /** Begin saving session to a file.
+ * @param filename File name string. */
void begin_save(string filename);
- /** Append a packet to the session file being saved. */
+ /** Append a packet to the session file being saved.
+ * @param packet Packet to append. */
void append(shared_ptr<Packet> packet);
/** Append raw logic data to the session file being saved. */
void append(void *data, size_t length, unsigned int unit_size);
/** Get current trigger setting. */
shared_ptr<Trigger> get_trigger();
- /** Set trigger setting. */
+ /** Set trigger setting.
+ * @param trigger Trigger object to use. */
void set_trigger(shared_ptr<Trigger> trigger);
protected:
Session(shared_ptr<Context> context);
Session(shared_ptr<Context> context, string filename);
~Session();
- struct sr_session *structure;
const shared_ptr<Context> context;
map<const struct sr_dev_inst *, shared_ptr<Device> > devices;
vector<DatafeedCallbackData *> datafeed_callbacks;
string save_filename;
uint64_t save_samplerate;
shared_ptr<Trigger> trigger;
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(Session *session) { delete session; }
- };
friend class Deleter;
friend class Context;
friend class DatafeedCallbackData;
};
/** A packet on the session datafeed */
-class SR_API Packet : public enable_shared_from_this<Packet>
+class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
{
public:
/** Type of this packet. */
Packet(shared_ptr<Device> device,
const struct sr_datafeed_packet *structure);
~Packet();
- const struct sr_datafeed_packet *structure;
shared_ptr<Device> device;
PacketPayload *payload;
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(Packet *packet) { delete packet; }
- };
friend class Deleter;
friend class Session;
friend class Output;
protected:
PacketPayload();
virtual ~PacketPayload() = 0;
- shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) {
- return static_pointer_cast<PacketPayload>(get_shared_pointer(parent));
- }
+ virtual shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) = 0;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
};
/** Payload of a datafeed header packet */
-class SR_API Header : public PacketPayload,
- public StructureWrapper<Packet, const struct sr_datafeed_header>
+class SR_API Header :
+ public ParentOwned<Header, Packet, const struct sr_datafeed_header>,
+ public PacketPayload
{
public:
+ /* Feed version number. */
int get_feed_version();
+ /* Start time of this session. */
Glib::TimeVal get_start_time();
protected:
Header(const struct sr_datafeed_header *structure);
~Header();
- const struct sr_datafeed_header *structure;
+ shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
friend class Packet;
};
/** Payload of a datafeed metadata packet */
-class SR_API Meta : public PacketPayload,
- public StructureWrapper<Packet, const struct sr_datafeed_meta>
+class SR_API Meta :
+ public ParentOwned<Meta, Packet, const struct sr_datafeed_meta>,
+ public PacketPayload
{
public:
+ /* Mapping of (ConfigKey, value) pairs. */
map<const ConfigKey *, Glib::VariantBase> get_config();
protected:
Meta(const struct sr_datafeed_meta *structure);
~Meta();
- const struct sr_datafeed_meta *structure;
+ shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
map<const ConfigKey *, Glib::VariantBase> config;
friend class Packet;
};
/** Payload of a datafeed packet with logic data */
-class SR_API Logic : public PacketPayload,
- public StructureWrapper<Packet, const struct sr_datafeed_logic>
+class SR_API Logic :
+ public ParentOwned<Logic, Packet, const struct sr_datafeed_logic>,
+ public PacketPayload
{
public:
/* Pointer to data. */
protected:
Logic(const struct sr_datafeed_logic *structure);
~Logic();
- const struct sr_datafeed_logic *structure;
+ shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
friend class Packet;
};
/** Payload of a datafeed packet with analog data */
-class SR_API Analog : public PacketPayload,
- public StructureWrapper<Packet, const struct sr_datafeed_analog>
+class SR_API Analog :
+ public ParentOwned<Analog, Packet, const struct sr_datafeed_analog>,
+ public PacketPayload
{
public:
/** Pointer to data. */
protected:
Analog(const struct sr_datafeed_analog *structure);
~Analog();
- const struct sr_datafeed_analog *structure;
+ shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
friend class Packet;
};
/** An input format supported by the library */
class SR_API InputFormat :
- public StructureWrapper<Context, struct sr_input_format>
+ public ParentOwned<InputFormat, Context, const struct sr_input_module>
{
public:
/** Name of this input format. */
string get_name();
/** Description of this input format. */
string get_description();
- /** Check whether a given file matches this input format. */
- bool format_match(string filename);
- /** Open a file using this input format. */
- shared_ptr<InputFileDevice> open_file(string filename,
- map<string, string> options = {});
+ /** Options supported by this input format. */
+ map<string, shared_ptr<Option> > get_options();
+ /** Create an input using this input format.
+ * @param options Mapping of (option name, value) pairs. */
+ shared_ptr<Input> create_input(map<string, Glib::VariantBase> options = {});
protected:
- InputFormat(struct sr_input_format *structure);
+ InputFormat(const struct sr_input_module *structure);
~InputFormat();
friend class Context;
- friend class InputFileDevice;
+ friend class InputDevice;
};
-/** A virtual device associated with an input file */
-class SR_API InputFileDevice : public Device
+/** An input instance (an input format applied to a file or stream) */
+class SR_API Input : public UserOwned<Input, const struct sr_input>
{
public:
- /** Load data from file. */
- void load();
+ /** Virtual device associated with this input. */
+ shared_ptr<InputDevice> get_device();
+ /** Send next stream data.
+ * @param data Next stream data. */
+ void send(string data);
protected:
- InputFileDevice(shared_ptr<InputFormat> format,
- struct sr_input *input, string filename);
- ~InputFileDevice();
- struct sr_input *input;
- shared_ptr<InputFormat> format;
- string filename;
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(InputFileDevice *device) { delete device; }
- };
+ Input(shared_ptr<Context> context, const struct sr_input *structure);
+ ~Input();
+ shared_ptr<Context> context;
+ InputDevice *device;
friend class Deleter;
+ friend class Context;
friend class InputFormat;
};
+/** A virtual device associated with an input */
+class SR_API InputDevice :
+ public ParentOwned<InputDevice, Input, struct sr_dev_inst>,
+ public Device
+{
+protected:
+ InputDevice(shared_ptr<Input> input, struct sr_dev_inst *sdi);
+ ~InputDevice();
+ shared_ptr<Device> get_shared_from_this();
+ shared_ptr<Input> input;
+ friend class Input;
+};
+
/** An option used by an output format */
-class SR_API Option
+class SR_API Option : public UserOwned<Option, const struct sr_option>
{
public:
/** Short name of this option suitable for command line usage. */
vector<Glib::VariantBase> get_values();
protected:
Option(const struct sr_option *structure,
- shared_ptr<const struct sr_option> structure_array);
+ 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; }
- };
+ shared_ptr<const struct sr_option *> structure_array;
friend class Deleter;
+ friend class InputFormat;
friend class OutputFormat;
};
/** An output format supported by the library */
class SR_API OutputFormat :
- public StructureWrapper<Context, const struct sr_output_module>
+ public ParentOwned<OutputFormat, Context, const struct sr_output_module>
{
public:
/** Name 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. */
+ /** Create an output using this format.
+ * @param device Device to output for.
+ * @param options Mapping of (option name, value) pairs. */
shared_ptr<Output> create_output(shared_ptr<Device> device,
map<string, Glib::VariantBase> options = {});
protected:
};
/** An output instance (an output format applied to a device) */
-class SR_API Output
+class SR_API Output : public UserOwned<Output, const struct sr_output>
{
public:
- /** Update output with data from the given packet. */
+ /** Update output with data from the given packet.
+ * @param packet Packet to handle. */
string receive(shared_ptr<Packet> packet);
protected:
Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
Output(shared_ptr<OutputFormat> format,
shared_ptr<Device> device, map<string, Glib::VariantBase> options);
~Output();
- const struct sr_output *structure;
const shared_ptr<OutputFormat> format;
const shared_ptr<Device> device;
const map<string, Glib::VariantBase> options;
- /** Deleter needed to allow shared_ptr use with protected destructor. */
- class Deleter
- {
- public:
- void operator()(Output *output) { delete output; }
- };
friend class Deleter;
friend class OutputFormat;
};