output: Introduce output module API wrappers.
This commit is contained in:
parent
7e7b7fb7d3
commit
dba3e6826e
18
Makefile.am
18
Makefile.am
|
@ -49,17 +49,17 @@ libsigrok_la_SOURCES += \
|
|||
|
||||
# Output formats
|
||||
libsigrok_la_SOURCES += \
|
||||
output/binary.c \
|
||||
output/bits.c \
|
||||
output/vcd.c \
|
||||
output/ols.c \
|
||||
output/gnuplot.c \
|
||||
output/chronovu_la8.c \
|
||||
output/csv.c \
|
||||
output/analog.c \
|
||||
output/output.c \
|
||||
output/analog.c \
|
||||
output/ascii.c \
|
||||
output/bits.c \
|
||||
output/binary.c \
|
||||
output/csv.c \
|
||||
output/chronovu_la8.c \
|
||||
output/gnuplot.c \
|
||||
output/hex.c \
|
||||
output/ascii.c
|
||||
output/ols.c \
|
||||
output/vcd.c
|
||||
|
||||
# Hardware (common files)
|
||||
libsigrok_la_SOURCES += \
|
||||
|
|
11
libsigrok.h
11
libsigrok.h
|
@ -430,24 +430,21 @@ struct sr_input_format {
|
|||
|
||||
/** Output (file) format struct. */
|
||||
struct sr_output {
|
||||
/**
|
||||
* A pointer to this output format's 'struct sr_output_format'.
|
||||
* The frontend can use this to call the module's callbacks.
|
||||
*/
|
||||
/** A pointer to this output's format. */
|
||||
struct sr_output_format *format;
|
||||
|
||||
/**
|
||||
* The device for which this output module is creating output. This
|
||||
* can be used by the module to find out channel names and numbers.
|
||||
*/
|
||||
struct sr_dev_inst *sdi;
|
||||
const struct sr_dev_inst *sdi;
|
||||
|
||||
/**
|
||||
* An optional parameter which the frontend can pass in to the
|
||||
* output module. How the string is interpreted is entirely up to
|
||||
* the module.
|
||||
*/
|
||||
char *param;
|
||||
GHashTable *params;
|
||||
|
||||
/**
|
||||
* A generic pointer which can be used by the module to keep internal
|
||||
|
@ -514,7 +511,7 @@ struct sr_output_format {
|
|||
* @retval SR_OK Success
|
||||
* @retval other Negative error code.
|
||||
*/
|
||||
int (*receive) (struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
int (*receive) (struct sr_output *o,
|
||||
const struct sr_datafeed_packet *packet, GString **out);
|
||||
|
||||
/**
|
||||
|
|
|
@ -206,8 +206,8 @@ static void fancyprint(int unit, int mqflags, float value, GString *out)
|
|||
g_string_append_c(out, '\n');
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_analog *analog;
|
||||
struct sr_channel *ch;
|
||||
|
@ -215,8 +215,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
const float *fdata;
|
||||
int i, p;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -48,6 +48,8 @@ static int init(struct sr_output *o)
|
|||
struct sr_channel *ch;
|
||||
GSList *l;
|
||||
GVariant *gvar;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
uint64_t samplerate;
|
||||
unsigned int i, j;
|
||||
int spl, num_channels;
|
||||
|
@ -55,15 +57,24 @@ static int init(struct sr_output *o)
|
|||
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
g_hash_table_iter_init(&iter, o->params);
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
if (!strcmp(key, "width")) {
|
||||
if ((spl = strtoul(value, NULL, 10)) < 1) {
|
||||
sr_err("Invalid width.");
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
} else {
|
||||
sr_err("Unknown parameter '%s'.", key);
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = g_malloc0(sizeof(struct context));
|
||||
o->internal = ctx;
|
||||
ctx->trigger = -1;
|
||||
|
||||
if (o->param && o->param[0]) {
|
||||
if ((spl = strtoul(o->param, NULL, 10)) < 1)
|
||||
return SR_ERR_ARG;
|
||||
} else
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
ctx->samples_per_line = spl;
|
||||
|
||||
for (l = o->sdi->channels; l; l = l->next) {
|
||||
|
@ -109,8 +120,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -118,8 +129,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint64_t i, j;
|
||||
gchar *p, c;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -24,15 +24,14 @@
|
|||
#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
|
||||
#define LOG_PREFIX "output/binary:"
|
||||
#define LOG_PREFIX "output/binary"
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
|
||||
(void)o;
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (packet->type != SR_DF_LOGIC)
|
||||
|
@ -46,6 +45,5 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
SR_PRIV struct sr_output_format output_binary = {
|
||||
.id = "binary",
|
||||
.description = "Raw binary",
|
||||
.init = NULL,
|
||||
.receive = receive,
|
||||
};
|
||||
|
|
|
@ -44,6 +44,8 @@ static int init(struct sr_output *o)
|
|||
struct sr_channel *ch;
|
||||
GSList *l;
|
||||
GVariant *gvar;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
uint64_t samplerate;
|
||||
unsigned int i, j;
|
||||
int spl, num_channels;
|
||||
|
@ -51,15 +53,24 @@ static int init(struct sr_output *o)
|
|||
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
g_hash_table_iter_init(&iter, o->params);
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
if (!strcmp(key, "width")) {
|
||||
if ((spl = strtoul(value, NULL, 10)) < 1) {
|
||||
sr_err("Invalid width.");
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
} else {
|
||||
sr_err("Unknown parameter '%s'.", key);
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = g_malloc0(sizeof(struct context));
|
||||
o->internal = ctx;
|
||||
ctx->trigger = -1;
|
||||
|
||||
if (o->param && o->param[0]) {
|
||||
if ((spl = strtoul(o->param, NULL, 10)) < 1)
|
||||
return SR_ERR_ARG;
|
||||
} else
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
ctx->samples_per_line = spl;
|
||||
|
||||
for (l = o->sdi->channels; l; l = l->next) {
|
||||
|
@ -104,8 +115,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -113,8 +124,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint64_t i, j;
|
||||
gchar *p, c;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -101,8 +101,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -110,8 +110,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint64_t samplerate;
|
||||
gchar c[4];
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -117,8 +117,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -126,8 +126,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint64_t i, j;
|
||||
gchar *p, c;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -133,16 +133,14 @@ static int init(struct sr_output *o)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
const uint8_t *sample;
|
||||
unsigned int curbit, p, idx, i;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->internal)
|
||||
return SR_ERR_BUG;
|
||||
|
|
29
output/hex.c
29
output/hex.c
|
@ -47,6 +47,8 @@ static int init(struct sr_output *o)
|
|||
struct sr_channel *ch;
|
||||
GSList *l;
|
||||
GVariant *gvar;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
uint64_t samplerate;
|
||||
unsigned int i, j;
|
||||
int spl, num_channels;
|
||||
|
@ -54,15 +56,24 @@ static int init(struct sr_output *o)
|
|||
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
g_hash_table_iter_init(&iter, o->params);
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
if (!strcmp(key, "width")) {
|
||||
if ((spl = strtoul(value, NULL, 10)) < 1) {
|
||||
sr_err("Invalid width.");
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
} else {
|
||||
sr_err("Unknown parameter '%s'.", key);
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = g_malloc0(sizeof(struct context));
|
||||
o->internal = ctx;
|
||||
ctx->trigger = -1;
|
||||
|
||||
if (o->param && o->param[0]) {
|
||||
if ((spl = strtoul(o->param, NULL, 10)) < 1)
|
||||
return SR_ERR_ARG;
|
||||
} else
|
||||
spl = DEFAULT_SAMPLES_PER_LINE;
|
||||
ctx->samples_per_line = spl;
|
||||
|
||||
for (l = o->sdi->channels; l; l = l->next) {
|
||||
|
@ -109,8 +120,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -118,8 +129,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint64_t i, j;
|
||||
gchar *p;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->sdi)
|
||||
return SR_ERR_ARG;
|
||||
|
|
|
@ -88,8 +88,8 @@ static GString *gen_header(const struct sr_dev_inst *sdi, struct context *ctx)
|
|||
return s;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
struct context *ctx;
|
||||
const struct sr_datafeed_meta *meta;
|
||||
|
@ -117,7 +117,7 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
logic = packet->payload;
|
||||
if (ctx->num_samples == 0) {
|
||||
/* First logic packet in the feed. */
|
||||
*out = gen_header(sdi, ctx);
|
||||
*out = gen_header(o->sdi, ctx);
|
||||
} else
|
||||
*out = g_string_sized_new(512);
|
||||
for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) {
|
||||
|
|
|
@ -37,13 +37,11 @@
|
|||
* to change the frontends at all.
|
||||
*
|
||||
* All output modules are fed data in a stream. Devices that can stream data
|
||||
* into libsigrok live, instead of storing and then transferring the whole
|
||||
* buffer, can thus generate output live.
|
||||
* into libsigrok, instead of storing and then transferring the whole buffer,
|
||||
* can thus generate output live.
|
||||
*
|
||||
* Output modules are responsible for allocating enough memory to store
|
||||
* their own output, and passing a pointer to that memory (and length) of
|
||||
* the allocated memory back to the caller. The caller is then expected to
|
||||
* free this memory when finished with it.
|
||||
* Output modules generate a newly allocated GString. The caller is then
|
||||
* expected to free this with g_string_free() when finished with it.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
@ -62,15 +60,15 @@ extern SR_PRIV struct sr_output_format output_analog;
|
|||
/* @endcond */
|
||||
|
||||
static struct sr_output_format *output_module_list[] = {
|
||||
&output_bits,
|
||||
&output_hex,
|
||||
&output_ascii,
|
||||
&output_binary,
|
||||
&output_vcd,
|
||||
&output_ols,
|
||||
&output_gnuplot,
|
||||
&output_chronovu_la8,
|
||||
&output_bits,
|
||||
&output_csv,
|
||||
&output_gnuplot,
|
||||
&output_hex,
|
||||
&output_ols,
|
||||
&output_vcd,
|
||||
&output_chronovu_la8,
|
||||
&output_analog,
|
||||
NULL,
|
||||
};
|
||||
|
@ -80,4 +78,40 @@ SR_API struct sr_output_format **sr_output_list(void)
|
|||
return output_module_list;
|
||||
}
|
||||
|
||||
SR_API struct sr_output *sr_output_new(struct sr_output_format *of,
|
||||
GHashTable *params, const struct sr_dev_inst *sdi)
|
||||
{
|
||||
struct sr_output *o;
|
||||
|
||||
o = g_malloc(sizeof(struct sr_output));
|
||||
o->format = of;
|
||||
o->sdi = sdi;
|
||||
o->params = params;
|
||||
if (o->format->init && o->format->init(o) != SR_OK) {
|
||||
g_free(o);
|
||||
o = NULL;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
SR_API int sr_output_send(struct sr_output *o,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
{
|
||||
return o->format->receive(o, packet, out);
|
||||
}
|
||||
|
||||
SR_API int sr_output_free(struct sr_output *o)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SR_OK;
|
||||
if (o->format->cleanup)
|
||||
ret = o->format->cleanup(o);
|
||||
g_free(o);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -139,8 +139,8 @@ static int init(struct sr_output *o)
|
|||
return SR_OK;
|
||||
}
|
||||
|
||||
static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, GString **out)
|
||||
static int receive(struct sr_output *o, const struct sr_datafeed_packet *packet,
|
||||
GString **out)
|
||||
{
|
||||
const struct sr_datafeed_logic *logic;
|
||||
struct context *ctx;
|
||||
|
@ -149,8 +149,6 @@ static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
|
|||
uint8_t *sample;
|
||||
gboolean timestamp_written;
|
||||
|
||||
(void)sdi;
|
||||
|
||||
*out = NULL;
|
||||
if (!o || !o->internal)
|
||||
return SR_ERR_BUG;
|
||||
|
|
5
proto.h
5
proto.h
|
@ -130,6 +130,11 @@ SR_API struct sr_input_format **sr_input_list(void);
|
|||
/*--- output/output.c -------------------------------------------------------*/
|
||||
|
||||
SR_API struct sr_output_format **sr_output_list(void);
|
||||
SR_API struct sr_output *sr_output_new(struct sr_output_format *of,
|
||||
GHashTable *params, const struct sr_dev_inst *sdi);
|
||||
SR_API int sr_output_send(struct sr_output *o,
|
||||
const struct sr_datafeed_packet *packet, GString **out);
|
||||
SR_API int sr_output_free(struct sr_output *o);
|
||||
|
||||
/*--- strutil.c -------------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue