]> sigrok.org Git - libsigrok.git/blame_incremental - 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
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
20/**
21
22@mainpage API Reference
23
24Introduction
25------------
26
27The libsigrokcxx API provides an object-oriented C++ interface to the
28functionality in libsigrok, including automatic memory and resource management.
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
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.
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
70#ifndef LIBSIGROKCXX_HPP
71#define LIBSIGROKCXX_HPP
72
73#include <libsigrok/libsigrok.h>
74#include <glibmm.h>
75
76#include <stdexcept>
77#include <memory>
78#include <vector>
79#include <map>
80#include <set>
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;
94class SR_API Session;
95class SR_API ConfigKey;
96class SR_API InputFormat;
97class SR_API OutputFormat;
98class SR_API OutputFlag;
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;
112class SR_API Input;
113class SR_API InputDevice;
114class SR_API Output;
115class SR_API DataType;
116class SR_API Option;
117class SR_API UserDevice;
118
119/** Exception thrown when an error code is returned by any libsigrok call. */
120class SR_API Error: public exception
121{
122public:
123 explicit Error(int result);
124 ~Error() noexcept;
125 const int result;
126 const char *what() const noexcept;
127};
128
129/* Base template for classes whose resources are owned by a parent object. */
130template <class Class, class Parent, typename Struct>
131class SR_API ParentOwned
132{
133protected:
134 /* Parent object which owns this child object's underlying structure.
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. */
147 shared_ptr<Parent> _parent;
148
149 /* Weak pointer for shared_from_this() implementation. */
150 weak_ptr<Class> _weak_this;
151
152public:
153 /* Get parent object that owns this object. */
154 shared_ptr<Parent> parent()
155 {
156 return _parent;
157 }
158
159 /* Note, this implementation will create a new smart_ptr if none exists. */
160 shared_ptr<Class> shared_from_this()
161 {
162 shared_ptr<Class> shared;
163
164 if (!(shared = _weak_this.lock()))
165 {
166 shared = shared_ptr<Class>(static_cast<Class *>(this), reset_parent);
167 _weak_this = shared;
168 }
169
170 return shared;
171 }
172
173 shared_ptr<Class> get_shared_pointer(shared_ptr<Parent> parent)
174 {
175 if (!parent)
176 throw Error(SR_ERR_BUG);
177 this->_parent = parent;
178 return shared_from_this();
179 }
180
181 shared_ptr<Class> get_shared_pointer(Parent *parent)
182 {
183 if (!parent)
184 throw Error(SR_ERR_BUG);
185 return get_shared_pointer(parent->shared_from_this());
186 }
187protected:
188 static void reset_parent(Class *object)
189 {
190 if (!object->_parent)
191 throw Error(SR_ERR_BUG);
192 object->_parent.reset();
193 }
194
195 Struct *_structure;
196
197 explicit ParentOwned(Struct *structure) :
198 _structure(structure)
199 {
200 }
201};
202
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:
216 Struct *_structure;
217
218 explicit UserOwned(Struct *structure) :
219 _structure(structure)
220 {
221 }
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 };
229};
230
231/** Type of log callback */
232typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
233
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,
249 const char *name, void *cb_data) noexcept;
250 static SR_PRIV int close_callback(struct sr_resource *res,
251 void *cb_data) noexcept;
252 static SR_PRIV ssize_t read_callback(const struct sr_resource *res,
253 void *buf, size_t count, void *cb_data) noexcept;
254 friend class Context;
255};
256
257/** The global libsigrok context */
258class SR_API Context : public UserOwned<Context, struct sr_context>
259{
260public:
261 /** Create new context */
262 static shared_ptr<Context> create();
263 /** libsigrok package version. */
264 static string package_version();
265 /** libsigrok library version. */
266 static string lib_version();
267 /** Available hardware drivers, indexed by name. */
268 map<string, shared_ptr<Driver> > drivers();
269 /** Available input formats, indexed by name. */
270 map<string, shared_ptr<InputFormat> > input_formats();
271 /** Available output formats, indexed by name. */
272 map<string, shared_ptr<OutputFormat> > output_formats();
273 /** Current log level. */
274 const LogLevel *log_level();
275 /** Set the log level.
276 * @param level LogLevel to use. */
277 void set_log_level(const LogLevel *level);
278 /** Set the log callback.
279 * @param callback Callback of the form callback(LogLevel, string). */
280 void set_log_callback(LogCallbackFunction callback);
281 /** Set the log callback to the default handler. */
282 void set_log_callback_default();
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);
286 /** Create a new session. */
287 shared_ptr<Session> create_session();
288 /** Create a new user device. */
289 shared_ptr<UserDevice> create_user_device(
290 string vendor, string model, string version);
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(
295 const map<const ConfigKey *, Glib::VariantBase> &config);
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. */
300 shared_ptr<Packet> create_analog_packet(
301 const vector<shared_ptr<Channel> > &channels,
302 float *data_pointer, unsigned int num_samples, const Quantity *mq,
303 const Unit *unit, const vector<const QuantityFlag *> &mqflags);
304 /** Load a saved session.
305 * @param filename File name string. */
306 shared_ptr<Session> load_session(string filename);
307 /** Create a new trigger.
308 * @param name Name string for new trigger. */
309 shared_ptr<Trigger> create_trigger(string name);
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);
316 map<string, string> serials(shared_ptr<Driver> driver);
317protected:
318 map<string, Driver *> _drivers;
319 map<string, InputFormat *> _input_formats;
320 map<string, OutputFormat *> _output_formats;
321 Session *_session;
322 LogCallbackFunction _log_callback;
323 Context();
324 ~Context();
325 friend class Deleter;
326 friend class Session;
327 friend class Driver;
328};
329
330enum Capability {
331 GET = SR_CONF_GET,
332 SET = SR_CONF_SET,
333 LIST = SR_CONF_LIST
334};
335
336/** An object that can be configured. */
337class SR_API Configurable
338{
339public:
340 /** Read configuration for the given key.
341 * @param key ConfigKey to read. */
342 Glib::VariantBase config_get(const ConfigKey *key);
343 /** Set configuration for the given key to a specified value.
344 * @param key ConfigKey to set.
345 * @param value Value to set. */
346 void config_set(const ConfigKey *key, const Glib::VariantBase &value);
347 /** Enumerate available values for the given configuration key.
348 * @param key ConfigKey to enumerate values for. */
349 Glib::VariantContainerBase config_list(const ConfigKey *key);
350 /** Enumerate available keys, according to a given index key. */
351 map<const ConfigKey *, set<Capability> > config_keys(const ConfigKey *key);
352 /** Check for a key in the list from a given index key. */
353 bool config_check(const ConfigKey *key, const ConfigKey *index_key);
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
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. */
372 string name();
373 /** Long name for this driver. */
374 string long_name();
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(
378 const map<const ConfigKey *, Glib::VariantBase> &options = {});
379protected:
380 bool _initialized;
381 vector<HardwareDevice *> _devices;
382 explicit Driver(struct sr_dev_driver *structure);
383 ~Driver();
384 friend class Context;
385 friend class HardwareDevice;
386 friend class ChannelGroup;
387};
388
389/** A generic device, either hardware or virtual */
390class SR_API Device : public Configurable
391{
392public:
393 /** Vendor name for this device. */
394 string vendor();
395 /** Model name for this device. */
396 string model();
397 /** Version string for this device. */
398 string version();
399 /** Serial number for this device. */
400 string serial_number();
401 /** Connection ID for this device. */
402 string connection_id();
403 /** List of the channels available on this device. */
404 vector<shared_ptr<Channel> > channels();
405 /** Channel groups available on this device, indexed by name. */
406 map<string, shared_ptr<ChannelGroup> > channel_groups();
407 /** Open device. */
408 void open();
409 /** Close device. */
410 void close();
411protected:
412 explicit Device(struct sr_dev_inst *structure);
413 ~Device();
414 virtual shared_ptr<Device> get_shared_from_this() = 0;
415 shared_ptr<Channel> get_channel(struct sr_channel *ptr);
416 struct sr_dev_inst *_structure;
417 map<struct sr_channel *, Channel *> _channels;
418 map<string, ChannelGroup *> _channel_groups;
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;
430 friend class Analog;
431};
432
433/** A real hardware device, connected via a driver */
434class SR_API HardwareDevice :
435 public UserOwned<HardwareDevice, struct sr_dev_inst>,
436 public Device
437{
438public:
439 /** Driver providing this device. */
440 shared_ptr<Driver> driver();
441protected:
442 HardwareDevice(shared_ptr<Driver> driver, struct sr_dev_inst *structure);
443 ~HardwareDevice();
444 shared_ptr<Device> get_shared_from_this();
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;
453 friend class Driver;
454 friend class ChannelGroup;
455};
456
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
479/** A channel on a device */
480class SR_API Channel :
481 public ParentOwned<Channel, Device, struct sr_channel>
482{
483public:
484 /** Current name of this channel. */
485 string name();
486 /** Set the name of this channel. *
487 * @param name Name string to set. */
488 void set_name(string name);
489 /** Type of this channel. */
490 const ChannelType *type();
491 /** Enabled status of this channel. */
492 bool enabled();
493 /** Set the enabled status of this channel.
494 * @param value Boolean value to set. */
495 void set_enabled(bool value);
496 /** Get the index number of this channel. */
497 unsigned int index();
498protected:
499 explicit Channel(struct sr_channel *structure);
500 ~Channel();
501 const ChannelType * const _type;
502 friend class Device;
503 friend class UserDevice;
504 friend class ChannelGroup;
505 friend class Session;
506 friend class TriggerStage;
507 friend class Context;
508};
509
510/** A group of channels on a device, which share some configuration */
511class SR_API ChannelGroup :
512 public ParentOwned<ChannelGroup, Device, struct sr_channel_group>,
513 public Configurable
514{
515public:
516 /** Name of this channel group. */
517 string name();
518 /** List of the channels in this group. */
519 vector<shared_ptr<Channel> > channels();
520protected:
521 ChannelGroup(Device *device, struct sr_channel_group *structure);
522 ~ChannelGroup();
523 vector<Channel *> _channels;
524 friend class Device;
525};
526
527/** A trigger configuration */
528class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
529{
530public:
531 /** Name of this trigger configuration. */
532 string name();
533 /** List of the stages in this trigger. */
534 vector<shared_ptr<TriggerStage> > stages();
535 /** Add a new stage to this trigger. */
536 shared_ptr<TriggerStage> add_stage();
537protected:
538 Trigger(shared_ptr<Context> context, string name);
539 ~Trigger();
540 shared_ptr<Context> _context;
541 vector<TriggerStage *> _stages;
542 friend class Deleter;
543 friend class Context;
544 friend class Session;
545};
546
547/** A stage in a trigger configuration */
548class SR_API TriggerStage :
549 public ParentOwned<TriggerStage, Trigger, struct sr_trigger_stage>
550{
551public:
552 /** Index number of this stage. */
553 int number();
554 /** List of match conditions on this stage. */
555 vector<shared_ptr<TriggerMatch> > matches();
556 /** Add a new match condition to this stage.
557 * @param channel Channel to match on.
558 * @param type TriggerMatchType to apply. */
559 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
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. */
564 void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
565protected:
566 vector<TriggerMatch *> _matches;
567 explicit TriggerStage(struct sr_trigger_stage *structure);
568 ~TriggerStage();
569 friend class Trigger;
570};
571
572/** A match condition in a trigger configuration */
573class SR_API TriggerMatch :
574 public ParentOwned<TriggerMatch, TriggerStage, struct sr_trigger_match>
575{
576public:
577 /** Channel this condition matches on. */
578 shared_ptr<Channel> channel();
579 /** Type of match. */
580 const TriggerMatchType *type();
581 /** Threshold value. */
582 float value();
583protected:
584 TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
585 ~TriggerMatch();
586 shared_ptr<Channel> _channel;
587 friend class TriggerStage;
588};
589
590/** Type of session stopped callback */
591typedef function<void()> SessionStoppedCallback;
592
593/** Type of datafeed callback */
594typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
595 DatafeedCallbackFunction;
596
597/* Data required for C callback function to call a C++ datafeed callback */
598class SR_PRIV DatafeedCallbackData
599{
600public:
601 void run(const struct sr_dev_inst *sdi,
602 const struct sr_datafeed_packet *pkt);
603protected:
604 DatafeedCallbackFunction _callback;
605 DatafeedCallbackData(Session *session,
606 DatafeedCallbackFunction callback);
607 Session *_session;
608 friend class Session;
609};
610
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:
617 explicit SessionDevice(struct sr_dev_inst *sdi);
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
630/** A sigrok session */
631class SR_API Session : public UserOwned<Session, struct sr_session>
632{
633public:
634 /** Add a device to this session.
635 * @param device Device to add. */
636 void add_device(shared_ptr<Device> device);
637 /** List devices attached to this session. */
638 vector<shared_ptr<Device> > devices();
639 /** Remove all devices from this session. */
640 void remove_devices();
641 /** Add a datafeed callback to this session.
642 * @param callback Callback of the form callback(Device, Packet). */
643 void add_datafeed_callback(DatafeedCallbackFunction callback);
644 /** Remove all datafeed callbacks from this session. */
645 void remove_datafeed_callbacks();
646 /** Start the session. */
647 void start();
648 /** Run the session event loop. */
649 void run();
650 /** Stop the session. */
651 void stop();
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);
656 /** Get current trigger setting. */
657 shared_ptr<Trigger> trigger();
658 /** Get the context. */
659 shared_ptr<Context> context();
660 /** Set trigger setting.
661 * @param trigger Trigger object to use. */
662 void set_trigger(shared_ptr<Trigger> trigger);
663 /** Get filename this session was loaded from. */
664 string filename();
665protected:
666 explicit Session(shared_ptr<Context> context);
667 Session(shared_ptr<Context> context, string filename);
668 ~Session();
669 shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
670 const shared_ptr<Context> _context;
671 map<const struct sr_dev_inst *, SessionDevice *> _owned_devices;
672 map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
673 vector<DatafeedCallbackData *> _datafeed_callbacks;
674 SessionStoppedCallback _stopped_callback;
675 string _filename;
676 shared_ptr<Trigger> _trigger;
677 friend class Deleter;
678 friend class Context;
679 friend class DatafeedCallbackData;
680 friend class SessionDevice;
681};
682
683/** A packet on the session datafeed */
684class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
685{
686public:
687 /** Type of this packet. */
688 const PacketType *type();
689 /** Payload of this packet. */
690 shared_ptr<PacketPayload> payload();
691protected:
692 Packet(shared_ptr<Device> device,
693 const struct sr_datafeed_packet *structure);
694 ~Packet();
695 shared_ptr<Device> _device;
696 PacketPayload *_payload;
697 friend class Deleter;
698 friend class Session;
699 friend class Output;
700 friend class DatafeedCallbackData;
701 friend class Header;
702 friend class Meta;
703 friend class Logic;
704 friend class Analog;
705 friend class Context;
706};
707
708/** Abstract base class for datafeed packet payloads */
709class SR_API PacketPayload
710{
711protected:
712 PacketPayload();
713 virtual ~PacketPayload() = 0;
714 virtual shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) = 0;
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;
722 friend class Packet;
723 friend class Output;
724};
725
726/** Payload of a datafeed header packet */
727class SR_API Header :
728 public ParentOwned<Header, Packet, const struct sr_datafeed_header>,
729 public PacketPayload
730{
731public:
732 /* Feed version number. */
733 int feed_version();
734 /* Start time of this session. */
735 Glib::TimeVal start_time();
736protected:
737 explicit Header(const struct sr_datafeed_header *structure);
738 ~Header();
739 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
740 friend class Packet;
741};
742
743/** Payload of a datafeed metadata packet */
744class SR_API Meta :
745 public ParentOwned<Meta, Packet, const struct sr_datafeed_meta>,
746 public PacketPayload
747{
748public:
749 /* Mapping of (ConfigKey, value) pairs. */
750 map<const ConfigKey *, Glib::VariantBase> config();
751protected:
752 explicit Meta(const struct sr_datafeed_meta *structure);
753 ~Meta();
754 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
755 map<const ConfigKey *, Glib::VariantBase> _config;
756 friend class Packet;
757};
758
759/** Payload of a datafeed packet with logic data */
760class SR_API Logic :
761 public ParentOwned<Logic, Packet, const struct sr_datafeed_logic>,
762 public PacketPayload
763{
764public:
765 /* Pointer to data. */
766 void *data_pointer();
767 /* Data length in bytes. */
768 size_t data_length();
769 /* Size of each sample in bytes. */
770 unsigned int unit_size();
771protected:
772 explicit Logic(const struct sr_datafeed_logic *structure);
773 ~Logic();
774 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
775 friend class Packet;
776};
777
778/** Payload of a datafeed packet with analog data */
779class SR_API Analog :
780 public ParentOwned<Analog, Packet, const struct sr_datafeed_analog>,
781 public PacketPayload
782{
783public:
784 /** Pointer to data. */
785 void *data_pointer();
786 /** Number of samples in this packet. */
787 uint32_t num_samples();
788 /** Channels for which this packet contains data. */
789 vector<shared_ptr<Channel> > channels();
790 /** Measured quantity of the samples in this packet. */
791 const Quantity *mq();
792 /** Unit of the samples in this packet. */
793 const Unit *unit();
794 /** Measurement flags associated with the samples in this packet. */
795 vector<const QuantityFlag *> mq_flags();
796protected:
797 explicit Analog(const struct sr_datafeed_analog *structure);
798 ~Analog();
799 shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
800 friend class Packet;
801};
802
803/** An input format supported by the library */
804class SR_API InputFormat :
805 public ParentOwned<InputFormat, Context, const struct sr_input_module>
806{
807public:
808 /** Name of this input format. */
809 string name();
810 /** Description of this input format. */
811 string description();
812 /** A list of preferred file name extensions for this file format.
813 * @note This list is a recommendation only. */
814 vector<string> extensions();
815 /** Options supported by this input format. */
816 map<string, shared_ptr<Option> > options();
817 /** Create an input using this input format.
818 * @param options Mapping of (option name, value) pairs. */
819 shared_ptr<Input> create_input(const map<string, Glib::VariantBase> &options = {});
820protected:
821 explicit InputFormat(const struct sr_input_module *structure);
822 ~InputFormat();
823 friend class Context;
824 friend class InputDevice;
825};
826
827/** An input instance (an input format applied to a file or stream) */
828class SR_API Input : public UserOwned<Input, const struct sr_input>
829{
830public:
831 /** Virtual device associated with this input. */
832 shared_ptr<InputDevice> device();
833 /** Send next stream data.
834 * @param data Next stream data.
835 * @param length Length of data. */
836 void send(void *data, size_t length);
837 /** Signal end of input data. */
838 void end();
839protected:
840 Input(shared_ptr<Context> context, const struct sr_input *structure);
841 ~Input();
842 shared_ptr<Context> _context;
843 InputDevice *_device;
844 friend class Deleter;
845 friend class Context;
846 friend class InputFormat;
847};
848
849/** A virtual device associated with an input */
850class SR_API InputDevice :
851 public ParentOwned<InputDevice, Input, struct sr_dev_inst>,
852 public Device
853{
854protected:
855 InputDevice(shared_ptr<Input> input, struct sr_dev_inst *sdi);
856 ~InputDevice();
857 shared_ptr<Device> get_shared_from_this();
858 shared_ptr<Input> _input;
859 friend class Input;
860};
861
862/** An option used by an output format */
863class SR_API Option : public UserOwned<Option, const struct sr_option>
864{
865public:
866 /** Short name of this option suitable for command line usage. */
867 string id();
868 /** Short name of this option suitable for GUI usage. */
869 string name();
870 /** Description of this option in a sentence. */
871 string description();
872 /** Default value for this option. */
873 Glib::VariantBase default_value();
874 /** Possible values for this option, if a limited set. */
875 vector<Glib::VariantBase> values();
876protected:
877 Option(const struct sr_option *structure,
878 shared_ptr<const struct sr_option *> structure_array);
879 ~Option();
880 shared_ptr<const struct sr_option *> _structure_array;
881 friend class Deleter;
882 friend class InputFormat;
883 friend class OutputFormat;
884};
885
886/** An output format supported by the library */
887class SR_API OutputFormat :
888 public ParentOwned<OutputFormat, Context, const struct sr_output_module>
889{
890public:
891 /** Name of this output format. */
892 string name();
893 /** Description of this output format. */
894 string description();
895 /** A list of preferred file name extensions for this file format.
896 * @note This list is a recommendation only. */
897 vector<string> extensions();
898 /** Options supported by this output format. */
899 map<string, shared_ptr<Option> > options();
900 /** Create an output using this format.
901 * @param device Device to output for.
902 * @param options Mapping of (option name, value) pairs. */
903 shared_ptr<Output> create_output(
904 shared_ptr<Device> device,
905 const map<string, Glib::VariantBase> &options = {});
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,
912 const map<string, Glib::VariantBase> &options = {});
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);
920protected:
921 explicit OutputFormat(const struct sr_output_module *structure);
922 ~OutputFormat();
923 friend class Context;
924 friend class Output;
925};
926
927/** An output instance (an output format applied to a device) */
928class SR_API Output : public UserOwned<Output, const struct sr_output>
929{
930public:
931 /** Update output with data from the given packet.
932 * @param packet Packet to handle. */
933 string receive(shared_ptr<Packet> packet);
934protected:
935 Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
936 Output(shared_ptr<OutputFormat> format,
937 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
938 Output(string filename, shared_ptr<OutputFormat> format,
939 shared_ptr<Device> device, const map<string, Glib::VariantBase> &options);
940 ~Output();
941 const shared_ptr<OutputFormat> _format;
942 const shared_ptr<Device> _device;
943 const map<string, Glib::VariantBase> _options;
944 friend class Deleter;
945 friend class OutputFormat;
946};
947
948/** Base class for objects which wrap an enumeration value from libsigrok */
949template <class Class, typename Enum> class SR_API EnumValue
950{
951public:
952 /** The integer constant associated with this value. */
953 int id() const
954 {
955 return static_cast<int>(_id);
956 }
957 /** The name associated with this value. */
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 }
978protected:
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;
987 const string _name;
988};
989
990#include <libsigrokcxx/enums.hpp>
991
992}
993
994#endif