]> sigrok.org Git - libsigrok.git/commitdiff
output_ols: now fully compliant with spec
authorBert Vermeulen <redacted>
Tue, 1 Feb 2011 05:13:32 +0000 (06:13 +0100)
committerBert Vermeulen <redacted>
Tue, 1 Feb 2011 05:13:32 +0000 (06:13 +0100)
output/output_ols.c

index 55230bf3f29934f76ff8e93954d7045d5c290d7d..1c57aee8e7579ca5c64754529a4d4bdf9d771c1d 100644 (file)
@@ -2,6 +2,7 @@
  * This file is part of the sigrok project.
  *
  * Copyright (C) 2011 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2011 Bert Vermeulen <bert@biot.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "config.h"
 
 struct context {
-       unsigned int num_enabled_probes;
+       GString *header;
+       GString *body;
+       uint64_t num_samples;
+       gboolean got_trigger;
+       uint64_t trigger_pos;
        unsigned int unitsize;
-       char *probelist[MAX_NUM_PROBES + 1];
-       char *header;
 };
 
-/* FIXME */
-#define MAX_HEADER_LEN 2048
-
-/* TODO: Support cursors? */
-#define OLS_HEADER \
-"# Generated by: %s on %s%s\n" \
-"# Probe list used for capturing:\n" \
-"# Number:\tName:\n" \
-"%s" \
-";Size: %" PRIu64 "\n" \
-";Rate: %" PRIu64 "\n" \
-";Channels: %d\n" \
-";EnabledChannels: -1\n" \
-";Compressed: true\n" \
-";AbsoluteLength: %" PRIu64 "\n" \
-";CursorEnabled: false\n" \
-";Cursor0: -9223372036854775808\n" \
-";Cursor1: -9223372036854775808\n" \
-";Cursor2: -9223372036854775808\n" \
-";Cursor3: -9223372036854775808\n" \
-";Cursor4: -9223372036854775808\n" \
-";Cursor5: -9223372036854775808\n" \
-";Cursor6: -9223372036854775808\n" \
-";Cursor7: -9223372036854775808\n" \
-";Cursor8: -9223372036854775808\n" \
-";Cursor9: -9223372036854775808\n"
-
-const char *ols_header_comment = "\
-# Comment: Acquisition with %d/%d probes at %s";
 
-static int init(struct sr_output *o)
+static void make_header(struct sr_output *o)
 {
        struct context *ctx;
-       struct probe *probe;
-       GSList *l;
        uint64_t samplerate;
-       unsigned int i;
-       int b, num_probes;
-       char *c, *frequency_s;
-       char wbuf[1000], comment[128];
-       time_t t;
-
-       if (!(ctx = calloc(1, sizeof(struct context))))
-               return SR_ERR_MALLOC;
-
-       if (!(ctx->header = calloc(1, MAX_HEADER_LEN + 1))) {
-               free(ctx);
-               return SR_ERR_MALLOC;
-       }
-
-       o->internal = ctx;
-       ctx->num_enabled_probes = 0;
-       for (l = o->device->probes; l; l = l->next) {
-               probe = l->data;
-               if (!probe->enabled)
-                       continue;
-               ctx->probelist[ctx->num_enabled_probes++] = probe->name;
-       }
-       ctx->probelist[ctx->num_enabled_probes] = 0;
-       ctx->unitsize = (ctx->num_enabled_probes + 7) / 8;
-
-       num_probes = g_slist_length(o->device->probes);
-       comment[0] = '\0';
+       int i;
 
-       /* TODO: Currently not available in the demo module. */
+       ctx = o->internal;
 
-       if (o->device->plugin && device_has_hwcap(o->device, SR_HWCAP_SAMPLERATE)) {
+       if (o->device->plugin && device_has_hwcap(o->device, SR_HWCAP_SAMPLERATE))
                samplerate = *((uint64_t *) o->device->plugin->get_device_info(
                                o->device->plugin_index, SR_DI_CUR_SAMPLERATE));
-               if (!(frequency_s = sr_samplerate_string(samplerate))) {
-                       free(ctx->header);
-                       free(ctx);
-                       return SR_ERR;
-               }
-               snprintf(comment, 127, ols_header_comment,
-                        ctx->num_enabled_probes, num_probes, frequency_s);
-               free(frequency_s);
-       }
-
-       /* Columns / channels */
-       wbuf[0] = '\0';
-       for (i = 0; i < ctx->num_enabled_probes; i++) {
-               c = (char *)&wbuf + strlen((char *)&wbuf);
-               sprintf(c, "# %d\t\t%s\n", i + 1, ctx->probelist[i]);
-       }
-
-       if (!(frequency_s = sr_period_string(samplerate))) {
-               free(ctx->header);
-               free(ctx);
-               return SR_ERR;
-       }
+       else
+               samplerate = 0;
+
+       g_string_append_printf(ctx->header, ";Size: %"PRIu64"\n", ctx->num_samples);
+       g_string_append_printf(ctx->header, ";Rate: %"PRIu64"\n", samplerate);
+       g_string_append_printf(ctx->header, ";Channels: %d\n", ctx->unitsize*8);
+       g_string_append_printf(ctx->header, ";EnabledChannels: -1\n");
+       if (ctx->got_trigger)
+               g_string_append_printf(ctx->header, ";TriggerPosition: %"PRIu64"\n", ctx->trigger_pos);
+       g_string_append_printf(ctx->header, ";Compressed: true\n");
+       g_string_append_printf(ctx->header, ";AbsoluteLength: %"PRIu64"\n", ctx->num_samples);
+       g_string_append_printf(ctx->header, ";CursorEnabled: false\n");
+       for (i = 0; i < 10; i++)
+               g_string_append_printf(ctx->header, ";Cursor%d: 0\n", i);
 
-       t = time(NULL);
-
-       /* TODO: Special handling for the demo driver. */
-       /* TODO: Don't hardcode numsamples! */
-       /* TODO: Check if num_enabled_probes/channels setting is correct. */
-       b = snprintf(ctx->header, MAX_HEADER_LEN, OLS_HEADER,
-                    PACKAGE_STRING, ctime(&t),
-                    comment,
-                    (const char *)&wbuf,
-                    (uint64_t)10000 /* numsamples */,
-                    samplerate,
-                    ctx->num_enabled_probes,
-                    (uint64_t)10000 /* numsamples */);
+}
 
