]> sigrok.org Git - libsigrok.git/blob - bindings/cxx/include/libsigrokcxx/libsigrokcxx.hpp
C++: Make some methods static to match the C API
[libsigrok.git] / bindings / cxx / include / libsigrokcxx / libsigrokcxx.hpp
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
24 Introduction
25 ------------
26
27 The libsigrokcxx API provides an object-oriented C++ interface to the
28 functionality in libsigrok, including automatic memory and resource management.
29
30 It is built on top of the public libsigrok C API, and is designed to be used as
31 a standalone alternative API. Programs should not mix usage of the C and C++
32 APIs; the C++ interface code needs to have full control of all C API calls for
33 resources to be managed correctly.
34
35 Memory management
36 -----------------
37
38 All runtime objects created through the C++ API are passed and accessed via
39 shared pointers, using the C++11 std::shared_ptr implementation. This means
40 that a reference count is kept for each object.
41
42 Shared pointers can be copied and assigned in a user's program, automatically
43 updating their reference count and deleting objects when they are no longer in
44 use. The C++ interface code also keeps track of internal dependencies between
45 libsigrok resources, and ensures that objects are not prematurely deleted when
46 their resources are in use by other objects.
47
48 This means that management of libsigrokcxx objects and their underlying
49 libsigrok resources can be treated as fully automatic. As long as all shared
50 pointers to objects are deleted or reassigned when no longer in use, all
51 underlying resources will be released at the right time.
52
53 Getting started
54 ---------------
55
56 Usage of the C++ API needs to begin with a call to sigrok::Context::create().
57 This will create the global libsigrok context and returns a shared pointer to
58 the sigrok::Context object. Methods on this object provide access to the
59 hardware drivers, input and output formats supported by the library, as well
60 as means of creating other objects such as sessions and triggers.
61
62 Error handling
63 --------------
64
65 When any libsigrok C API call returns an error, a sigrok::Error exception is
66 raised, 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
82 namespace sigrok
83 {
84
85 using namespace std;
86
87 /* Forward declarations */
88 class SR_API Error;
89 class SR_API Context;
90 class SR_API Driver;
91 class SR_API Device;
92 class SR_API HardwareDevice;
93 class SR_API Channel;
94 class SR_API Session;
95 class SR_API ConfigKey;
96 class SR_API InputFormat;
97 class SR_API OutputFormat;
98 class SR_API OutputFlag;
99 class SR_API LogLevel;
100 class SR_API ChannelGroup;
101 class SR_API Trigger;
102 class SR_API TriggerStage;
103 class SR_API TriggerMatch;
104 class SR_API TriggerMatchType;
105 class SR_API ChannelType;
106 class SR_API Packet;
107 class SR_API PacketPayload;
108 class SR_API PacketType;
109 class SR_API Quantity;
110 class SR_API Unit;
111 class SR_API QuantityFlag;
112 class SR_API Input;
113 class SR_API InputDevice;
114 class SR_API Output;
115 class SR_API DataType;
116 class SR_API Option;
117 class SR_API UserDevice;
118
119 /** Exception thrown when an error code is returned by any libsigrok call. */
120 class SR_API Error: public exception
121 {
122 public:
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. */
130 template <class Class, class Parent, typename Struct>
131 class SR_API ParentOwned
132 {
133 protected:
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
152 public:
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         }
187 protected:
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. */
204 template <class Class, typename Struct>
205 class SR_API UserOwned : public enable_shared_from_this<Class>
206 {
207 public:
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         }
215 protected:
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 */
232 typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
233
234 /** Resource reader delegate. */
235 class SR_API ResourceReader
236 {
237 public:
238         ResourceReader() {}
239         virtual ~ResourceReader();
240 private:
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 */
258 class SR_API Context : public UserOwned<Context, struct sr_context>
259 {
260 public:
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);
317 protected:
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
330 enum 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. */
337 class SR_API Configurable
338 {
339 public:
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);
354 protected:
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 */
366 class SR_API Driver :
367         public ParentOwned<Driver, Context, struct sr_dev_driver>,
368         public Configurable
369 {
370 public:
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 = {});
379 protected:
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 */
390 class SR_API Device : public Configurable
391 {
392 public:
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();
411 protected:
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 */
434 class SR_API HardwareDevice :
435         public UserOwned<HardwareDevice, struct sr_dev_inst>,
436         public Device
437 {
438 public:
439         /** Driver providing this device. */
440         shared_ptr<Driver> driver();
441 protected:
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 */
458 class SR_API UserDevice :
459         public UserOwned<UserDevice, struct sr_dev_inst>,
460         public Device
461 {
462 public:
463         /** Add a new channel to this device. */
464         shared_ptr<Channel> add_channel(unsigned int index, const ChannelType *type, string name);
465 protected:
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 */
480 class SR_API Channel :
481         public ParentOwned<Channel, Device, struct sr_channel>
482 {
483 public:
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();
498 protected:
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 */
511 class SR_API ChannelGroup :
512         public ParentOwned<ChannelGroup, Device, struct sr_channel_group>,
513         public Configurable
514 {
515 public:
516         /** Name of this channel group. */
517         string name();
518         /** List of the channels in this group. */
519         vector<shared_ptr<Channel> > channels();
520 protected:
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 */
528 class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
529 {
530 public:
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();
537 protected:
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 */
548 class SR_API TriggerStage :
549         public ParentOwned<TriggerStage, Trigger, struct sr_trigger_stage>
550 {
551 public:
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);
565 protected:
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  */
573 class SR_API TriggerMatch :
574         public ParentOwned<TriggerMatch, TriggerStage, struct sr_trigger_match>
575 {
576 public:
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();
583 protected:
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 */
591 typedef function<void()> SessionStoppedCallback;
592
593 /** Type of datafeed callback */
594 typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
595         DatafeedCallbackFunction;
596
597 /* Data required for C callback function to call a C++ datafeed callback */
598 class SR_PRIV DatafeedCallbackData
599 {
600 public:
601         void run(const struct sr_dev_inst *sdi,
602                 const struct sr_datafeed_packet *pkt);
603 protected:
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 */
612 class SR_API SessionDevice :
613         public ParentOwned<SessionDevice, Session, struct sr_dev_inst>,
614         public Device
615 {
616 protected:
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 */
631 class SR_API Session : public UserOwned<Session, struct sr_session>
632 {
633 public:
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();
665 protected:
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 */
684 class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
685 {
686 public:
687         /** Type of this packet. */
688         const PacketType *type();
689         /** Payload of this packet. */
690         shared_ptr<PacketPayload> payload();
691 protected:
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 */
709 class SR_API PacketPayload
710 {
711 protected:
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 */
727 class SR_API Header :
728         public ParentOwned<Header, Packet, const struct sr_datafeed_header>,
729         public PacketPayload
730 {
731 public:
732         /* Feed version number. */
733         int feed_version();
734         /* Start time of this session. */
735         Glib::TimeVal start_time();
736 protected:
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 */
744 class SR_API Meta :
745         public ParentOwned<Meta, Packet, const struct sr_datafeed_meta>,
746         public PacketPayload
747 {
748 public:
749         /* Mapping of (ConfigKey, value) pairs. */
750         map<const ConfigKey *, Glib::VariantBase> config();
751 protected:
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 */
760 class SR_API Logic :
761         public ParentOwned<Logic, Packet, const struct sr_datafeed_logic>,
762         public PacketPayload
763 {
764 public:
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();
771 protected:
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 */
779 class SR_API Analog :
780         public ParentOwned<Analog, Packet, const struct sr_datafeed_analog>,
781         public PacketPayload
782 {
783 public:
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();
796 protected:
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 */
804 class SR_API InputFormat :
805         public ParentOwned<InputFormat, Context, const struct sr_input_module>
806 {
807 public:
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 = {});
820 protected:
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) */
828 class SR_API Input : public UserOwned<Input, const struct sr_input>
829 {
830 public:
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();
839 protected:
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 */
850 class SR_API InputDevice :
851         public ParentOwned<InputDevice, Input, struct sr_dev_inst>,
852         public Device
853 {
854 protected:
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 */
863 class SR_API Option : public UserOwned<Option, const struct sr_option>
864 {
865 public:
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();
876 protected:
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 */
887 class SR_API OutputFormat :
888         public ParentOwned<OutputFormat, Context, const struct sr_output_module>
889 {
890 public:
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);
920 protected:
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) */
928 class SR_API Output : public UserOwned<Output, const struct sr_output>
929 {
930 public:
931         /** Update output with data from the given packet.
932          * @param packet Packet to handle. */
933         string receive(shared_ptr<Packet> packet);
934 protected:
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 */
949 template <class Class, typename Enum> class SR_API EnumValue
950 {
951 public:
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         }
978 protected:
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