output: Introduce output module API wrappers.

This commit is contained in:
Bert Vermeulen 2014-04-20 22:51:09 +02:00
parent 7e7b7fb7d3
commit dba3e6826e
14 changed files with 137 additions and 86 deletions

View File

@ -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 += \

View File

@ -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);
/**

View File

@ -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;

View File

@ -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;

View File

@ -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,
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}
/** @} */

View File

@ -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;

View File

@ -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 -------------------------------------------------------------*/