# Output formats
libsigrok_la_SOURCES += \
- output/binary.c \
+ output/output.c \
+ output/analog.c \
+ output/ascii.c \
output/bits.c \
- output/vcd.c \
- output/ols.c \
- output/gnuplot.c \
- output/chronovu_la8.c \
+ output/binary.c \
output/csv.c \
- output/analog.c \
- output/output.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 += \
/** 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
* @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);
/**
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;
const float *fdata;
int i, p;
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
struct sr_channel *ch;
GSList *l;
GVariant *gvar;
+ GHashTableIter iter;
+ gpointer key, value;
uint64_t samplerate;
unsigned int i, j;
int spl, num_channels;
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) {
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;
uint64_t i, j;
gchar *p, c;
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
#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)
SR_PRIV struct sr_output_format output_binary = {
.id = "binary",
.description = "Raw binary",
- .init = NULL,
.receive = receive,
};
struct sr_channel *ch;
GSList *l;
GVariant *gvar;
+ GHashTableIter iter;
+ gpointer key, value;
uint64_t samplerate;
unsigned int i, j;
int spl, num_channels;
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) {
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;
uint64_t i, j;
gchar *p, c;
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
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;
uint64_t samplerate;
gchar c[4];
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
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;
uint64_t i, j;
gchar *p, c;
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
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;
struct sr_channel *ch;
GSList *l;
GVariant *gvar;
+ GHashTableIter iter;
+ gpointer key, value;
uint64_t samplerate;
unsigned int i, j;
int spl, num_channels;
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) {
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;
uint64_t i, j;
gchar *p;
- (void)sdi;
-
*out = NULL;
if (!o || !o->sdi)
return SR_ERR_ARG;
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;
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) {
* 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.
*
* @{
*/
/* @endcond */
static struct sr_output_format *output_module_list[] = {
- &output_bits,
- &output_hex,
&output_ascii,
&output_binary,
- &output_vcd,
- &output_ols,
+ &output_bits,
+ &output_csv,
&output_gnuplot,
+ &output_hex,
+ &output_ols,
+ &output_vcd,
&output_chronovu_la8,
- &output_csv,
&output_analog,
NULL,
};
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;
+}
+
+
/** @} */
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;
uint8_t *sample;
gboolean timestamp_written;
- (void)sdi;
-
*out = NULL;
if (!o || !o->internal)
return SR_ERR_BUG;
/*--- 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 -------------------------------------------------------------*/