From: Gerhard Sittig Date: Sun, 28 Oct 2018 09:45:42 +0000 (+0100) Subject: input/wav: add channel list checks for file re-read X-Git-Url: http://sigrok.org/gitweb/?a=commitdiff_plain;h=2581d204e0a367a74d0903fdb3fbe32ffab42a25;hp=d829239749d1cf2934a067080e78eeb4ef1913f5;p=libsigrok.git input/wav: add channel list checks for file re-read Do for the WAV input module what commit 08f8421a9e82 did for VCD. Check the channel list for consistency across re-imports of the same file. This addresses the WAV part of bug #1241. This commit also changes the WAV module's reset() method's behaviour. The previous implementation only created channels once, and re-used that channel list when the file got re-read. Which could cause issues when the file's properties changed between re-runs. This implementation always creates the channel list upon every file import, and ensures a consistent channel list across re-imports. This follows the approach that was taken in all other input modules before. --- diff --git a/src/input/wav.c b/src/input/wav.c index a6369f4d..4e9d6c12 100644 --- a/src/input/wav.c +++ b/src/input/wav.c @@ -52,6 +52,7 @@ struct context { int unitsize; gboolean found_data; gboolean create_channels; + GSList *prev_sr_channels; }; static int parse_wav_header(GString *buf, struct context *inc) @@ -306,6 +307,44 @@ static int process_buffer(struct sr_input *in) return SR_OK; } +/* + * Check the channel list for consistency across file re-import. See + * the VCD input module for more details and motivation. + */ + +static void keep_header_for_reread(const struct sr_input *in) +{ + struct context *inc; + + inc = in->priv; + g_slist_free_full(inc->prev_sr_channels, sr_channel_free_cb); + inc->prev_sr_channels = in->sdi->channels; + in->sdi->channels = NULL; +} + +static int check_header_in_reread(const struct sr_input *in) +{ + struct context *inc; + + if (!in) + return FALSE; + inc = in->priv; + if (!inc) + return FALSE; + if (!inc->prev_sr_channels) + return TRUE; + + if (sr_channel_lists_differ(inc->prev_sr_channels, in->sdi->channels)) { + sr_err("Channel list change not supported for file re-read."); + return FALSE; + } + g_slist_free_full(in->sdi->channels, sr_channel_free_cb); + in->sdi->channels = inc->prev_sr_channels; + inc->prev_sr_channels = NULL; + + return TRUE; +} + static int receive(struct sr_input *in, GString *buf) { struct context *inc; @@ -335,8 +374,9 @@ static int receive(struct sr_input *in, GString *buf) snprintf(channelname, sizeof(channelname), "CH%d", i + 1); sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname); } + if (!check_header_in_reread(in)) + return SR_ERR_DATA; } - inc->create_channels = FALSE; /* sdi is ready, notify frontend. */ @@ -368,12 +408,19 @@ static int end(struct sr_input *in) static int reset(struct sr_input *in) { - memset(in->priv, 0, sizeof(struct context)); + struct context *inc; + + inc = in->priv; + memset(inc, 0, sizeof(*inc)); /* - * We only want to create the sigrok channels once, so - * inc->create_channels won't be set to TRUE this time around. + * Create, and re-create channels for every iteration of file + * import. Other logic will enforce a consistent set of channels + * across re-import, or an appropriate error message when file + * properties should change. */ + keep_header_for_reread(in); + inc->create_channels = TRUE; g_string_truncate(in->buf, 0);