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