]> sigrok.org Git - libsigrok.git/blame - src/output/output.c
Drop trailing whitespace in various files.
[libsigrok.git] / src / output / output.c
CommitLineData
a1bb33af 1/*
50985c20 2 * This file is part of the libsigrok project.
a1bb33af 3 *
17bfaca6 4 * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
a1bb33af
UH
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
6ec6c43b 20#include <config.h>
a755b0e1 21#include <string.h>
c1aae900 22#include <libsigrok/libsigrok.h>
45c59c8b 23#include "libsigrok-internal.h"
a1bb33af 24
e00b3f58 25/** @cond PRIVATE */
a755b0e1 26#define LOG_PREFIX "output"
e00b3f58 27/** @endcond */
a755b0e1 28
393fb9cb
UH
29/**
30 * @file
31 *
a755b0e1 32 * Output module handling.
393fb9cb
UH
33 */
34
7b870c38 35/**
a755b0e1 36 * @defgroup grp_output Output modules
7b870c38 37 *
a755b0e1 38 * Output module handling.
7b870c38 39 *
a755b0e1 40 * libsigrok supports several output modules for file formats such as binary,
f9c6b5cf 41 * VCD, csv, and so on. It provides an output API that frontends can use.
a755b0e1 42 * New output modules can be added/implemented in libsigrok without having
07e1aad5
UH
43 * to change the frontends at all.
44 *
45 * All output modules are fed data in a stream. Devices that can stream data
dba3e682
BV
46 * into libsigrok, instead of storing and then transferring the whole buffer,
47 * can thus generate output live.
07e1aad5 48 *
dba3e682
BV
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.
07e1aad5 51 *
7b870c38
UH
52 * @{
53 */
54
b4bd7088 55/** @cond PRIVATE */
a755b0e1
BV
56extern SR_PRIV struct sr_output_module output_bits;
57extern SR_PRIV struct sr_output_module output_hex;
58extern SR_PRIV struct sr_output_module output_ascii;
59extern SR_PRIV struct sr_output_module output_binary;
60extern SR_PRIV struct sr_output_module output_vcd;
61extern SR_PRIV struct sr_output_module output_ols;
a755b0e1
BV
62extern SR_PRIV struct sr_output_module output_chronovu_la8;
63extern SR_PRIV struct sr_output_module output_csv;
64extern SR_PRIV struct sr_output_module output_analog;
3250d8c7 65extern SR_PRIV struct sr_output_module output_srzip;
afaa75b9 66extern SR_PRIV struct sr_output_module output_wav;
b4bd7088 67/* @endcond */
a1bb33af 68
a755b0e1 69static const struct sr_output_module *output_module_list[] = {
6f64ebb2 70 &output_ascii,
1c5b9d30 71 &output_binary,
dba3e682
BV
72 &output_bits,
73 &output_csv,
dba3e682
BV
74 &output_hex,
75 &output_ols,
76 &output_vcd,
8c48f179 77 &output_chronovu_la8,
161a8a27 78 &output_analog,
3250d8c7 79 &output_srzip,
afaa75b9 80 &output_wav,
4c9ffa83 81 NULL,
a1bb33af
UH
82};
83
a755b0e1 84/**
63f6df68 85 * Returns a NULL-terminated list of all available output modules.
a755b0e1
BV
86 *
87 * @since 0.4.0
88 */
89SR_API const struct sr_output_module **sr_output_list(void)
a1bb33af 90{
a1bb33af
UH
91 return output_module_list;
92}
7b870c38 93
a755b0e1
BV
94/**
95 * Returns the specified output module's ID.
96 *
97 * @since 0.4.0
98 */
4fb0a5f8 99SR_API const char *sr_output_id_get(const struct sr_output_module *omod)
a755b0e1 100{
4fb0a5f8 101 if (!omod) {
a755b0e1
BV
102 sr_err("Invalid output module NULL!");
103 return NULL;
104 }
105
4fb0a5f8 106 return omod->id;
a755b0e1
BV
107}
108
109/**
110 * Returns the specified output module's name.
111 *
112 * @since 0.4.0
113 */
4fb0a5f8 114SR_API const char *sr_output_name_get(const struct sr_output_module *omod)
a755b0e1 115{
4fb0a5f8 116 if (!omod) {
a755b0e1
BV
117 sr_err("Invalid output module NULL!");
118 return NULL;
119 }
120
4fb0a5f8 121 return omod->name;
a755b0e1
BV
122}
123
124/**
125 * Returns the specified output module's description.
126 *
127 * @since 0.4.0
128 */
4fb0a5f8 129SR_API const char *sr_output_description_get(const struct sr_output_module *omod)
a755b0e1 130{
4fb0a5f8 131 if (!omod) {
a755b0e1
BV
132 sr_err("Invalid output module NULL!");
133 return NULL;
134 }
135
4fb0a5f8 136 return omod->desc;
a755b0e1
BV
137}
138
8a174d23
JH
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 */
147SR_API const char *const *sr_output_extensions_get(
4fb0a5f8 148 const struct sr_output_module *omod)
8a174d23 149{
4fb0a5f8 150 if (!omod) {
8a174d23
JH
151 sr_err("Invalid output module NULL!");
152 return NULL;
153 }
154
4fb0a5f8 155 return omod->exts;
8a174d23
JH
156}
157
3cd4b381
SA
158/*
159 * Checks whether a given flag is set.
160 *
161 * @see sr_output_flag
162 * @since 0.4.0
163 */
164SR_API gboolean sr_output_test_flag(const struct sr_output_module *omod,
165 uint64_t flag)
166{
167 return (flag & omod->flags);
168}
169
a755b0e1
BV
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 */
176SR_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 */
4fb0a5f8 197SR_API const struct sr_option **sr_output_options_get(const struct sr_output_module *omod)
a755b0e1 198{
fc746430
BV
199 const struct sr_option *mod_opts, **opts;
200 int size, i;
a755b0e1 201
4fb0a5f8 202 if (!omod || !omod->options)
a755b0e1
BV
203 return NULL;
204
4fb0a5f8 205 mod_opts = omod->options();
fc746430 206
fdefc40a 207 for (size = 0; mod_opts[size].id; size++)
fc746430 208 ;
879dd50f 209 opts = g_malloc((size + 1) * sizeof(struct sr_option *));
fc746430
BV
210
211 for (i = 0; i < size; i++)
212 opts[i] = &mod_opts[i];
213 opts[i] = NULL;
214
215 return opts;
a755b0e1
BV
216}
217
218/**
219 * After a call to sr_output_options_get(), this function cleans up all
fc746430 220 * resources returned by that call.
a755b0e1
BV
221 *
222 * @since 0.4.0
223 */
499c85dc 224SR_API void sr_output_options_free(const struct sr_option **options)
dba3e682 225{
499c85dc 226 int i;
a755b0e1 227
499c85dc 228 if (!options)
a755b0e1
BV
229 return;
230
499c85dc
BV
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;
a755b0e1
BV
235 }
236
499c85dc
BV
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;
a755b0e1 240 }
dba3e682 241 }
499c85dc 242 g_free(options);
a755b0e1 243}
dba3e682 244
a755b0e1
BV
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 */
4fb0a5f8 258SR_API const struct sr_output *sr_output_new(const struct sr_output_module *omod,
81b3ce37
SA
259 GHashTable *options, const struct sr_dev_inst *sdi,
260 const char *filename)
a755b0e1
BV
261{
262 struct sr_output *op;
af7d656d 263 const struct sr_option *mod_opts;
dcc55fe9
BV
264 const GVariantType *gvt;
265 GHashTable *new_opts;
266 GHashTableIter iter;
267 gpointer key, value;
268 int i;
a755b0e1
BV
269
270 op = g_malloc(sizeof(struct sr_output));
4fb0a5f8 271 op->module = omod;
a755b0e1 272 op->sdi = sdi;
81b3ce37 273 op->filename = g_strdup(filename);
950043c3 274
63f6df68
BV
275 new_opts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
276 (GDestroyNotify)g_variant_unref);
4fb0a5f8
UH
277 if (omod->options) {
278 mod_opts = omod->options();
dcc55fe9 279 for (i = 0; mod_opts[i].id; i++) {
63f6df68
BV
280 if (options && g_hash_table_lookup_extended(options,
281 mod_opts[i].id, &key, &value)) {
282 /* Pass option along. */
dcc55fe9
BV
283 gvt = g_variant_get_type(mod_opts[i].def);
284 if (!g_variant_is_of_type(value, gvt)) {
6433156c
DE
285 sr_err("Invalid type for '%s' option.",
286 (char *)key);
dcc55fe9
BV
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 {
63f6df68 293 /* Option not given: insert the default value. */
dcc55fe9
BV
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. */
63f6df68
BV
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)) {
6433156c
DE
304 sr_err("Output module '%s' has no option '%s'",
305 omod->id, (char *)key);
63f6df68
BV
306 g_hash_table_destroy(new_opts);
307 g_free(op);
308 return NULL;
309 }
dcc55fe9
BV
310 }
311 }
63f6df68 312 }
dcc55fe9
BV
313
314 if (op->module->init && op->module->init(op, new_opts) != SR_OK) {
a755b0e1
BV
315 g_free(op);
316 op = NULL;
317 }
706f482a
BV
318 if (new_opts)
319 g_hash_table_destroy(new_opts);
a755b0e1
BV
320
321 return op;
dba3e682
BV
322}
323
a755b0e1
BV
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 */
332SR_API int sr_output_send(const struct sr_output *o,
dba3e682
BV
333 const struct sr_datafeed_packet *packet, GString **out)
334{
a755b0e1 335 return o->module->receive(o, packet, out);
dba3e682
BV
336}
337
a755b0e1
BV
338/**
339 * Free the specified output instance and all associated resources.
340 *
341 * @since 0.4.0
342 */
343SR_API int sr_output_free(const struct sr_output *o)
dba3e682
BV
344{
345 int ret;
346
a755b0e1
BV
347 if (!o)
348 return SR_ERR_ARG;
349
dba3e682 350 ret = SR_OK;
a755b0e1
BV
351 if (o->module->cleanup)
352 ret = o->module->cleanup((struct sr_output *)o);
81b3ce37 353 g_free((char *)o->filename);
a755b0e1 354 g_free((gpointer)o);
dba3e682
BV
355
356 return ret;
357}
358
7b870c38 359/** @} */