X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Finput%2Fvcd.c;h=e14215712b75c56477342a4706de8cecee5e0cf1;hb=c7bc82ffa1b09a228a8395049e2b691cd7bd85f8;hp=8111c59cf757237149be9026100a4d6a0fa3c1c1;hpb=7db0639495cb8d96aadcd17678a535c97449a677;p=libsigrok.git diff --git a/src/input/vcd.c b/src/input/vcd.c index 8111c59c..e1421571 100644 --- a/src/input/vcd.c +++ b/src/input/vcd.c @@ -70,6 +70,7 @@ #define CHUNKSIZE 1024 struct context { + gboolean started; gboolean got_header; uint64_t samplerate; unsigned int maxchannels; @@ -256,7 +257,7 @@ static int format_match(GHashTable *metadata) g_free(name); g_free(contents); - return status; + return status ? SR_OK : SR_ERR; } /* Send N samples of the given value. */ @@ -408,8 +409,6 @@ static int init(struct sr_input *in, GHashTable *options) char name[16]; struct context *inc; - inc = g_malloc0(sizeof(struct context)); - num_channels = g_variant_get_int32(g_hash_table_lookup(options, "numchannels")); if (num_channels < 1) { sr_err("Invalid value for numchannels: must be at least 1."); @@ -419,6 +418,7 @@ static int init(struct sr_input *in, GHashTable *options) sr_err("No more than 64 channels supported."); return SR_ERR_ARG; } + inc = in->priv = g_malloc0(sizeof(struct context)); inc->maxchannels = num_channels; inc->downsample = g_variant_get_int32(g_hash_table_lookup(options, "downsample")); @@ -429,8 +429,7 @@ static int init(struct sr_input *in, GHashTable *options) inc->skip = g_variant_get_int32(g_hash_table_lookup(options, "skip")); inc->skip /= inc->downsample; - /* Create a virtual device. */ - in->sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, NULL, NULL, NULL); + in->sdi = g_malloc0(sizeof(struct sr_dev_inst)); in->priv = inc; for (i = 0; i < num_channels; i++) { @@ -458,7 +457,7 @@ static gboolean have_header(GString *buf) return FALSE; } -static int receive(const struct sr_input *in, GString *buf) +static int process_buffer(struct sr_input *in) { struct sr_datafeed_packet packet; struct sr_datafeed_meta meta; @@ -467,23 +466,8 @@ static int receive(const struct sr_input *in, GString *buf) uint64_t samplerate; char *p; - if (buf->len == 0) { - /* End of stream. */ - packet.type = SR_DF_END; - sr_session_send(in->sdi, &packet); - return SR_OK; - } - - g_string_append_len(in->buf, buf->str, buf->len); - inc = in->priv; - if (!inc->got_header) { - if (!have_header(in->buf)) - return SR_OK; - if (!parse_header(in, in->buf) != SR_OK) - /* There was a header in there, but it was malformed. */ - return SR_ERR; - + if (!inc->started) { std_session_send_df_header(in->sdi, LOG_PREFIX); packet.type = SR_DF_META; @@ -493,6 +477,8 @@ static int receive(const struct sr_input *in, GString *buf) meta.config = g_slist_append(NULL, src); sr_session_send(in->sdi, &packet); sr_config_free(src); + + inc->started = TRUE; } while ((p = g_strrstr_len(in->buf->str, in->buf->len, "\n"))) { @@ -506,24 +492,65 @@ static int receive(const struct sr_input *in, GString *buf) return SR_OK; } -static int cleanup(struct sr_input *in) +static int receive(struct sr_input *in, GString *buf) { struct context *inc; + int ret; + + g_string_append_len(in->buf, buf->str, buf->len); inc = in->priv; - g_slist_free_full(inc->channels, free_channel); - g_free(inc); - in->priv = NULL; + if (!inc->got_header) { + if (!have_header(in->buf)) + return SR_OK; + if (!parse_header(in, in->buf) != SR_OK) + /* There was a header in there, but it was malformed. */ + return SR_ERR; - return SR_OK; + in->sdi_ready = TRUE; + /* sdi is ready, notify frontend. */ + return SR_OK; + } + + ret = process_buffer(in); + + return ret; +} + +static int end(struct sr_input *in) +{ + struct sr_datafeed_packet packet; + struct context *inc; + int ret; + + if (in->sdi_ready) + ret = process_buffer(in); + else + ret = SR_OK; + + inc = in->priv; + if (inc->started) { + packet.type = SR_DF_END; + sr_session_send(in->sdi, &packet); + } + + return ret; +} + +static void cleanup(struct sr_input *in) +{ + struct context *inc; + + inc = in->priv; + g_slist_free_full(inc->channels, free_channel); } static struct sr_option options[] = { - { "numchannels", "Max channels", "Maximum number of channels", NULL, NULL }, + { "numchannels", "Number of channels", "Number of channels", NULL, NULL }, { "skip", "Skip", "Skip until timestamp", NULL, NULL }, { "downsample", "Downsample", "Divide samplerate by factor", NULL, NULL }, { "compress", "Compress", "Compress idle periods longer than this value", NULL, NULL }, - { 0 } + ALL_ZERO }; static struct sr_option *get_options(void) @@ -542,10 +569,12 @@ SR_PRIV struct sr_input_module input_vcd = { .id = "vcd", .name = "VCD", .desc = "Value Change Dump", + .exts = (const char*[]){"vcd", NULL}, .metadata = { SR_INPUT_META_HEADER | SR_INPUT_META_REQUIRED }, .options = get_options, .format_match = format_match, .init = init, .receive = receive, + .end = end, .cleanup = cleanup, };