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