]> sigrok.org Git - libsigrok.git/blob - bindings/cxx/include/libsigrok/libsigrok.hpp
1936d4d5d2820c3de60e395d199e64442890199f
[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         /** Description identifying this device. */
356         virtual string description();
357         /** Vendor name for this device. */
358         string vendor();
359         /** Model name for this device. */
360         string model();
361         /** Version string for this device. */
362         string version();
363         /** Serial number for this device. */
364         string serial_number();
365         /** Connection ID for this device. */
366         string connection_id();
367         /** List of the channels available on this device. */
368         vector<shared_ptr<Channel> > channels();
369         /** Channel groups available on this device, indexed by name. */
370         map<string, shared_ptr<ChannelGroup> > channel_groups();
371         /** Open device. */
372         void open();
373         /** Close device. */
374         void close();
375 protected:
376         Device(struct sr_dev_inst *structure);
377         ~Device();
378         virtual shared_ptr<Device> get_shared_from_this() = 0;
379         shared_ptr<Channel> get_channel(struct sr_channel *ptr);
380         struct sr_dev_inst *_structure;
381         map<struct sr_channel *, Channel *> _channels;
382         map<string, ChannelGroup *> _channel_groups;
383         /** Deleter needed to allow shared_ptr use with protected destructor. */
384         class Deleter
385         {
386         public:
387                 void operator()(Device *device) { delete device; }
388         };
389         friend class Deleter;
390         friend class Session;
391         friend class Channel;
392         friend class ChannelGroup;
393         friend class Output;
394         friend class Analog;
395 };
396
397 /** A real hardware device, connected via a driver */
398 class SR_API HardwareDevice :
399         public UserOwned<HardwareDevice, struct sr_dev_inst>,
400         public Device
401 {
402 public:
403         /** Driver providing this device. */
404         shared_ptr<Driver> driver();
405 protected:
406         HardwareDevice(shared_ptr<Driver> driver, struct sr_dev_inst *structure);
407         ~HardwareDevice();
408         shared_ptr<Device> get_shared_from_this();
409         shared_ptr<Driver> _driver;
410         /** Deleter needed to allow shared_ptr use with protected destructor. */
411         class Deleter
412         {
413         public:
414                 void operator()(HardwareDevice *device) { delete device; }
415         };
416         friend class Deleter;
417         friend class Driver;
418         friend class ChannelGroup;
419 };
420
421 /** A channel on a device */
422 class SR_API Channel :
423         public ParentOwned<Channel, Device, struct sr_channel>
424 {
425 public:
426         /** Current name of this channel. */
427         string name();
428         /** Set the name of this channel. *
429          * @param name Name string to set. */
430         void set_name(string name);
431         /** Type of this channel. */
432         const ChannelType *type();
433         /** Enabled status of this channel. */
434         bool enabled();
435         /** Set the enabled status of this channel.
436          * @param value Boolean value to set. */
437         void set_enabled(bool value);
438         /** Get the index number of this channel. */
439         unsigned int index();
440 protected:
441         Channel(struct sr_channel *structure);
442         ~Channel();
443         const ChannelType * const _type;
444         friend class Device;
445         friend class ChannelGroup;
446         friend class Session;
447         friend class TriggerStage;
448 };
449
450 /** A group of channels on a device, which share some configuration */
451 class SR_API ChannelGroup :
452         public ParentOwned<ChannelGroup, Device, struct sr_channel_group>,
453         public Configurable
454 {
455 public:
456         /** Name of this channel group. */
457         string name();
458         /** List of the channels in this group. */
459         vector<shared_ptr<Channel> > channels();
460 protected:
461         ChannelGroup(Device *device, struct sr_channel_group *structure);
462         ~ChannelGroup();
463         vector<Channel *> _channels;
464         friend class Device;
465 };
466
467 /** A trigger configuration */
468 class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
469 {
470 public:
471         /** Name of this trigger configuration. */
472         string name();
473         /** List of the stages in this trigger. */
474         vector<shared_ptr<TriggerStage> > stages();
475         /** Add a new stage to this trigger. */
476         shared_ptr<TriggerStage> add_stage();
477 protected:
478         Trigger(shared_ptr<Context> context, string name);
479         ~Trigger();
480         shared_ptr<Context> _context;
481         vector<TriggerStage *> _stages;
482         friend class Deleter;
483         friend class Context;
484         friend class Session;
485 };
486
487 /** A stage in a trigger configuration */
488 class SR_API TriggerStage :
489         public ParentOwned<TriggerStage, Trigger, struct sr_trigger_stage>
490 {
491 public:
492         /** Index number of this stage. */
493         int number();
494         /** List of match conditions on this stage. */
495         vector<shared_ptr<TriggerMatch> > matches();
496         /** Add a new match condition to this stage.
497          * @param channel Channel to match on.
498          * @param type TriggerMatchType to apply. */
499         void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type);
500         /** Add a new match condition to this stage.
501          * @param channel Channel to match on.
502          * @param type TriggerMatchType to apply.
503          * @param value Threshold value. */
504         void add_match(shared_ptr<Channel> channel, const TriggerMatchType *type, float value);
505 protected:
506         vector<TriggerMatch *> _matches;
507         TriggerStage(struct sr_trigger_stage *structure);
508         ~TriggerStage();
509         friend class Trigger;
510 };
511
512 /** A match condition in a trigger configuration  */
513 class SR_API TriggerMatch :
514         public ParentOwned<TriggerMatch, TriggerStage, struct sr_trigger_match>
515 {
516 public:
517         /** Channel this condition matches on. */
518         shared_ptr<Channel> channel();
519         /** Type of match. */
520         const TriggerMatchType *type();
521         /** Threshold value. */
522         float value();
523 protected:
524         TriggerMatch(struct sr_trigger_match *structure, shared_ptr<Channel> channel);
525         ~TriggerMatch();
526         shared_ptr<Channel> _channel;
527         friend class TriggerStage;
528 };
529
530 /** Type of datafeed callback */
531 typedef function<void(shared_ptr<Device>, shared_ptr<Packet>)>
532         DatafeedCallbackFunction;
533
534 /* Data required for C callback function to call a C++ datafeed callback */
535 class SR_PRIV DatafeedCallbackData
536 {
537 public:
538         void run(const struct sr_dev_inst *sdi,
539                 const struct sr_datafeed_packet *pkt);
540 protected:
541         DatafeedCallbackFunction _callback;
542         DatafeedCallbackData(Session *session,
543                 DatafeedCallbackFunction callback);
544         Session *_session;
545         friend class Session;
546 };
547
548 /** Type of source callback */
549 typedef function<bool(Glib::IOCondition)>
550         SourceCallbackFunction;
551
552 /* Data required for C callback function to call a C++ source callback */
553 class SR_PRIV SourceCallbackData
554 {
555 public:
556         bool run(int revents);
557 protected:
558         SourceCallbackData(shared_ptr<EventSource> source);
559         shared_ptr<EventSource> _source;
560         friend class Session;
561 };
562
563 /** An I/O event source */
564 class SR_API EventSource
565 {
566 public:
567         /** Create an event source from a file descriptor.
568          * @param fd File descriptor.
569          * @param events GLib IOCondition event mask.
570          * @param timeout Timeout in milliseconds.
571          * @param callback Callback of the form callback(events) */
572         static shared_ptr<EventSource> create(int fd, Glib::IOCondition events,
573                 int timeout, SourceCallbackFunction callback);
574         /** Create an event source from a GLib PollFD
575          * @param pollfd GLib PollFD
576          * @param timeout Timeout in milliseconds.
577          * @param callback Callback of the form callback(events) */
578         static shared_ptr<EventSource> create(Glib::PollFD pollfd, int timeout,
579                 SourceCallbackFunction callback);
580         /** Create an event source from a GLib IOChannel
581          * @param channel GLib IOChannel.
582          * @param events GLib IOCondition event mask.
583          * @param timeout Timeout in milliseconds.
584          * @param callback Callback of the form callback(events) */
585         static shared_ptr<EventSource> create(
586                 Glib::RefPtr<Glib::IOChannel> channel, Glib::IOCondition events,
587                 int timeout, SourceCallbackFunction callback);
588 protected:
589         EventSource(int timeout, SourceCallbackFunction callback);
590         ~EventSource();
591         enum source_type {
592                 SOURCE_FD,
593                 SOURCE_POLLFD,
594                 SOURCE_IOCHANNEL
595         } _type;
596         int _fd;
597         Glib::PollFD _pollfd;
598         Glib::RefPtr<Glib::IOChannel> _channel;
599         Glib::IOCondition _events;
600         int _timeout;
601         SourceCallbackFunction _callback;
602         /** Deleter needed to allow shared_ptr use with protected destructor. */
603         class Deleter
604         {
605         public:
606                 void operator()(EventSource *source) { delete source; }
607         };
608         friend class Deleter;
609         friend class Session;
610         friend class SourceCallbackData;
611 };
612
613 /** A virtual device associated with a stored session */
614 class SR_API SessionDevice :
615         public ParentOwned<SessionDevice, Session, struct sr_dev_inst>,
616         public Device
617 {
618         /** Description identifying this device. */
619         string description();
620 protected:
621         SessionDevice(struct sr_dev_inst *sdi);
622         ~SessionDevice();
623         shared_ptr<Device> get_shared_from_this();
624         /** Deleter needed to allow shared_ptr use with protected destructor. */
625         class Deleter
626         {
627         public:
628                 void operator()(SessionDevice *device) { delete device; }
629         };
630         friend class Deleter;
631         friend class Session;
632 };
633
634 /** A sigrok session */
635 class SR_API Session : public UserOwned<Session, struct sr_session>
636 {
637 public:
638         /** Add a device to this session.
639          * @param device Device to add. */
640         void add_device(shared_ptr<Device> device);
641         /** List devices attached to this session. */
642         vector<shared_ptr<Device> > devices();
643         /** Remove all devices from this session. */
644         void remove_devices();
645         /** Add a datafeed callback to this session.
646          * @param callback Callback of the form callback(Device, Packet). */
647         void add_datafeed_callback(DatafeedCallbackFunction callback);
648         /** Remove all datafeed callbacks from this session. */
649         void remove_datafeed_callbacks();
650         /** Add an I/O event source.
651          * @param source EventSource to add. */
652         void add_source(shared_ptr<EventSource> source);
653         /** Remove an event source.
654          * @param source EventSource to remove. */
655         void remove_source(shared_ptr<EventSource> source);
656         /** Start the session. */
657         void start();
658         /** Run the session event loop. */
659         void run();
660         /** Stop the session. */
661         void stop();
662         /** Begin saving session to a file.
663          * @param filename File name string. */
664         void begin_save(string filename);
665         /** Append a packet to the session file being saved.
666          * @param packet Packet to append. */
667         void append(shared_ptr<Packet> packet);
668         /** Append raw logic data to the session file being saved. */
669         void append(void *data, size_t length, unsigned int unit_size);
670         /** Get current trigger setting. */
671         shared_ptr<Trigger> trigger();
672         /** Set trigger setting.
673          * @param trigger Trigger object to use. */
674         void set_trigger(shared_ptr<Trigger> trigger);
675 protected:
676         Session(shared_ptr<Context> context);
677         Session(shared_ptr<Context> context, string filename);
678         ~Session();
679         shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
680         const shared_ptr<Context> _context;
681         map<const struct sr_dev_inst *, SessionDevice *> _owned_devices;
682         map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
683         vector<DatafeedCallbackData *> _datafeed_callbacks;
684         map<shared_ptr<EventSource>, SourceCallbackData *> _source_callbacks;
685         string _filename;
686         bool _saving;
687         bool _save_initialized;
688         string _save_filename;
689         uint64_t _save_samplerate;
690         shared_ptr<Trigger> _trigger;
691         friend class Deleter;
692         friend class Context;
693         friend class DatafeedCallbackData;
694         friend class SessionDevice;
695 };
696
697 /** A packet on the session datafeed */
698 class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
699 {
700 public:
701         /** Type of this packet. */
702         const PacketType *type();
703         /** Payload of this packet. */
704         shared_ptr<PacketPayload> payload();
705 protected:
706         Packet(shared_ptr<Device> device,
707                 const struct sr_datafeed_packet *structure);
708         ~Packet();
709         shared_ptr<Device> _device;
710         PacketPayload *_payload;
711         friend class Deleter;
712         friend class Session;
713         friend class Output;
714         friend class DatafeedCallbackData;
715         friend class Header;
716         friend class Meta;
717         friend class Logic;
718         friend class Analog;
719 };
720
721 /** Abstract base class for datafeed packet payloads */
722 class SR_API PacketPayload
723 {
724 protected:
725         PacketPayload();
726         virtual ~PacketPayload() = 0;
727         virtual shared_ptr<PacketPayload> get_shared_pointer(Packet *parent) = 0;
728         /** Deleter needed to allow shared_ptr use with protected destructor. */
729         class Deleter
730         {
731         public:
732                 void operator()(PacketPayload *payload) { delete payload; }
733         };
734         friend class Deleter;
735         friend class Packet;
736         friend class Output;
737 };
738
739 /** Payload of a datafeed header packet */
740 class SR_API Header :
741         public ParentOwned<Header, Packet, const struct sr_datafeed_header>,
742         public PacketPayload
743 {
744 public:
745         /* Feed version number. */
746         int feed_version();
747         /* Start time of this session. */
748         Glib::TimeVal start_time();
749 protected:
750         Header(const struct sr_datafeed_header *structure);
751         ~Header();
752         shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
753         friend class Packet;
754 };
755
756 /** Payload of a datafeed metadata packet */
757 class SR_API Meta :
758         public ParentOwned<Meta, Packet, const struct sr_datafeed_meta>,
759         public PacketPayload
760 {
761 public:
762         /* Mapping of (ConfigKey, value) pairs. */
763         map<const ConfigKey *, Glib::VariantBase> config();
764 protected:
765         Meta(const struct sr_datafeed_meta *structure);
766         ~Meta();
767         shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
768         map<const ConfigKey *, Glib::VariantBase> _config;
769         friend class Packet;
770 };
771
772 /** Payload of a datafeed packet with logic data */
773 class SR_API Logic :
774         public ParentOwned<Logic, Packet, const struct sr_datafeed_logic>,
775         public PacketPayload
776 {
777 public:
778         /* Pointer to data. */
779         void *data_pointer();
780         /* Data length in bytes. */
781         size_t data_length();
782         /* Size of each sample in bytes. */
783         unsigned int unit_size();
784 protected:
785         Logic(const struct sr_datafeed_logic *structure);
786         ~Logic();
787         shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
788         friend class Packet;
789 };
790
791 /** Payload of a datafeed packet with analog data */
792 class SR_API Analog :
793         public ParentOwned<Analog, Packet, const struct sr_datafeed_analog>,
794         public PacketPayload
795 {
796 public:
797         /** Pointer to data. */
798         float *data_pointer();
799         /** Number of samples in this packet. */
800         unsigned int num_samples();
801         /** Channels for which this packet contains data. */
802         vector<shared_ptr<Channel> > channels();
803         /** Measured quantity of the samples in this packet. */
804         const Quantity *mq();
805         /** Unit of the samples in this packet. */
806         const Unit *unit();
807         /** Measurement flags associated with the samples in this packet. */
808         vector<const QuantityFlag *> mq_flags();
809 protected:
810         Analog(const struct sr_datafeed_analog *structure);
811         ~Analog();
812         shared_ptr<PacketPayload> get_shared_pointer(Packet *parent);
813         friend class Packet;
814 };
815
816 /** An input format supported by the library */
817 class SR_API InputFormat :
818         public ParentOwned<InputFormat, Context, const struct sr_input_module>
819 {
820 public:
821         /** Name of this input format. */
822         string name();
823         /** Description of this input format. */
824         string description();
825         /** Options supported by this input format. */
826         map<string, shared_ptr<Option> > options();
827         /** Create an input using this input format.
828          * @param options Mapping of (option name, value) pairs. */
829         shared_ptr<Input> create_input(map<string, Glib::VariantBase> options =
830                 map<string, Glib::VariantBase>());
831 protected:
832         InputFormat(const struct sr_input_module *structure);
833         ~InputFormat();
834         friend class Context;
835         friend class InputDevice;
836 };
837
838 /** An input instance (an input format applied to a file or stream) */
839 class SR_API Input : public UserOwned<Input, const struct sr_input>
840 {
841 public:
842         /** Virtual device associated with this input. */
843         shared_ptr<InputDevice> device();
844         /** Send next stream data.
845          * @param data Next stream data. */
846         void send(string data);
847         /** Signal end of input data. */
848         void end();
849 protected:
850         Input(shared_ptr<Context> context, const struct sr_input *structure);
851         ~Input();
852         shared_ptr<Context> _context;
853         InputDevice *_device;
854         friend class Deleter;
855         friend class Context;
856         friend class InputFormat;
857 };
858
859 /** A virtual device associated with an input */
860 class SR_API InputDevice :
861         public ParentOwned<InputDevice, Input, struct sr_dev_inst>,
862         public Device
863 {
864 public:
865         /** Description identifying this device. */
866         string description();
867 protected:
868         InputDevice(shared_ptr<Input> input, struct sr_dev_inst *sdi);
869         ~InputDevice();
870         shared_ptr<Device> get_shared_from_this();
871         shared_ptr<Input> _input;
872         friend class Input;
873 };
874
875 /** An option used by an output format */
876 class SR_API Option : public UserOwned<Option, const struct sr_option>
877 {
878 public:
879         /** Short name of this option suitable for command line usage. */
880         string id();
881         /** Short name of this option suitable for GUI usage. */
882         string name();
883         /** Description of this option in a sentence. */
884         string description();
885         /** Default value for this option. */
886         Glib::VariantBase default_value();
887         /** Possible values for this option, if a limited set. */
888         vector<Glib::VariantBase> values();
889 protected:
890         Option(const struct sr_option *structure,
891                 shared_ptr<const struct sr_option *> structure_array);
892         ~Option();
893         shared_ptr<const struct sr_option *> _structure_array;
894         friend class Deleter;
895         friend class InputFormat;
896         friend class OutputFormat;
897 };
898
899 /** An output format supported by the library */
900 class SR_API OutputFormat :
901         public ParentOwned<OutputFormat, Context, const struct sr_output_module>
902 {
903 public:
904         /** Name of this output format. */
905         string name();
906         /** Description of this output format. */
907         string description();
908         /** Options supported by this output format. */
909         map<string, shared_ptr<Option> > options();
910         /** Create an output using this format.
911          * @param device Device to output for.
912          * @param options Mapping of (option name, value) pairs. */
913         shared_ptr<Output> create_output(shared_ptr<Device> device,
914                 map<string, Glib::VariantBase> options =
915                         map<string, Glib::VariantBase>());
916 protected:
917         OutputFormat(const struct sr_output_module *structure);
918         ~OutputFormat();
919         friend class Context;
920         friend class Output;
921 };
922
923 /** An output instance (an output format applied to a device) */
924 class SR_API Output : public UserOwned<Output, const struct sr_output>
925 {
926 public:
927         /** Update output with data from the given packet.
928          * @param packet Packet to handle. */
929         string receive(shared_ptr<Packet> packet);
930 protected:
931         Output(shared_ptr<OutputFormat> format, shared_ptr<Device> device);
932         Output(shared_ptr<OutputFormat> format,
933                 shared_ptr<Device> device, map<string, Glib::VariantBase> options);
934         ~Output();
935         const shared_ptr<OutputFormat> _format;
936         const shared_ptr<Device> _device;
937         const map<string, Glib::VariantBase> _options;
938         friend class Deleter;
939         friend class OutputFormat;
940 };
941
942 /** Base class for objects which wrap an enumeration value from libsigrok */
943 template <typename T> class SR_API EnumValue
944 {
945 public:
946         /** The enum constant associated with this value. */
947         T id() const { return _id; }
948         /** The name associated with this value. */
949         string name() const { return _name; }
950 protected:
951         EnumValue(T id, const char name[]) : _id(id), _name(name) {}
952         ~EnumValue() {}
953         const T _id;
954         const string _name;
955 };
956
957 #include "enums.hpp"
958
959 }
960
961 #endif // LIBSIGROK_HPP