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