libsigrok  0.5.0
sigrok hardware access and backend library
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
output.c
Go to the documentation of this file.
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
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 #include <config.h>
21 #include <string.h>
22 #include <libsigrok/libsigrok.h>
23 #include "libsigrok-internal.h"
24 
25 /** @cond PRIVATE */
26 #define LOG_PREFIX "output"
27 /** @endcond */
28 
29 /**
30  * @file
31  *
32  * Output module handling.
33  */
34 
35 /**
36  * @defgroup grp_output Output modules
37  *
38  * Output module handling.
39  *
40  * libsigrok supports several output modules for file formats such as binary,
41  * VCD, csv, and so on. It provides an output API that frontends can use.
42  * New output modules can be added/implemented in libsigrok without having
43  * to change the frontends at all.
44  *
45  * All output modules are fed data in a stream. Devices that can stream data
46  * into libsigrok, instead of storing and then transferring the whole buffer,
47  * can thus generate output live.
48  *
49  * Output modules generate a newly allocated GString. The caller is then
50  * expected to free this with g_string_free() when finished with it.
51  *
52  * @{
53  */
54 
55 /** @cond PRIVATE */
56 extern SR_PRIV struct sr_output_module output_bits;
57 extern SR_PRIV struct sr_output_module output_hex;
58 extern SR_PRIV struct sr_output_module output_ascii;
59 extern SR_PRIV struct sr_output_module output_binary;
60 extern SR_PRIV struct sr_output_module output_vcd;
61 extern SR_PRIV struct sr_output_module output_ols;
62 extern SR_PRIV struct sr_output_module output_chronovu_la8;
63 extern SR_PRIV struct sr_output_module output_csv;
64 extern SR_PRIV struct sr_output_module output_analog;
65 extern SR_PRIV struct sr_output_module output_srzip;
66 extern SR_PRIV struct sr_output_module output_wav;
67 /* @endcond */
68 
69 static const struct sr_output_module *output_module_list[] = {
70  &output_ascii,
71  &output_binary,
72  &output_bits,
73  &output_csv,
74  &output_hex,
75  &output_ols,
76  &output_vcd,
77  &output_chronovu_la8,
78  &output_analog,
79  &output_srzip,
80  &output_wav,
81  NULL,
82 };
83 
84 /**
85  * Returns a NULL-terminated list of all available output modules.
86  *
87  * @since 0.4.0
88  */
89 SR_API const struct sr_output_module **sr_output_list(void)
90 {
91  return output_module_list;
92 }
93 
94 /**
95  * Returns the specified output module's ID.
96  *
97  * @since 0.4.0
98  */
99 SR_API const char *sr_output_id_get(const struct sr_output_module *omod)
100 {
101  if (!omod) {
102  sr_err("Invalid output module NULL!");
103  return NULL;
104  }
105 
106  return omod->id;
107 }
108 
109 /**
110  * Returns the specified output module's name.
111  *
112  * @since 0.4.0
113  */
114 SR_API const char *sr_output_name_get(const struct sr_output_module *omod)
115 {
116  if (!omod) {
117  sr_err("Invalid output module NULL!");
118  return NULL;
119  }
120 
121  return omod->name;
122 }
123 
124 /**
125  * Returns the specified output module's description.
126  *
127  * @since 0.4.0
128  */
129 SR_API const char *sr_output_description_get(const struct sr_output_module *omod)
130 {
131  if (!omod) {
132  sr_err("Invalid output module NULL!");
133  return NULL;
134  }
135 
136  return omod->desc;
137 }
138 
139 /**
140  * Returns the specified output module's file extensions typical for the file
141  * format, as a NULL terminated array, or returns a NULL pointer if there is
142  * no preferred extension.
143  * @note these are a suggestions only.
144  *
145  * @since 0.4.0
146  */
147 SR_API const char *const *sr_output_extensions_get(
148  const struct sr_output_module *omod)
149 {
150  if (!omod) {
151  sr_err("Invalid output module NULL!");
152  return NULL;
153  }
154 
155  return omod->exts;
156 }
157 
158 /*
159  * Checks whether a given flag is set.
160  *
161  * @see sr_output_flag
162  * @since 0.4.0
163  */
164 SR_API gboolean sr_output_test_flag(const struct sr_output_module *omod,
165  uint64_t flag)
166 {
167  return (flag & omod->flags);
168 }
169 
170 /**
171  * Return the output module with the specified ID, or NULL if no module
172  * with that id is found.
173  *
174  * @since 0.4.0
175  */
176 SR_API const struct sr_output_module *sr_output_find(char *id)
177 {
178  int i;
179 
180  for (i = 0; output_module_list[i]; i++) {
181  if (!strcmp(output_module_list[i]->id, id))
182  return output_module_list[i];
183  }
184 
185  return NULL;
186 }
187 
188 /**
189  * Returns a NULL-terminated array of struct sr_option, or NULL if the
190  * module takes no options.
191  *
192  * Each call to this function must be followed by a call to
193  * sr_output_options_free().
194  *
195  * @since 0.4.0
196  */
197 SR_API const struct sr_option **sr_output_options_get(const struct sr_output_module *omod)
198 {
199  const struct sr_option *mod_opts, **opts;
200  int size, i;
201 
202  if (!omod || !omod->options)
203  return NULL;
204 
205  mod_opts = omod->options();
206 
207  for (size = 0; mod_opts[size].id; size++)
208  ;
209  opts = g_malloc((size + 1) * sizeof(struct sr_option *));
210 
211  for (i = 0; i < size; i++)
212  opts[i] = &mod_opts[i];
213  opts[i] = NULL;
214 
215  return opts;
216 }
217 
218 /**
219  * After a call to sr_output_options_get(), this function cleans up all
220  * resources returned by that call.
221  *
222  * @since 0.4.0
223  */
224 SR_API void sr_output_options_free(const struct sr_option **options)
225 {
226  int i;
227 
228  if (!options)
229  return;
230 
231  for (i = 0; options[i]; i++) {
232  if (options[i]->def) {
233  g_variant_unref(options[i]->def);
234  ((struct sr_option *)options[i])->def = NULL;
235  }
236 
237  if (options[i]->values) {
238  g_slist_free_full(options[i]->values, (GDestroyNotify)g_variant_unref);
239  ((struct sr_option *)options[i])->values = NULL;
240  }
241  }
242  g_free(options);
243 }
244 
245 /**
246  * Create a new output instance using the specified output module.
247  *
248  * <code>options</code> is a *HashTable with the keys corresponding with
249  * the module options' <code>id</code> field. The values should be GVariant
250  * pointers with sunk * references, of the same GVariantType as the option's
251  * default value.
252  *
253  * The sr_dev_inst passed in can be used by the instance to determine
254  * channel names, samplerate, and so on.
255  *
256  * @since 0.4.0
257  */
258 SR_API const struct sr_output *sr_output_new(const struct sr_output_module *omod,
259  GHashTable *options, const struct sr_dev_inst *sdi,
260  const char *filename)
261 {
262  struct sr_output *op;
263  const struct sr_option *mod_opts;
264  const GVariantType *gvt;
265  GHashTable *new_opts;
266  GHashTableIter iter;
267  gpointer key, value;
268  int i;
269 
270  op = g_malloc(sizeof(struct sr_output));
271  op->module = omod;
272  op->sdi = sdi;
273  op->filename = g_strdup(filename);
274 
275  new_opts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
276  (GDestroyNotify)g_variant_unref);
277  if (omod->options) {
278  mod_opts = omod->options();
279  for (i = 0; mod_opts[i].id; i++) {
280  if (options && g_hash_table_lookup_extended(options,
281  mod_opts[i].id, &key, &value)) {
282  /* Pass option along. */
283  gvt = g_variant_get_type(mod_opts[i].def);
284  if (!g_variant_is_of_type(value, gvt)) {
285  sr_err("Invalid type for '%s' option.",
286  (char *)key);
287  g_free(op);
288  return NULL;
289  }
290  g_hash_table_insert(new_opts, g_strdup(mod_opts[i].id),
291  g_variant_ref(value));
292  } else {
293  /* Option not given: insert the default value. */
294  g_hash_table_insert(new_opts, g_strdup(mod_opts[i].id),
295  g_variant_ref(mod_opts[i].def));
296  }
297  }
298 
299  /* Make sure no invalid options were given. */
300  if (options) {
301  g_hash_table_iter_init(&iter, options);
302  while (g_hash_table_iter_next(&iter, &key, &value)) {
303  if (!g_hash_table_lookup(new_opts, key)) {
304  sr_err("Output module '%s' has no option '%s'",
305  omod->id, (char *)key);
306  g_hash_table_destroy(new_opts);
307  g_free(op);
308  return NULL;
309  }
310  }
311  }
312  }
313 
314  if (op->module->init && op->module->init(op, new_opts) != SR_OK) {
315  g_free(op);
316  op = NULL;
317  }
318  if (new_opts)
319  g_hash_table_destroy(new_opts);
320 
321  return op;
322 }
323 
324 /**
325  * Send a packet to the specified output instance.
326  *
327  * The instance's output is returned as a newly allocated GString,
328  * which must be freed by the caller.
329  *
330  * @since 0.4.0
331  */
332 SR_API int sr_output_send(const struct sr_output *o,
333  const struct sr_datafeed_packet *packet, GString **out)
334 {
335  return o->module->receive(o, packet, out);
336 }
337 
338 /**
339  * Free the specified output instance and all associated resources.
340  *
341  * @since 0.4.0
342  */
343 SR_API int sr_output_free(const struct sr_output *o)
344 {
345  int ret;
346 
347  if (!o)
348  return SR_ERR_ARG;
349 
350  ret = SR_OK;
351  if (o->module->cleanup)
352  ret = o->module->cleanup((struct sr_output *)o);
353  g_free((char *)o->filename);
354  g_free((gpointer)o);
355 
356  return ret;
357 }
358 
359 /** @} */
void sr_output_options_free(const struct sr_option **options)
After a call to sr_output_options_get(), this function cleans up all resources returned by that call...
Definition: output.c:224
Generic option struct used by various subsystems.
Definition: libsigrok.h:542
int sr_output_send(const struct sr_output *o, const struct sr_datafeed_packet *packet, GString **out)
Send a packet to the specified output instance.
Definition: output.c:332
const char * id
Definition: libsigrok.h:544
No error.
Definition: libsigrok.h:67
const char * sr_output_name_get(const struct sr_output_module *omod)
Returns the specified output module's name.
Definition: output.c:114
const char * sr_output_id_get(const struct sr_output_module *omod)
Returns the specified output module's ID.
Definition: output.c:99
The public libsigrok header file to be used by frontends.
const struct sr_output_module * sr_output_find(char *id)
Return the output module with the specified ID, or NULL if no module with that id is found...
Definition: output.c:176
GSList * values
Definition: libsigrok.h:552
const char * sr_output_description_get(const struct sr_output_module *omod)
Returns the specified output module's description.
Definition: output.c:129
Packet in a sigrok data feed.
Definition: libsigrok.h:476
int sr_output_free(const struct sr_output *o)
Free the specified output instance and all associated resources.
Definition: output.c:343
#define SR_PRIV
Definition: libsigrok.h:128
const struct sr_output_module ** sr_output_list(void)
Returns a NULL-terminated list of all available output modules.
Definition: output.c:89
Function argument error.
Definition: libsigrok.h:70
const struct sr_output * sr_output_new(const struct sr_output_module *omod, GHashTable *options, const struct sr_dev_inst *sdi, const char *filename)
Create a new output instance using the specified output module.
Definition: output.c:258
gboolean sr_output_test_flag(const struct sr_output_module *omod, uint64_t flag)
Definition: output.c:164
const char *const * sr_output_extensions_get(const struct sr_output_module *omod)
Returns the specified output module's file extensions typical for the file format, as a NULL terminated array, or returns a NULL pointer if there is no preferred extension.
Definition: output.c:147
const struct sr_option ** sr_output_options_get(const struct sr_output_module *omod)
Returns a NULL-terminated array of struct sr_option, or NULL if the module takes no options...
Definition: output.c:197
GVariant * def
Definition: libsigrok.h:550
#define SR_API
Definition: libsigrok.h:121