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