]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp
C++: Make some methods static to match the C API
[libsigrok.git] / bindings / cxx / include / libsigrokcxx / libsigrokcxx.hpp
CommitLineData
c23c8659
ML
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013-2014 Martin Ling <martin-sigrok@earth.li>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
07443fd2
ML
20/**
21
22@mainpage API Reference
23
24Introduction
25------------
26
52ff4f6a
UH
27The libsigrokcxx API provides an object-oriented C++ interface to the
28functionality in libsigrok, including automatic memory and resource management.
07443fd2
ML
29
30It is built on top of the public libsigrok C API, and is designed to be used as
31a standalone alternative API. Programs should not mix usage of the C and C++
32APIs; the C++ interface code needs to have full control of all C API calls for
33resources to be managed correctly.
34
35Memory management
36-----------------
37
38All runtime objects created through the C++ API are passed and accessed via
39shared pointers, using the C++11 std::shared_ptr implementation. This means
40that a reference count is kept for each object.
41
42Shared pointers can be copied and assigned in a user's program, automatically
43updating their reference count and deleting objects when they are no longer in
44use. The C++ interface code also keeps track of internal dependencies between
45libsigrok resources, and ensures that objects are not prematurely deleted when
46their resources are in use by other objects.
47
52ff4f6a
UH
48This means that management of libsigrokcxx objects and their underlying
49libsigrok resources can be treated as fully automatic. As long as all shared
50pointers to objects are deleted or reassigned when no longer in use, all
51underlying resources will be released at the right time.
07443fd2
ML
52
53Getting started
54---------------
55
56Usage of the C++ API needs to begin with a call to sigrok::Context::create().
57This will create the global libsigrok context and returns a shared pointer to
58the sigrok::Context object. Methods on this object provide access to the
59hardware drivers, input and output formats supported by the library, as well
60as means of creating other objects such as sessions and triggers.
61
62Error handling
63--------------
64
65When any libsigrok C API call returns an error, a sigrok::Error exception is
66raised, which provides access to the error code and description.
67
68*/
69
1b40fdb8
UH
70#ifndef LIBSIGROKCXX_HPP
71#define LIBSIGROKCXX_HPP
c23c8659 72
8b2a1843 73#include <libsigrok/libsigrok.h>
e0e6aecc 74#include <glibmm.h>
c23c8659
ML
75
76#include <stdexcept>
77#include <memory>
78#include <vector>
79#include <map>
4c7c4194 80#include <set>
c23c8659
ML
81
82namespace sigrok
83{
84
85using namespace std;
86
87/* Forward declarations */
88class SR_API Error;
89class SR_API Context;
90class SR_API Driver;
91class SR_API Device;
92class SR_API HardwareDevice;
93class SR_API Channel;
c23c8659
ML
94class SR_API Session;
95class SR_API ConfigKey;
96class SR_API InputFormat;
97class SR_API OutputFormat;
3cd4b381 98class SR_API OutputFlag;
c23c8659
ML
99class SR_API LogLevel;
100class SR_API ChannelGroup;
101class SR_API Trigger;
102class SR_API TriggerStage;
103class SR_API TriggerMatch;
104class SR_API TriggerMatchType;
105class SR_API ChannelType;
106class SR_API Packet;
107class SR_API PacketPayload;
108class SR_API PacketType;
109class SR_API Quantity;
110class SR_API Unit;
111class SR_API QuantityFlag;
ca3291e3
ML
112class SR_API Input;
113class SR_API InputDevice;
c23c8659
ML
114class SR_API Output;
115class SR_API DataType;
58aa1f83 116class SR_API Option;
9fa5b426 117class SR_API UserDevice;
c23c8659
ML
118
119/** Exception thrown when an error code is returned by any libsigrok call. */
120class SR_API Error: public exception
121{
122public:
6c11b496 123 explicit Error(int result);
15914cdb 124 ~Error() noexcept;
c23c8659 125 const int result;
15914cdb 126 const char *what() const noexcept;
c23c8659
ML
127};
128
541c855e 129/* Base template for classes whose resources are owned by a parent object. */
bf52cc8c 130template <class Class, class Parent, typename Struct>
541c855e 131class SR_API ParentOwned
c23c8659 132{
7649683c 133protected:
07443fd2 134 /* Parent object which owns this child object's underlying structure.
c23c8659
ML
135
136 This shared pointer will be null when this child is unused, but
137 will be assigned to point to the parent before any shared pointer
138 to this child is handed out to the user.
139
140 When the reference count of this child falls to zero, this shared
141 pointer to its parent is reset by a custom deleter on the child's
142 shared pointer.
143
144 This strategy ensures that the destructors for both the child and
145 the parent are called at the correct time, i.e. only when all
146 references to both the parent and all its children are gone. */
3b161085 147 shared_ptr<Parent> _parent;
7649683c 148
0d0170ae 149 /* Weak pointer for shared_from_this() implementation. */
3b161085 150 weak_ptr<Class> _weak_this;
0d0170ae 151
7649683c 152public:
73a1eb01
ML
153 /* Get parent object that owns this object. */
154 shared_ptr<Parent> parent()
155 {
156 return _parent;
157 }
158
0d0170ae 159 /* Note, this implementation will create a new smart_ptr if none exists. */
bf52cc8c 160 shared_ptr<Class> shared_from_this()
0d0170ae 161 {
bf52cc8c 162 shared_ptr<Class> shared;
0d0170ae 163
3b161085 164 if (!(shared = _weak_this.lock()))
0d0170ae 165 {
ce3e1e61 166 shared = shared_ptr<Class>(static_cast<Class *>(this), reset_parent);
3b161085 167 _weak_this = shared;
0d0170ae
ML
168 }
169
170 return shared;
171 }
172
bf52cc8c 173 shared_ptr<Class> get_shared_pointer(shared_ptr<Parent> parent)
7649683c 174 {
78132e2a
ML
175 if (!parent)
176 throw Error(SR_ERR_BUG);
3b161085 177 this->_parent = parent;
0d0170ae 178 return shared_from_this();
7649683c 179 }
0d0170ae 180
bf52cc8c 181 shared_ptr<Class> get_shared_pointer(Parent *parent)
7649683c 182 {
78132e2a
ML
183 if (!parent)
184 throw Error(SR_ERR_BUG);
bf52cc8c 185 return get_shared_pointer(parent->shared_from_this());
7649683c 186 }
c23c8659 187protected:
bf52cc8c 188 static void reset_parent(Class *object)
7649683c 189 {
3b161085 190 if (!object->_parent)
78132e2a 191 throw Error(SR_ERR_BUG);
3b161085 192 object->_parent.reset();
7649683c
ML
193 }
194
3b161085 195 Struct *_structure;
c23c8659 196
6c11b496 197 explicit ParentOwned(Struct *structure) :
3b161085 198 _structure(structure)
c23c8659
ML
199 {
200 }
201};
202
90e89c2a
ML
203/* Base template for classes whose resources are owned by the user. */
204template <class Class, typename Struct>
205class SR_API UserOwned : public enable_shared_from_this<Class>
206{
207public:
208 shared_ptr<Class> shared_from_this()
209 {
210 auto shared = enable_shared_from_this<Class>::shared_from_this();
211 if (!shared)
212 throw Error(SR_ERR_BUG);
213 return shared;
214 }
215protected:
3b161085 216 Struct *_structure;
90e89c2a 217
6c11b496 218 explicit UserOwned(Struct *structure) :
3b161085 219 _structure(structure)
90e89c2a
ML
220 {
221 }
b4ed33a7
ML
222
223 /* Deleter needed to allow shared_ptr use with protected destructor. */
224 class Deleter
225 {
226 public:
227 void operator()(Class *object) { delete object; }
228 };
90e89c2a
ML
229};
230
c23c8659
ML
231/** Type of log callback */
232typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
233
e2eaf858
DE
234/** Resource reader delegate. */
235class SR_API ResourceReader
236{
237public:
238 ResourceReader() {}
239 virtual ~ResourceReader();
240private:
241 /** Resource open hook. */
242 virtual void open(struct sr_resource *res, string name) = 0;
243 /** Resource close hook. */
244 virtual void close(struct sr_resource *res) = 0;
245 /** Resource read hook. */
246 virtual size_t read(const struct sr_resource *res, void *buf, size_t count) = 0;
247
248 static SR_PRIV int open_callback(struct sr_resource *res,
0ab8e5d2 249 const char *name, void *cb_data) noexcept;
e2eaf858 250 static SR_PRIV int close_callback(struct sr_resource *res,
0ab8e5d2 251 void *cb_data) noexcept;
e2eaf858 252 static SR_PRIV ssize_t read_callback(const struct sr_resource *res,
0ab8e5d2 253 void *buf, size_t count, void *cb_data) noexcept;
e2eaf858
DE
254 friend class Context;
255};
256
07443fd2 257/** The global libsigrok context */
90e89c2a 258class SR_API Context : public UserOwned<Context, struct sr_context>
c23c8659
ML
259{
260public:
261 /** Create new context */
262 static shared_ptr<Context> create();
263 /** libsigrok package version. */
a73d4926 264 static string package_version();
c23c8659 265 /** libsigrok library version. */
a73d4926 266 static string lib_version();
c23c8659 267 /** Available hardware drivers, indexed by name. */
3b161085 268 map<string, shared_ptr<Driver> > drivers();
c23c8659 269 /** Available input formats, indexed by name. */
3b161085 270 map<string, shared_ptr<InputFormat> > input_formats();
c23c8659 271 /** Available output formats, indexed by name. */
3b161085 272 map<string, shared_ptr<OutputFormat> > output_formats();
c23c8659 273 /** Current log level. */
3b161085 274 const LogLevel *log_level();
b6f411ac
ML
275 /** Set the log level.
276 * @param level LogLevel to use. */
c23c8659 277 void set_log_level(const LogLevel *level);
b6f411ac
ML
278 /** Set the log callback.
279 * @param callback Callback of the form callback(LogLevel, string). */
c23c8659
ML
280 void set_log_callback(LogCallbackFunction callback);
281 /** Set the log callback to the default handler. */
282 void set_log_callback_default();
e2eaf858
DE
283 /** Install a delegate for reading resource files.
284 * @param reader The resource reader delegate, or nullptr to unset. */
285 void set_resource_reader(ResourceReader *reader);
c23c8659
ML
286 /** Create a new session. */
287 shared_ptr<Session> create_session();
9fa5b426
ML
288 /** Create a new user device. */
289 shared_ptr<UserDevice> create_user_device(
290 string vendor, string model, string version);
304be4a7
ML
291 /** Create a header packet. */
292 shared_ptr<Packet> create_header_packet(Glib::TimeVal start_time);
293 /** Create a meta packet. */
294 shared_ptr<Packet> create_meta_packet(
d370545d 295 const map<const ConfigKey *, Glib::VariantBase> &config);
304be4a7
ML
296 /** Create a logic packet. */
297 shared_ptr<Packet> create_logic_packet(
298 void *data_pointer, size_t data_length, unsigned int unit_size);
299 /** Create an analog packet. */
dd13d47a 300 shared_ptr<Packet> create_analog_packet(
d370545d 301 const vector<shared_ptr<Channel> > &channels,
304be4a7 302 float *data_pointer, unsigned int num_samples, const Quantity *mq,
d370545d 303 const Unit *unit, const vector<const QuantityFlag *> &mqflags);
b6f411ac
ML
304 /** Load a saved session.
305 * @param filename File name string. */
c23c8659 306 shared_ptr<Session> load_session(string filename);
b6f411ac
ML
307 /** Create a new trigger.
308 * @param name Name string for new trigger. */
c23c8659 309 shared_ptr<Trigger> create_trigger(string name);
ca3291e3
ML
310 /** Open an input file.
311 * @param filename File name string. */
312 shared_ptr<Input> open_file(string filename);
313 /** Open an input stream based on header data.
314 * @param header Initial data from stream. */
315 shared_ptr<Input> open_stream(string header);
24287ea9 316 map<string, string> serials(shared_ptr<Driver> driver);
c23c8659 317protected:
3b161085
ML
318 map<string, Driver *> _drivers;
319 map<string, InputFormat *> _input_formats;
320 map<string, OutputFormat *> _output_formats;
321 Session *_session;
322 LogCallbackFunction _log_callback;
c23c8659
ML
323 Context();
324 ~Context();
c23c8659
ML
325 friend class Deleter;
326 friend class Session;
327 friend class Driver;
328};
329
4c7c4194
ML
330enum Capability {
331 GET = SR_CONF_GET,
332 SET = SR_CONF_SET,
333 LIST = SR_CONF_LIST
334};
335
c23c8659
ML
336/** An object that can be configured. */
337class SR_API Configurable
338{
339public:
b6f411ac
ML
340 /** Read configuration for the given key.
341 * @param key ConfigKey to read. */
c23c8659 342 Glib::VariantBase config_get(const ConfigKey *key);
b6f411ac
ML
343 /** Set configuration for the given key to a specified value.
344 * @param key ConfigKey to set.
345 * @param value Value to set. */
d370545d 346 void config_set(const ConfigKey *key, const Glib::VariantBase &value);
b6f411ac
ML
347 /** Enumerate available values for the given configuration key.
348 * @param key ConfigKey to enumerate values for. */
e194c011 349 Glib::VariantContainerBase config_list(const ConfigKey *key);
d54190a3 350 /** Enumerate available keys, according to a given index key. */
4c7c4194 351 map<const ConfigKey *, set<Capability> > config_keys(const ConfigKey *key);
d9eed47d
ML
352 /** Check for a key in the list from a given index key. */
353 bool config_check(const ConfigKey *key, const ConfigKey *index_key);
c23c8659
ML
354protected:
355 Configurable(
356 struct sr_dev_driver *driver,
357 struct sr_dev_inst *sdi,
358 struct sr_channel_group *channel_group);
359 virtual ~Configurable();
360 struct sr_dev_driver *config_driver;
361 struct sr_dev_inst *config_sdi;
362 struct sr_channel_group *config_channel_group;
363};
364
59b74d28
ML
365/** A hardware driver provided by the library */
366class SR_API Driver :
367 public ParentOwned<Driver, Context, struct sr_dev_driver>,
368 public Configurable
369{
370public:
371 /** Name of this driver. */
3b161085 372 string name();
59b74d28 373 /** Long name for this driver. */
3b161085 374 string long_name();
59b74d28
ML
375 /** Scan for devices and return a list of devices found.
376 * @param options Mapping of (ConfigKey, value) pairs. */
377 vector<shared_ptr<HardwareDevice> > scan(
d370545d 378 const map<const ConfigKey *, Glib::VariantBase> &options = {});
59b74d28 379protected:
3b161085
ML
380 bool _initialized;
381 vector<HardwareDevice *> _devices;
6c11b496 382 explicit Driver(struct sr_dev_driver *structure);
59b74d28
ML
383 ~Driver();
384 friend class Context;
385 friend class HardwareDevice;
386 friend class ChannelGroup;
387};
388
07443fd2 389/** A generic device, either hardware or virtual */
d01d2314 390class SR_API Device : public Configurable
c23c8659
ML
391{
392public:
393 /** Vendor name for this device. */
3b161085 394 string vendor();
c23c8659 395 /** Model name for this device. */
3b161085 396 string model();
c23c8659 397 /** Version string for this device. */
3b161085 398 string version();
d1075e5a
ML
399 /** Serial number for this device. */
400 string serial_number();
401 /** Connection ID for this device. */
402 string connection_id();
c23c8659 403 /** List of the channels available on this device. */
3b161085 404 vector<shared_ptr<Channel> > channels();
6be7a7f2 405 /** Channel groups available on this device, indexed by name. */
3b161085 406 map<string, shared_ptr<ChannelGroup> > channel_groups();
c23c8659
ML
407 /** Open device. */
408 void open();
409 /** Close device. */
410 void close();
411protected:
6c11b496 412 explicit Device(struct sr_dev_inst *structure);
c23c8659 413 ~Device();
d01d2314 414 virtual shared_ptr<Device> get_shared_from_this() = 0;
4178d971 415 shared_ptr<Channel> get_channel(struct sr_channel *ptr);
3b161085
ML
416 struct sr_dev_inst *_structure;
417 map<struct sr_channel *, Channel *> _channels;
418 map<string, ChannelGroup *> _channel_groups;
c23c8659
ML
419 /** Deleter needed to allow shared_ptr use with protected destructor. */
420 class Deleter
421 {
422 public:
423 void operator()(Device *device) { delete device; }
424 };
425 friend class Deleter;
426 friend class Session;
427 friend class Channel;
428 friend class ChannelGroup;
429 friend class Output;
dd13d47a 430 friend class Analog;
c23c8659
ML
431};
432
07443fd2 433/** A real hardware device, connected via a driver */
6e5240f4 434class SR_API HardwareDevice :
a4e47454 435 public UserOwned<HardwareDevice, struct sr_dev_inst>,
6e5240f4 436 public Device
c23c8659
ML
437{
438public:
439 /** Driver providing this device. */
3b161085 440 shared_ptr<Driver> driver();
c23c8659 441protected:
a4e47454 442 HardwareDevice(shared_ptr<Driver> driver, struct sr_dev_inst *structure);
c23c8659 443 ~HardwareDevice();
d01d2314 444 shared_ptr<Device> get_shared_from_this();
a4e47454
ML
445 shared_ptr<Driver> _driver;
446 /** Deleter needed to allow shared_ptr use with protected destructor. */
447 class Deleter
448 {
449 public:
450 void operator()(HardwareDevice *device) { delete device; }
451 };
452 friend class Deleter;
c23c8659
ML
453 friend class Driver;
454 friend class ChannelGroup;
455};
456
9fa5b426
ML
457/** A virtual device, created by the user */
458class SR_API UserDevice :
459 public UserOwned<UserDevice, struct sr_dev_inst>,
460 public Device
461{
462public:
463 /** Add a new channel to this device. */
464 shared_ptr<Channel> add_channel(unsigned int index, const ChannelType *type, string name);
465protected:
466 UserDevice(string vendor, string model, string version);
467 ~UserDevice();
468 shared_ptr<Device> get_shared_from_this();
469 /** Deleter needed to allow shared_ptr use with protected destructor. */
470 class Deleter
471 {
472 public:
473 void operator()(UserDevice *device) { delete device; }
474 };
475 friend class Context;
476 friend class Deleter;
477};
478
07443fd2 479/** A channel on a device */
bf52cc8c 480class SR_API Channel :
541c855e 481 public ParentOwned<Channel, Device, struct sr_channel>
c23c8659
ML
482{
483public:
484 /** Current name of this channel. */
3b161085 485 string name();
b6f411ac
ML
486 /** Set the name of this channel. *
487 * @param name Name string to set. */
c23c8659
ML
488 void set_name(string name);
489 /** Type of this channel. */
3b161085 490 const ChannelType *type();
c23c8659 491 /** Enabled status of this channel. */
3b161085 492 bool enabled();
b6f411ac
ML
493 /** Set the enabled status of this channel.
494 * @param value Boolean value to set. */
c23c8659 495 void set_enabled(bool value);
06bd935e 496 /** Get the index number of this channel. */
3b161085 497 unsigned int index();
c23c8659 498protected:
6c11b496 499 explicit Channel(struct sr_channel *structure);
c23c8659 500 ~Channel();
3b161085 501 const ChannelType * const _type;
c23c8659 502 friend class Device;
9fa5b426 503 friend class UserDevice;
c23c8659
ML
504 friend class ChannelGroup;
505 friend class Session;
506 friend class TriggerStage;
304be4a7 507 friend class Context;
c23c8659
ML
508};
509
07443fd2 510/** A group of channels on a device, which share some configuration */
c23c8659 511class SR_API ChannelGroup :
541c855e 512 public ParentOwned<ChannelGroup, Device, struct sr_channel_group>,
c23c8659
ML
513 public Configurable
514{
515public:
516 /** Name of this channel group. */
3b161085 517 string name();
c23c8659 518 /** List of the channels in this group. */
3b161085 519 vector<shared_ptr<Channel> > channels();
c23c8659 520protected:
6be7a7f2 521 ChannelGroup(Device *device, struct sr_channel_group *structure);
c23c8659 522 ~ChannelGroup();
3b161085 523 vector<Channel *> _channels;
6be7a7f2 524 friend class Device;
c23c8659
ML
525};
526
07443fd2 527/** A trigger configuration */
90e89c2a 528class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
c23c8659
ML
529{
530public:
b6f411ac 531 /** Name of this trigger configuration. */
3b161085 532 string name();
b6f411ac 533 /** List of the stages in this trigger. */
3b161085 534 vector<shared_ptr<TriggerStage> > stages();
b6f411ac 535 /** Add a new stage to this trigger. */
c23c8659
ML
536 shared_ptr<TriggerStage> add_stage();
537protected:
538 Trigger(shared_ptr<Context> context, string name);
539 ~Trigger();
3b161085
ML
540 shared_ptr<Context> _context;
541 vector<TriggerStage *> _stages;
b4ed33a7 542 friend class Deleter;
c23c8659 543 friend class Context;
6fa0eb86 544 friend class Session;
c23c8659
ML
545};
546
07443fd2 547/** A stage in a trigger configuration */
bf52cc8c 548class SR_API TriggerStage :
541c855e 549 public ParentOwned<TriggerStage, Trigger, struct sr_trigger_stage>
c23c8659
ML
550{
551public:
b6f411ac 552 /** Index number of this stage. */
3b161085 553 int number();
b6f411ac 554 /** List of match conditions on this stage. */
3b161085 555 vector<shared_ptr<TriggerMatch> > matches();
b6f411ac
ML
556 /** Add a new match condition to this stage.
557 * @param channel Channel to match on.
558 * @param type TriggerMatchType to apply. */
c23c8659 559 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
b6f411ac
ML
560 /** Add a new match condition to this stage.
561 * @param channel Channel to match on.
562 * @param type TriggerMatchType to apply.
563 * @param value Threshold value. */
c23c8659
ML
564 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
565protected:
3b161085 566 vector<TriggerMatch *> _matches;
6c11b496 567 explicit TriggerStage(struct sr_trigger_stage *structure);
c23c8659
ML
568 ~TriggerStage();
569 friend class Trigger;
570};
571
07443fd2 572/** A match condition in a trigger configuration */
bf52cc8c 573class SR_API TriggerMatch :
541c855e 574 public ParentOwned<TriggerMatch, TriggerStage, struct sr_trigger_match>
c23c8659
ML
575{
576public:
b6f411ac 577 /** Channel this condition matches on. */
3b161085 578 shared_ptr<Channel> channel();
b6f411ac 579 /** Type of match. */
3b161085 580 const TriggerMatchType *type();
b6f411ac 581 /** Threshold value. */
3b161085 582 float value();
c23c8659
ML
583protected:
584 TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
585 ~TriggerMatch();
3b161085 586 shared_ptr<Channel> _channel;
c23c8659
ML
587 friend class TriggerStage;
588};
589
f91cf612
DE
590/** Type of session stopped callback */
591typedef function<void()> SessionStoppedCallback;
592
c23c8659
ML
593/** Type of datafeed callback */
594typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
595 DatafeedCallbackFunction;
596
07443fd2 597/* Data required for C callback function to call a C++ datafeed callback */
c23c8659
ML
598class SR_PRIV DatafeedCallbackData
599{
600public:
601 void run(const struct sr_dev_inst *sdi,
602 const struct sr_datafeed_packet *pkt);
603protected:
3b161085 604 DatafeedCallbackFunction _callback;
c23c8659
ML
605 DatafeedCallbackData(Session *session,
606 DatafeedCallbackFunction callback);
3b161085 607 Session *_session;
c23c8659
ML
608 friend class Session;
609};
610
cac58676
ML
611/** A virtual device associated with a stored session */
612class SR_API SessionDevice :
613 public ParentOwned<SessionDevice, Session, struct sr_dev_inst>,
614 public Device
615{
616protected:
6c11b496 617 explicit SessionDevice(struct sr_dev_inst *sdi);
cac58676
ML
618 ~SessionDevice();
619 shared_ptr<Device> get_shared_from_this();
620 /** Deleter needed to allow shared_ptr use with protected destructor. */
621 class Deleter
622 {
623 public:
624 void operator()(SessionDevice *device) { delete device; }
625 };
626 friend class Deleter;
627 friend class Session;
628};
629
07443fd2 630/** A sigrok session */
90e89c2a 631class SR_API Session : public UserOwned<Session, struct sr_session>
c23c8659
ML
632{
633public:
b6f411ac
ML
634 /** Add a device to this session.
635 * @param device Device to add. */
c23c8659
ML
636 void add_device(shared_ptr<Device> device);
637 /** List devices attached to this session. */
3b161085 638 vector<shared_ptr<Device> > devices();
c23c8659
ML
639 /** Remove all devices from this session. */
640 void remove_devices();
b6f411ac
ML
641 /** Add a datafeed callback to this session.
642 * @param callback Callback of the form callback(Device, Packet). */
c23c8659
ML
643 void add_datafeed_callback(DatafeedCallbackFunction callback);
644 /** Remove all datafeed callbacks from this session. */
645 void remove_datafeed_callbacks();
c23c8659
ML
646 /** Start the session. */
647 void start();
648 /** Run the session event loop. */
649 void run();
650 /** Stop the session. */
651 void stop();
f91cf612
DE
652 /** Return whether the session is running. */
653 bool is_running() const;
654 /** Set callback to be invoked on session stop. */
655 void set_stopped_callback(SessionStoppedCallback callback);
6fa0eb86 656 /** Get current trigger setting. */
3b161085 657 shared_ptr<Trigger> trigger();
624d1610
UH
658 /** Get the context. */
659 shared_ptr<Context> context();
b6f411ac
ML
660 /** Set trigger setting.
661 * @param trigger Trigger object to use. */
6fa0eb86 662 void set_trigger(shared_ptr<Trigger> trigger);
1411f7d8
ML
663 /** Get filename this session was loaded from. */
664 string filename();
c23c8659 665protected:
6c11b496 666 explicit Session(shared_ptr<Context> context);
c23c8659
ML
667 Session(shared_ptr<Context> context, string filename);
668 ~Session();
ca4e307a 669 shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
3b161085 670 const shared_ptr<Context> _context;
ca4e307a
ML
671 map<const struct sr_dev_inst *, SessionDevice *> _owned_devices;
672 map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
3b161085 673 vector<DatafeedCallbackData *> _datafeed_callbacks;
f91cf612 674 SessionStoppedCallback _stopped_callback;
98d39b91 675 string _filename;
3b161085 676 shared_ptr<Trigger> _trigger;
c23c8659
ML
677 friend class Deleter;
678 friend class Context;
679 friend class DatafeedCallbackData;
98d39b91 680 friend class SessionDevice;
c23c8659
ML
681};
682
07443fd2 683/** A packet on the session datafeed */
90e89c2a 684class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
c23c8659
ML
685{
686public:
90ba83f2 687 /** Type of this packet. */
3b161085 688 const PacketType *type();
c23c8659 689 /** Payload of this packet. */
3b161085 690 shared_ptr<PacketPayload> payload();
c23c8659 691protected:
2928f47d
ML
692 Packet(shared_ptr<Device> device,
693 const struct sr_datafeed_packet *structure);
c23c8659 694 ~Packet();
3b161085
ML
695 shared_ptr<Device> _device;
696 PacketPayload *_payload;
c23c8659
ML
697 friend class Deleter;
698 friend class Session;
699 friend class Output;
700 friend class DatafeedCallbackData;
2928f47d
ML
701 friend class Header;
702 friend class Meta;
703 friend class Logic;
dd13d47a 704 friend class Analog;
304be4a7 705 friend class Context;
c23c8659
ML
706};
707
07443fd2 708/** Abstract base class for datafeed packet payloads */
c23c8659
ML
709class SR_API PacketPayload
710{
711protected:
712 PacketPayload();
713 virtual ~PacketPayload() = 0;
4cd883a7 714 virtual shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) = 0;
2928f47d
ML
715 /** Deleter needed to allow shared_ptr use with protected destructor. */
716 class Deleter
717 {
718 public:
719 void operator()(PacketPayload *payload) { delete payload; }
720 };
721 friend class Deleter;
c23c8659
ML
722 friend class Packet;
723 friend class Output;
724};
725
2928f47d 726/** Payload of a datafeed header packet */
4cd883a7 727class SR_API Header :
541c855e 728 public ParentOwned<Header, Packet, const struct sr_datafeed_header>,
4cd883a7 729 public PacketPayload
2928f47d
ML
730{
731public:
b6f411ac 732 /* Feed version number. */
3b161085 733 int feed_version();
b6f411ac 734 /* Start time of this session. */
3b161085 735 Glib::TimeVal start_time();
2928f47d 736protected:
6c11b496 737 explicit Header(const struct sr_datafeed_header *structure);
2928f47d 738 ~Header();
4cd883a7 739 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
2928f47d
ML
740 friend class Packet;
741};
742
743/** Payload of a datafeed metadata packet */
4cd883a7 744class SR_API Meta :
541c855e 745 public ParentOwned<Meta, Packet, const struct sr_datafeed_meta>,
4cd883a7 746 public PacketPayload
2928f47d
ML
747{
748public:
b6f411ac 749 /* Mapping of (ConfigKey, value) pairs. */
3b161085 750 map<const ConfigKey *, Glib::VariantBase> config();
2928f47d 751protected:
6c11b496 752 explicit Meta(const struct sr_datafeed_meta *structure);
2928f47d 753 ~Meta();
4cd883a7 754 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
3b161085 755 map<const ConfigKey *, Glib::VariantBase> _config;
2928f47d
ML
756 friend class Packet;
757};
758
07443fd2 759/** Payload of a datafeed packet with logic data */
4cd883a7 760class SR_API Logic :
541c855e 761 public ParentOwned<Logic, Packet, const struct sr_datafeed_logic>,
4cd883a7 762 public PacketPayload
c23c8659 763{
2928f47d
ML
764public:
765 /* Pointer to data. */
3b161085 766 void *data_pointer();
2928f47d 767 /* Data length in bytes. */
3b161085 768 size_t data_length();
2928f47d 769 /* Size of each sample in bytes. */
3b161085 770 unsigned int unit_size();
c23c8659 771protected:
6c11b496 772 explicit Logic(const struct sr_datafeed_logic *structure);
c23c8659 773 ~Logic();
4cd883a7 774 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
c23c8659
ML
775 friend class Packet;
776};
777
07443fd2 778/** Payload of a datafeed packet with analog data */
dd13d47a
UH
779class SR_API Analog :
780 public ParentOwned<Analog, Packet, const struct sr_datafeed_analog>,
4cd883a7 781 public PacketPayload
c23c8659
ML
782{
783public:
2928f47d 784 /** Pointer to data. */
dd13d47a 785 void *data_pointer();
c23c8659 786 /** Number of samples in this packet. */
dd13d47a 787 uint32_t num_samples();
2928f47d 788 /** Channels for which this packet contains data. */
3b161085 789 vector<shared_ptr<Channel> > channels();
c23c8659 790 /** Measured quantity of the samples in this packet. */
3b161085 791 const Quantity *mq();
c23c8659 792 /** Unit of the samples in this packet. */
3b161085 793 const Unit *unit();
c23c8659 794 /** Measurement flags associated with the samples in this packet. */
3b161085 795 vector<const QuantityFlag *> mq_flags();
c23c8659 796protected:
6c11b496 797 explicit Analog(const struct sr_datafeed_analog *structure);
dd13d47a 798 ~Analog();
4cd883a7 799 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
c23c8659
ML
800 friend class Packet;
801};
802
07443fd2 803/** An input format supported by the library */
c23c8659 804class SR_API InputFormat :
541c855e 805 public ParentOwned<InputFormat, Context, const struct sr_input_module>
c23c8659
ML
806{
807public:
808 /** Name of this input format. */
3b161085 809 string name();
c23c8659 810 /** Description of this input format. */
3b161085 811 string description();
c7bc82ff
JH
812 /** A list of preferred file name extensions for this file format.
813 * @note This list is a recommendation only. */
814 vector<string> extensions();
ca3291e3 815 /** Options supported by this input format. */
3b161085 816 map<string, shared_ptr<Option> > options();
ca3291e3
ML
817 /** Create an input using this input format.
818 * @param options Mapping of (option name, value) pairs. */
d370545d 819 shared_ptr<Input> create_input(const map<string, Glib::VariantBase> &options = {});
c23c8659 820protected:
6c11b496 821 explicit InputFormat(const struct sr_input_module *structure);
c23c8659
ML
822 ~InputFormat();
823 friend class Context;
ca3291e3 824 friend class InputDevice;
c23c8659
ML
825};
826
ca3291e3 827/** An input instance (an input format applied to a file or stream) */
90e89c2a 828class SR_API Input : public UserOwned<Input, const struct sr_input>
c23c8659
ML
829{
830public:
ca3291e3 831 /** Virtual device associated with this input. */
3b161085 832 shared_ptr<InputDevice> device();
ca3291e3 833 /** Send next stream data.
2b51d48b
ML
834 * @param data Next stream data.
835 * @param length Length of data. */
836 void send(void *data, size_t length);
9c51e8ec
ML
837 /** Signal end of input data. */
838 void end();
c23c8659 839protected:
ca3291e3
ML
840 Input(shared_ptr<Context> context, const struct sr_input *structure);
841 ~Input();
3b161085
ML
842 shared_ptr<Context> _context;
843 InputDevice *_device;
c23c8659 844 friend class Deleter;
ca3291e3 845 friend class Context;
c23c8659
ML
846 friend class InputFormat;
847};
848
ca3291e3 849/** A virtual device associated with an input */
6e5240f4 850class SR_API InputDevice :
541c855e 851 public ParentOwned<InputDevice, Input, struct sr_dev_inst>,
6e5240f4 852 public Device
ca3291e3
ML
853{
854protected:
855 InputDevice(shared_ptr<Input> input, struct sr_dev_inst *sdi);
856 ~InputDevice();
d01d2314 857 shared_ptr<Device> get_shared_from_this();
3b161085 858 shared_ptr<Input> _input;
ca3291e3
ML
859 friend class Input;
860};
861
58aa1f83 862/** An option used by an output format */
90e89c2a 863class SR_API Option : public UserOwned<Option, const struct sr_option>
58aa1f83
ML
864{
865public:
866 /** Short name of this option suitable for command line usage. */
3b161085 867 string id();
58aa1f83 868 /** Short name of this option suitable for GUI usage. */
3b161085 869 string name();
58aa1f83 870 /** Description of this option in a sentence. */
3b161085 871 string description();
58aa1f83 872 /** Default value for this option. */
3b161085 873 Glib::VariantBase default_value();
58aa1f83 874 /** Possible values for this option, if a limited set. */
3b161085 875 vector<Glib::VariantBase> values();
58aa1f83
ML
876protected:
877 Option(const struct sr_option *structure,
70d3b20b 878 shared_ptr<const struct sr_option *> structure_array);
58aa1f83 879 ~Option();
3b161085 880 shared_ptr<const struct sr_option *> _structure_array;
58aa1f83 881 friend class Deleter;
43942280 882 friend class InputFormat;
58aa1f83
ML
883 friend class OutputFormat;
884};
885
07443fd2 886/** An output format supported by the library */
c23c8659 887class SR_API OutputFormat :
541c855e 888 public ParentOwned<OutputFormat, Context, const struct sr_output_module>
c23c8659
ML
889{
890public:
891 /** Name of this output format. */
3b161085 892 string name();
c23c8659 893 /** Description of this output format. */
3b161085 894 string description();
8a174d23
JH
895 /** A list of preferred file name extensions for this file format.
896 * @note This list is a recommendation only. */
897 vector<string> extensions();
58aa1f83 898 /** Options supported by this output format. */
3b161085 899 map<string, shared_ptr<Option> > options();
b6f411ac
ML
900 /** Create an output using this format.
901 * @param device Device to output for.
902 * @param options Mapping of (option name, value) pairs. */
81b3ce37
SA
903 shared_ptr<Output> create_output(
904 shared_ptr<Device> device,
d370545d 905 const map<string, Glib::VariantBase> &options = {});
81b3ce37
SA
906 /** Create an output using this format.
907 * @param filename Name of destination file.
908 * @param device Device to output for.
909 * @param options Mapping of (option name, value) pairs. */
910 shared_ptr<Output> create_output(string filename,
911 shared_ptr<Device> device,
d370545d 912 const map<string, Glib::VariantBase> &options = {});
3cd4b381
SA
913 /**
914 * Checks whether a given flag is set.
915 * @param flag Flag to check
916 * @return true if flag is set for this module
917 * @see sr_output_flags
918 */
919 bool test_flag(const OutputFlag *flag);
c23c8659 920protected:
6c11b496 921 explicit OutputFormat(const struct sr_output_module *structure);
c23c8659
ML
922 ~OutputFormat();
923 friend class Context;
924 friend class Output;
925};
926
07443fd2 927/** An output instance (an output format applied to a device) */
90e89c2a 928class SR_API Output : public UserOwned<Output, const struct sr_output>
c23c8659
ML
929{
930public:
b6f411ac
ML
931 /** Update output with data from the given packet.
932 * @param packet Packet to handle. */
c23c8659
ML
933 string receive(shared_ptr<Packet> packet);
934protected:
935 Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
936 Output(shared_ptr<OutputFormat> format,
d370545d 937 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
81b3ce37 938 Output(string filename, shared_ptr<OutputFormat> format,
d370545d 939 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
c23c8659 940 ~Output();
3b161085
ML
941 const shared_ptr<OutputFormat> _format;
942 const shared_ptr<Device> _device;
943 const map<string, Glib::VariantBase> _options;
c23c8659
ML
944 friend class Deleter;
945 friend class OutputFormat;
946};
947
948/** Base class for objects which wrap an enumeration value from libsigrok */
9d229ecb 949template <class Class, typename Enum> class SR_API EnumValue
c23c8659
ML
950{
951public:
9d229ecb
ML
952 /** The integer constant associated with this value. */
953 int id() const
954 {
955 return static_cast<int>(_id);
956 }
c23c8659 957 /** The name associated with this value. */
9d229ecb
ML
958 string name() const
959 {
960 return _name;
961 }
962 /** Get value associated with a given integer constant. */
963 static const Class *get(int id)
964 {
965 auto key = static_cast<Enum>(id);
966 if (_values.find(key) == _values.end())
967 throw Error(SR_ERR_ARG);
968 return _values.at(key);
969 }
970 /** Get possible values. */
971 static std::vector<const Class *> values()
972 {
973 std::vector<const Class *> result;
974 for (auto entry : _values)
975 result.push_back(entry.second);
976 return result;
977 }
c23c8659 978protected:
9d229ecb
ML
979 EnumValue(Enum id, const char name[]) : _id(id), _name(name)
980 {
981 }
982 ~EnumValue()
983 {
984 }
985 static const std::map<const Enum, const Class * const> _values;
986 const Enum _id;
3b161085 987 const string _name;
c23c8659
ML
988};
989
8b2a1843 990#include <libsigrokcxx/enums.hpp>
c23c8659
ML
991
992}
993
1b40fdb8 994#endif