]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp
C++: Use smart pointers instead of manual delete
[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;
f17b4546
DE
303 map<string, unique_ptr<Driver> > _drivers;
304 map<string, unique_ptr<InputFormat> > _input_formats;
305 map<string, unique_ptr<OutputFormat> > _output_formats;
3b161085
ML
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;
f17b4546 373 friend class std::default_delete<Driver>;
59b74d28
ML
374};
375
07443fd2 376/** A generic device, either hardware or virtual */
d01d2314 377class SR_API Device : public Configurable
c23c8659
ML
378{
379public:
380 /** Vendor name for this device. */
15bebf57 381 string vendor() const;
c23c8659 382 /** Model name for this device. */
15bebf57 383 string model() const;
c23c8659 384 /** Version string for this device. */
15bebf57 385 string version() const;
d1075e5a 386 /** Serial number for this device. */
15bebf57 387 string serial_number() const;
d1075e5a 388 /** Connection ID for this device. */
15bebf57 389 string connection_id() const;
c23c8659 390 /** List of the channels available on this device. */
3b161085 391 vector<shared_ptr<Channel> > channels();
6be7a7f2 392 /** Channel groups available on this device, indexed by name. */
3b161085 393 map<string, shared_ptr<ChannelGroup> > channel_groups();
c23c8659
ML
394 /** Open device. */
395 void open();
396 /** Close device. */
397 void close();
398protected:
6c11b496 399 explicit Device(struct sr_dev_inst *structure);
c23c8659 400 ~Device();
d01d2314 401 virtual shared_ptr<Device> get_shared_from_this() = 0;
4178d971 402 shared_ptr<Channel> get_channel(struct sr_channel *ptr);
21d1bec6 403
3b161085 404 struct sr_dev_inst *_structure;
f17b4546 405 map<struct sr_channel *, unique_ptr<Channel> > _channels;
21d1bec6 406private:
f17b4546 407 map<string, unique_ptr<ChannelGroup> > _channel_groups;
c23c8659
ML
408 /** Deleter needed to allow shared_ptr use with protected destructor. */
409 class Deleter
410 {
411 public:
412 void operator()(Device *device) { delete device; }
413 };
414 friend class Deleter;
415 friend class Session;
416 friend class Channel;
417 friend class ChannelGroup;
418 friend class Output;
dd13d47a 419 friend class Analog;
c23c8659
ML
420};
421
07443fd2 422/** A real hardware device, connected via a driver */
6e5240f4 423class SR_API HardwareDevice :
d5d7b09e 424 public UserOwned<HardwareDevice>,
6e5240f4 425 public Device
c23c8659
ML
426{
427public:
428 /** Driver providing this device. */
3b161085 429 shared_ptr<Driver> driver();
21d1bec6 430private:
a4e47454 431 HardwareDevice(shared_ptr<Driver> driver, struct sr_dev_inst *structure);
c23c8659 432 ~HardwareDevice();
d01d2314 433 shared_ptr<Device> get_shared_from_this();
a4e47454
ML
434 shared_ptr<Driver> _driver;
435 /** Deleter needed to allow shared_ptr use with protected destructor. */
436 class Deleter
437 {
438 public:
439 void operator()(HardwareDevice *device) { delete device; }
440 };
441 friend class Deleter;
c23c8659
ML
442 friend class Driver;
443 friend class ChannelGroup;
444};
445
9fa5b426
ML
446/** A virtual device, created by the user */
447class SR_API UserDevice :
d5d7b09e 448 public UserOwned<UserDevice>,
9fa5b426
ML
449 public Device
450{
451public:
452 /** Add a new channel to this device. */
453 shared_ptr<Channel> add_channel(unsigned int index, const ChannelType *type, string name);
21d1bec6 454private:
9fa5b426
ML
455 UserDevice(string vendor, string model, string version);
456 ~UserDevice();
457 shared_ptr<Device> get_shared_from_this();
458 /** Deleter needed to allow shared_ptr use with protected destructor. */
459 class Deleter
460 {
461 public:
462 void operator()(UserDevice *device) { delete device; }
463 };
464 friend class Context;
465 friend class Deleter;
466};
467
07443fd2 468/** A channel on a device */
bf52cc8c 469class SR_API Channel :
d5d7b09e 470 public ParentOwned<Channel, Device>
c23c8659
ML
471{
472public:
473 /** Current name of this channel. */
15bebf57 474 string name() const;
b6f411ac
ML
475 /** Set the name of this channel. *
476 * @param name Name string to set. */
c23c8659
ML
477 void set_name(string name);
478 /** Type of this channel. */
15bebf57 479 const ChannelType *type() const;
c23c8659 480 /** Enabled status of this channel. */
15bebf57 481 bool enabled() const;
b6f411ac
ML
482 /** Set the enabled status of this channel.
483 * @param value Boolean value to set. */
c23c8659 484 void set_enabled(bool value);
06bd935e 485 /** Get the index number of this channel. */
15bebf57 486 unsigned int index() const;
21d1bec6 487private:
6c11b496 488 explicit Channel(struct sr_channel *structure);
c23c8659 489 ~Channel();
d5d7b09e 490 struct sr_channel *_structure;
3b161085 491 const ChannelType * const _type;
c23c8659 492 friend class Device;
9fa5b426 493 friend class UserDevice;
c23c8659
ML
494 friend class ChannelGroup;
495 friend class Session;
496 friend class TriggerStage;
304be4a7 497 friend class Context;
f17b4546 498 friend class std::default_delete<Channel>;
c23c8659
ML
499};
500
07443fd2 501/** A group of channels on a device, which share some configuration */
c23c8659 502class SR_API ChannelGroup :
d5d7b09e 503 public ParentOwned<ChannelGroup, Device>,
c23c8659
ML
504 public Configurable
505{
506public:
507 /** Name of this channel group. */
15bebf57 508 string name() const;
c23c8659 509 /** List of the channels in this group. */
3b161085 510 vector<shared_ptr<Channel> > channels();
21d1bec6 511private:
f17b4546 512 ChannelGroup(const Device *device, struct sr_channel_group *structure);
c23c8659 513 ~ChannelGroup();
3b161085 514 vector<Channel *> _channels;
6be7a7f2 515 friend class Device;
f17b4546 516 friend class std::default_delete<ChannelGroup>;
c23c8659
ML
517};
518
07443fd2 519/** A trigger configuration */
d5d7b09e 520class SR_API Trigger : public UserOwned<Trigger>
c23c8659
ML
521{
522public:
b6f411ac 523 /** Name of this trigger configuration. */
15bebf57 524 string name() const;
b6f411ac 525 /** List of the stages in this trigger. */
3b161085 526 vector<shared_ptr<TriggerStage> > stages();
b6f411ac 527 /** Add a new stage to this trigger. */
c23c8659 528 shared_ptr<TriggerStage> add_stage();
21d1bec6 529private:
c23c8659
ML
530 Trigger(shared_ptr<Context> context, string name);
531 ~Trigger();
d5d7b09e 532 struct sr_trigger *_structure;
3b161085 533 shared_ptr<Context> _context;
f17b4546 534 vector<unique_ptr<TriggerStage> > _stages;
b4ed33a7 535 friend class Deleter;
c23c8659 536 friend class Context;
6fa0eb86 537 friend class Session;
c23c8659
ML
538};
539
07443fd2 540/** A stage in a trigger configuration */
bf52cc8c 541class SR_API TriggerStage :
d5d7b09e 542 public ParentOwned<TriggerStage, Trigger>
c23c8659
ML
543{
544public:
b6f411ac 545 /** Index number of this stage. */
15bebf57 546 int number() const;
b6f411ac 547 /** List of match conditions on this stage. */
3b161085 548 vector<shared_ptr<TriggerMatch> > matches();
b6f411ac
ML
549 /** Add a new match condition to this stage.
550 * @param channel Channel to match on.
551 * @param type TriggerMatchType to apply. */
c23c8659 552 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
b6f411ac
ML
553 /** Add a new match condition to this stage.
554 * @param channel Channel to match on.
555 * @param type TriggerMatchType to apply.
556 * @param value Threshold value. */
c23c8659 557 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
21d1bec6 558private:
d5d7b09e 559 struct sr_trigger_stage *_structure;
f17b4546 560 vector<unique_ptr<TriggerMatch> > _matches;
6c11b496 561 explicit TriggerStage(struct sr_trigger_stage *structure);
c23c8659
ML
562 ~TriggerStage();
563 friend class Trigger;
f17b4546 564 friend class std::default_delete<TriggerStage>;
c23c8659
ML
565};
566
07443fd2 567/** A match condition in a trigger configuration */
bf52cc8c 568class SR_API TriggerMatch :
d5d7b09e 569 public ParentOwned<TriggerMatch, TriggerStage>
c23c8659
ML
570{
571public:
b6f411ac 572 /** Channel this condition matches on. */
3b161085 573 shared_ptr<Channel> channel();
b6f411ac 574 /** Type of match. */
15bebf57 575 const TriggerMatchType *type() const;
b6f411ac 576 /** Threshold value. */
15bebf57 577 float value() const;
21d1bec6 578private:
c23c8659
ML
579 TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
580 ~TriggerMatch();
d5d7b09e 581 struct sr_trigger_match *_structure;
3b161085 582 shared_ptr<Channel> _channel;
c23c8659 583 friend class TriggerStage;
f17b4546 584 friend class std::default_delete<TriggerMatch>;
c23c8659
ML
585};
586
f91cf612
DE
587/** Type of session stopped callback */
588typedef function<void()> SessionStoppedCallback;
589
c23c8659
ML
590/** Type of datafeed callback */
591typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
592 DatafeedCallbackFunction;
593
07443fd2 594/* Data required for C callback function to call a C++ datafeed callback */
c23c8659
ML
595class SR_PRIV DatafeedCallbackData
596{
597public:
598 void run(const struct sr_dev_inst *sdi,
599 const struct sr_datafeed_packet *pkt);
21d1bec6 600private:
3b161085 601 DatafeedCallbackFunction _callback;
c23c8659
ML
602 DatafeedCallbackData(Session *session,
603 DatafeedCallbackFunction callback);
3b161085 604 Session *_session;
c23c8659
ML
605 friend class Session;
606};
607
cac58676
ML
608/** A virtual device associated with a stored session */
609class SR_API SessionDevice :
d5d7b09e 610 public ParentOwned<SessionDevice, Session>,
cac58676
ML
611 public Device
612{
21d1bec6 613private:
6c11b496 614 explicit SessionDevice(struct sr_dev_inst *sdi);
cac58676
ML
615 ~SessionDevice();
616 shared_ptr<Device> get_shared_from_this();
617 /** Deleter needed to allow shared_ptr use with protected destructor. */
618 class Deleter
619 {
620 public:
621 void operator()(SessionDevice *device) { delete device; }
622 };
623 friend class Deleter;
624 friend class Session;
f17b4546 625 friend class std::default_delete<SessionDevice>;
cac58676
ML
626};
627
07443fd2 628/** A sigrok session */
d5d7b09e 629class SR_API Session : public UserOwned<Session>
c23c8659
ML
630{
631public:
b6f411ac
ML
632 /** Add a device to this session.
633 * @param device Device to add. */
c23c8659
ML
634 void add_device(shared_ptr<Device> device);
635 /** List devices attached to this session. */
3b161085 636 vector<shared_ptr<Device> > devices();
c23c8659
ML
637 /** Remove all devices from this session. */
638 void remove_devices();
b6f411ac
ML
639 /** Add a datafeed callback to this session.
640 * @param callback Callback of the form callback(Device, Packet). */
c23c8659
ML
641 void add_datafeed_callback(DatafeedCallbackFunction callback);
642 /** Remove all datafeed callbacks from this session. */
643 void remove_datafeed_callbacks();
c23c8659
ML
644 /** Start the session. */
645 void start();
646 /** Run the session event loop. */
647 void run();
648 /** Stop the session. */
649 void stop();
f91cf612
DE
650 /** Return whether the session is running. */
651 bool is_running() const;
652 /** Set callback to be invoked on session stop. */
653 void set_stopped_callback(SessionStoppedCallback callback);
6fa0eb86 654 /** Get current trigger setting. */
3b161085 655 shared_ptr<Trigger> trigger();
624d1610
UH
656 /** Get the context. */
657 shared_ptr<Context> context();
b6f411ac
ML
658 /** Set trigger setting.
659 * @param trigger Trigger object to use. */
6fa0eb86 660 void set_trigger(shared_ptr<Trigger> trigger);
1411f7d8 661 /** Get filename this session was loaded from. */
15bebf57 662 string filename() const;
21d1bec6 663private:
6c11b496 664 explicit Session(shared_ptr<Context> context);
c23c8659
ML
665 Session(shared_ptr<Context> context, string filename);
666 ~Session();
ca4e307a 667 shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
d5d7b09e 668 struct sr_session *_structure;
3b161085 669 const shared_ptr<Context> _context;
f17b4546 670 map<const struct sr_dev_inst *, unique_ptr<SessionDevice> > _owned_devices;
ca4e307a 671 map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
f17b4546 672 vector<unique_ptr<DatafeedCallbackData> > _datafeed_callbacks;
f91cf612 673 SessionStoppedCallback _stopped_callback;
98d39b91 674 string _filename;
3b161085 675 shared_ptr<Trigger> _trigger;
c23c8659
ML
676 friend class Deleter;
677 friend class Context;
678 friend class DatafeedCallbackData;
98d39b91 679 friend class SessionDevice;
c23c8659
ML
680};
681
07443fd2 682/** A packet on the session datafeed */
d5d7b09e 683class SR_API Packet : public UserOwned<Packet>
c23c8659
ML
684{
685public:
90ba83f2 686 /** Type of this packet. */
15bebf57 687 const PacketType *type() const;
c23c8659 688 /** Payload of this packet. */
3b161085 689 shared_ptr<PacketPayload> payload();
21d1bec6 690private:
2928f47d
ML
691 Packet(shared_ptr<Device> device,
692 const struct sr_datafeed_packet *structure);
c23c8659 693 ~Packet();
d5d7b09e 694 const struct sr_datafeed_packet *_structure;
3b161085 695 shared_ptr<Device> _device;
f17b4546 696 unique_ptr<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;
67b82fc9 714private:
b6ab954d 715 virtual shared_ptr<PacketPayload> share_owned_by(shared_ptr<Packet> parent) = 0;
21d1bec6 716
67b82fc9
DE
717 /** Deleter needed to allow shared_ptr use with protected destructor. */
718 class Deleter
719 {
720 public:
721 void operator()(PacketPayload *payload) { delete payload; }
722 };
2928f47d 723 friend class Deleter;
c23c8659
ML
724 friend class Packet;
725 friend class Output;
f17b4546 726 friend class std::default_delete<PacketPayload>;
c23c8659
ML
727};
728
2928f47d 729/** Payload of a datafeed header packet */
4cd883a7 730class SR_API Header :
d5d7b09e 731 public ParentOwned<Header, Packet>,
4cd883a7 732 public PacketPayload
2928f47d
ML
733{
734public:
b6f411ac 735 /* Feed version number. */
15bebf57 736 int feed_version() const;
b6f411ac 737 /* Start time of this session. */
15bebf57 738 Glib::TimeVal start_time() const;
21d1bec6 739private:
6c11b496 740 explicit Header(const struct sr_datafeed_header *structure);
2928f47d 741 ~Header();
b6ab954d 742 shared_ptr<PacketPayload> share_owned_by(shared_ptr<Packet> parent);
d5d7b09e
DE
743
744 const struct sr_datafeed_header *_structure;
745
2928f47d
ML
746 friend class Packet;
747};
748
749/** Payload of a datafeed metadata packet */
4cd883a7 750class SR_API Meta :
d5d7b09e 751 public ParentOwned<Meta, Packet>,
4cd883a7 752 public PacketPayload
2928f47d
ML
753{
754public:
b6f411ac 755 /* Mapping of (ConfigKey, value) pairs. */
15bebf57 756 map<const ConfigKey *, Glib::VariantBase> config() const;
21d1bec6 757private:
6c11b496 758 explicit Meta(const struct sr_datafeed_meta *structure);
2928f47d 759 ~Meta();
b6ab954d 760 shared_ptr<PacketPayload> share_owned_by(shared_ptr<Packet> parent);
d5d7b09e
DE
761
762 const struct sr_datafeed_meta *_structure;
3b161085 763 map<const ConfigKey *, Glib::VariantBase> _config;
d5d7b09e 764
2928f47d
ML
765 friend class Packet;
766};
767
07443fd2 768/** Payload of a datafeed packet with logic data */
4cd883a7 769class SR_API Logic :
d5d7b09e 770 public ParentOwned<Logic, Packet>,
4cd883a7 771 public PacketPayload
c23c8659 772{
2928f47d
ML
773public:
774 /* Pointer to data. */
3b161085 775 void *data_pointer();
2928f47d 776 /* Data length in bytes. */
15bebf57 777 size_t data_length() const;
2928f47d 778 /* Size of each sample in bytes. */
15bebf57 779 unsigned int unit_size() const;
21d1bec6 780private:
6c11b496 781 explicit Logic(const struct sr_datafeed_logic *structure);
c23c8659 782 ~Logic();
b6ab954d 783 shared_ptr<PacketPayload> share_owned_by(shared_ptr<Packet> parent);
d5d7b09e
DE
784
785 const struct sr_datafeed_logic *_structure;
786
c23c8659
ML
787 friend class Packet;
788};
789
07443fd2 790/** Payload of a datafeed packet with analog data */
dd13d47a 791class SR_API Analog :
d5d7b09e 792 public ParentOwned<Analog, Packet>,
4cd883a7 793 public PacketPayload
c23c8659
ML
794{
795public:
2928f47d 796 /** Pointer to data. */
dd13d47a 797 void *data_pointer();
c23c8659 798 /** Number of samples in this packet. */
15bebf57 799 unsigned int num_samples() const;
2928f47d 800 /** Channels for which this packet contains data. */
3b161085 801 vector<shared_ptr<Channel> > channels();
c23c8659 802 /** Measured quantity of the samples in this packet. */
15bebf57 803 const Quantity *mq() const;
c23c8659 804 /** Unit of the samples in this packet. */
15bebf57 805 const Unit *unit() const;
c23c8659 806 /** Measurement flags associated with the samples in this packet. */
15bebf57 807 vector<const QuantityFlag *> mq_flags() const;
21d1bec6 808private:
6c11b496 809 explicit Analog(const struct sr_datafeed_analog *structure);
dd13d47a 810 ~Analog();
b6ab954d 811 shared_ptr<PacketPayload> share_owned_by(shared_ptr<Packet> parent);
d5d7b09e
DE
812
813 const struct sr_datafeed_analog *_structure;
814
c23c8659
ML
815 friend class Packet;
816};
817
07443fd2 818/** An input format supported by the library */
c23c8659 819class SR_API InputFormat :
d5d7b09e 820 public ParentOwned<InputFormat, Context>
c23c8659
ML
821{
822public:
823 /** Name of this input format. */
15bebf57 824 string name() const;
c23c8659 825 /** Description of this input format. */
15bebf57 826 string description() const;
c7bc82ff
JH
827 /** A list of preferred file name extensions for this file format.
828 * @note This list is a recommendation only. */
15bebf57 829 vector<string> extensions() const;
ca3291e3 830 /** Options supported by this input format. */
3b161085 831 map<string, shared_ptr<Option> > options();
ca3291e3
ML
832 /** Create an input using this input format.
833 * @param options Mapping of (option name, value) pairs. */
d370545d 834 shared_ptr<Input> create_input(const map<string, Glib::VariantBase> &options = {});
21d1bec6 835private:
6c11b496 836 explicit InputFormat(const struct sr_input_module *structure);
c23c8659 837 ~InputFormat();
d5d7b09e
DE
838
839 const struct sr_input_module *_structure;
840
c23c8659 841 friend class Context;
ca3291e3 842 friend class InputDevice;
f17b4546 843 friend class std::default_delete<InputFormat>;
c23c8659
ML
844};
845
ca3291e3 846/** An input instance (an input format applied to a file or stream) */
d5d7b09e 847class SR_API Input : public UserOwned<Input>
c23c8659
ML
848{
849public:
ca3291e3 850 /** Virtual device associated with this input. */
3b161085 851 shared_ptr<InputDevice> device();
ca3291e3 852 /** Send next stream data.
2b51d48b
ML
853 * @param data Next stream data.
854 * @param length Length of data. */
855 void send(void *data, size_t length);
9c51e8ec
ML
856 /** Signal end of input data. */
857 void end();
21d1bec6 858private:
ca3291e3
ML
859 Input(shared_ptr<Context> context, const struct sr_input *structure);
860 ~Input();
d5d7b09e 861 const struct sr_input *_structure;
3b161085 862 shared_ptr<Context> _context;
f17b4546 863 unique_ptr<InputDevice> _device;
c23c8659 864 friend class Deleter;
ca3291e3 865 friend class Context;
c23c8659
ML
866 friend class InputFormat;
867};
868
ca3291e3 869/** A virtual device associated with an input */
6e5240f4 870class SR_API InputDevice :
d5d7b09e 871 public ParentOwned<InputDevice, Input>,
6e5240f4 872 public Device
ca3291e3 873{
21d1bec6 874private:
ca3291e3
ML
875 InputDevice(shared_ptr<Input> input, struct sr_dev_inst *sdi);
876 ~InputDevice();
d01d2314 877 shared_ptr<Device> get_shared_from_this();
3b161085 878 shared_ptr<Input> _input;
ca3291e3 879 friend class Input;
f17b4546 880 friend class std::default_delete<InputDevice>;
ca3291e3
ML
881};
882
58aa1f83 883/** An option used by an output format */
d5d7b09e 884class SR_API Option : public UserOwned<Option>
58aa1f83
ML
885{
886public:
887 /** Short name of this option suitable for command line usage. */
15bebf57 888 string id() const;
58aa1f83 889 /** Short name of this option suitable for GUI usage. */
15bebf57 890 string name() const;
58aa1f83 891 /** Description of this option in a sentence. */
15bebf57 892 string description() const;
58aa1f83 893 /** Default value for this option. */
15bebf57 894 Glib::VariantBase default_value() const;
58aa1f83 895 /** Possible values for this option, if a limited set. */
15bebf57 896 vector<Glib::VariantBase> values() const;
21d1bec6 897private:
58aa1f83 898 Option(const struct sr_option *structure,
70d3b20b 899 shared_ptr<const struct sr_option *> structure_array);
58aa1f83 900 ~Option();
d5d7b09e 901 const struct sr_option *_structure;
3b161085 902 shared_ptr<const struct sr_option *> _structure_array;
58aa1f83 903 friend class Deleter;
43942280 904 friend class InputFormat;
58aa1f83
ML
905 friend class OutputFormat;
906};
907
07443fd2 908/** An output format supported by the library */
c23c8659 909class SR_API OutputFormat :
d5d7b09e 910 public ParentOwned<OutputFormat, Context>
c23c8659
ML
911{
912public:
913 /** Name of this output format. */
15bebf57 914 string name() const;
c23c8659 915 /** Description of this output format. */
15bebf57 916 string description() const;
8a174d23
JH
917 /** A list of preferred file name extensions for this file format.
918 * @note This list is a recommendation only. */
15bebf57 919 vector<string> extensions() const;
58aa1f83 920 /** Options supported by this output format. */
3b161085 921 map<string, shared_ptr<Option> > options();
b6f411ac
ML
922 /** Create an output using this format.
923 * @param device Device to output for.
924 * @param options Mapping of (option name, value) pairs. */
81b3ce37
SA
925 shared_ptr<Output> create_output(
926 shared_ptr<Device> device,
d370545d 927 const map<string, Glib::VariantBase> &options = {});
81b3ce37
SA
928 /** Create an output using this format.
929 * @param filename Name of destination file.
930 * @param device Device to output for.
931 * @param options Mapping of (option name, value) pairs. */
932 shared_ptr<Output> create_output(string filename,
933 shared_ptr<Device> device,
d370545d 934 const map<string, Glib::VariantBase> &options = {});
3cd4b381
SA
935 /**
936 * Checks whether a given flag is set.
937 * @param flag Flag to check
938 * @return true if flag is set for this module
939 * @see sr_output_flags
940 */
15bebf57 941 bool test_flag(const OutputFlag *flag) const;
21d1bec6 942private:
6c11b496 943 explicit OutputFormat(const struct sr_output_module *structure);
c23c8659 944 ~OutputFormat();
d5d7b09e
DE
945
946 const struct sr_output_module *_structure;
947
c23c8659
ML
948 friend class Context;
949 friend class Output;
f17b4546 950 friend class std::default_delete<OutputFormat>;
c23c8659
ML
951};
952
07443fd2 953/** An output instance (an output format applied to a device) */
d5d7b09e 954class SR_API Output : public UserOwned<Output>
c23c8659
ML
955{
956public:
b6f411ac
ML
957 /** Update output with data from the given packet.
958 * @param packet Packet to handle. */
c23c8659 959 string receive(shared_ptr<Packet> packet);
21d1bec6 960private:
c23c8659
ML
961 Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
962 Output(shared_ptr<OutputFormat> format,
d370545d 963 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
81b3ce37 964 Output(string filename, shared_ptr<OutputFormat> format,
d370545d 965 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
c23c8659 966 ~Output();
d5d7b09e
DE
967
968 const struct sr_output *_structure;
3b161085
ML
969 const shared_ptr<OutputFormat> _format;
970 const shared_ptr<Device> _device;
971 const map<string, Glib::VariantBase> _options;
d5d7b09e 972
c23c8659
ML
973 friend class Deleter;
974 friend class OutputFormat;
975};
976
977/** Base class for objects which wrap an enumeration value from libsigrok */
9d229ecb 978template <class Class, typename Enum> class SR_API EnumValue
c23c8659
ML
979{
980public:
9d229ecb
ML
981 /** The integer constant associated with this value. */
982 int id() const
983 {
984 return static_cast<int>(_id);
985 }
c23c8659 986 /** The name associated with this value. */
9d229ecb
ML
987 string name() const
988 {
989 return _name;
990 }
991 /** Get value associated with a given integer constant. */
992 static const Class *get(int id)
993 {
15bebf57
DE
994 const auto pos = _values.find(static_cast<Enum>(id));
995 if (pos == _values.end())
9d229ecb 996 throw Error(SR_ERR_ARG);
15bebf57 997 return pos->second;
9d229ecb
ML
998 }
999 /** Get possible values. */
1000 static std::vector<const Class *> values()
1001 {
1002 std::vector<const Class *> result;
1003 for (auto entry : _values)
1004 result.push_back(entry.second);
1005 return result;
1006 }
c23c8659 1007protected:
9d229ecb
ML
1008 EnumValue(Enum id, const char name[]) : _id(id), _name(name)
1009 {
1010 }
1011 ~EnumValue()
1012 {
1013 }
21d1bec6 1014private:
9d229ecb
ML
1015 static const std::map<const Enum, const Class * const> _values;
1016 const Enum _id;
3b161085 1017 const string _name;
c23c8659
ML
1018};
1019
8b2a1843 1020#include <libsigrokcxx/enums.hpp>
c23c8659
ML
1021
1022}
1023
1b40fdb8 1024#endif