]> sigrok.org Git - libsigrok.git/commitdiff
output: Introduce output module API wrappers.
authorBert Vermeulen <redacted>
Sun, 20 Apr 2014 20:51:09 +0000 (22:51 +0200)
committerBert Vermeulen <redacted>
Sun, 20 Apr 2014 23:50:43 +0000 (01:50 +0200)
14 files changed:
Makefile.am
libsigrok.h
output/analog.c
output/ascii.c
output/binary.c
output/bits.c
output/chronovu_la8.c
output/csv.c
output/gnuplot.c
output/hex.c
output/ols.c
output/output.c
output/vcd.c
proto.h

index 4023778b117c3a24318483e646b63aeb1e5521cd..a88d264b3615fb9c8f93ab08d730cec2d8e8a174 100644 (file)
@@ -49,17 +49,17 @@ libsigrok_la_SOURCES += \
 
 # 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 += \
index f9678de76e4f7c6dca37a5b0d8401dd96e3f160d..f233b8cc47b7da5d9a997037bf49f3d879fece32 100644 (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);
 
        /**
index 131e24c487bfee8177a3cd6c24759178ef4da4df..bdb55733c492576d51e5ab72c7e1a5f4dfd2419d 100644 (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;
index 884769c8a504cf0ed28da019f486b8124d1306f6..44bd0b1546a136676af1bafb90e02cc92b0f246b 100644 (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;
index d631773fb540412f2744724e360d7acd070c76a3..6e2531d1a252af1e7a92ed63e14c0b2783c0824f 100644 (file)
 #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,
 };
index 9b4d34876326e49df60fc7f8c7122b43ac7709db..e0c64864db5b42e6a67c83c18c394f3516d145ba 100644 (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;
index 08164e6b6a0826a7a89da79edeee6b1487e4bc56..ad0b5d32fc2c1ccaf294fabdf7035cd977cecefe 100644 (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;
index 8e012212969caeeb7f348945783ac85865110926..0bec7ae281c4286825eb54f586828bdc2f683f10 100644 (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;
index 0eb116d291d3e3e7e3eb888f72e73df2a4f4095b..33a3ee0af305c6810b81c1f8ccb19072d854014a 100644 (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;
index 85ce90697033c091000e412786be87e7a20b92c2..a49d9d9283b32be70b71114f2449e1e39255baf2 100644 (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;
index 02e34e47672556a4c73b2a41bd066ea675b09c81..78a41bb0b4645032eb342ef1796246d165b6da6b 100644 (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) {
index a0c81e82bae664dd30d3905b5bb5cb4059b2316a..941678ec8d2185887b10cd429fcbb7582c8996c2 100644 (file)
  * 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_bits,
+       &output_csv,
        &output_gnuplot,
+       &output_hex,
+       &output_ols,
+       &output_vcd,
        &output_chronovu_la8,
-       &output_csv,
        &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;
+}
+
+
 /** @} */
index 7453b507fccd3b7ad999b64dce3fcf90eaa932ad..4d853057b5c712d208b642fa94838a86b1608f42 100644 (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;
diff --git a/proto.h b/proto.h
index 16bc269b099bf787a442f95bf748f3677c5cf96e..06e03766800d2dba83a8732bf5c6596e06192be4 100644 (file)
--- a/proto.h
+++ b/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 -------------------------------------------------------------*/