-       /* TODO: Yield errors on stuff the OLS format doesn't support. */
+static int init(struct sr_output *o)
+{
+       struct context *ctx;
+       struct probe *probe;
+       GSList *l;
+       int num_enabled_probes;
 
-       free(frequency_s);
+       if (!(ctx = g_malloc(sizeof(struct context))))
+               return SR_ERR_MALLOC;
 
-       if (b < 0) {
-               free(ctx->header);
-               free(ctx);
-               return SR_ERR;
+       o->internal = ctx;
+       ctx->header = g_string_sized_new(512);
+       ctx->body = g_string_sized_new(512);
+       ctx->num_samples = 0;
+       ctx->got_trigger = FALSE;
+       ctx->trigger_pos = 0;
+       num_enabled_probes = 0;
+       for (l = o->device->probes; l; l = l->next) {
+               probe = l->data;
+               if (probe->enabled)
+                       num_enabled_probes++;
        }
+       ctx->unitsize = (num_enabled_probes + 7) / 8;
 
-       return 0;
+       return SR_OK;
 }
 
 static int event(struct sr_output *o, int event_type, char **data_out,
@@ -161,19 +101,27 @@ static int event(struct sr_output *o, int event_type, char **data_out,
        struct context *ctx;
 
        ctx = o->internal;
+       *data_out = NULL;
+       *length_out = 0;
+
        switch (event_type) {
        case SR_DF_TRIGGER:
-               /* TODO */
+               ctx->got_trigger = TRUE;
+               ctx->trigger_pos = ctx->num_samples;
                break;
        case SR_DF_END:
+               make_header(o);
+               *length_out = ctx->header->len + ctx->body->len;
+               *data_out = g_malloc(*length_out);
+               memcpy(*data_out, ctx->header->str, ctx->header->len);
+               memcpy(*data_out + ctx->header->len, ctx->body->str, ctx->body->len);
+               g_string_free(ctx->header, TRUE);
+               g_string_free(ctx->body, TRUE);
                free(o->internal);
                o->internal = NULL;
                break;
        }
 
-       *data_out = NULL;
-       *length_out = 0;
-
        return SR_OK;
 }
 
@@ -181,39 +129,19 @@ static int data(struct sr_output *o, char *data_in, uint64_t length_in,
                char **data_out, uint64_t *length_out)
 {
        struct context *ctx;
-       unsigned int max_linelen, outsize, i;
        uint64_t sample;
-       static uint64_t samplecount = 0;
-       char *outbuf, *c;
+       unsigned int i;
 
        ctx = o->internal;
-       max_linelen = 100; /* FIXME */
-       outsize = length_in / ctx->unitsize * max_linelen;
-       if (ctx->header)
-               outsize += strlen(ctx->header);
-
-       if (!(outbuf = calloc(1, outsize)))
-               return SR_ERR_MALLOC;
-
-       outbuf[0] = '\0';
-       if (ctx->header) {
-               /* The header is still here, this must be the first packet. */
-               strncpy(outbuf, ctx->header, outsize);
-               free(ctx->header);
-               ctx->header = NULL;
-       }
-
        for (i = 0; i <= length_in - ctx->unitsize; i += ctx->unitsize) {
+               sample = 0;
                memcpy(&sample, data_in + i, ctx->unitsize);
-
-               c = outbuf + strlen(outbuf);
-               /* FIXME: OLS seems to only support 2^31 total samples? */
-               sprintf(c, "%08x@%" PRIu64 "\n", (uint32_t)sample,
-                       samplecount++);
+               g_string_append_printf(ctx->body, "%08x@%"PRIu64"\n",
+                               (uint32_t) sample, ctx->num_samples++);
        }
 
-       *data_out = outbuf;
-       *length_out = strlen(outbuf);
+       *data_out = NULL;
+       *length_out = 0;
 
        return SR_OK;
 }