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