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