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