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