size_t analog_ch_count;
gint *analog_index_map;
struct logic_buff {
- size_t unit_size;
+ size_t zip_unit_size;
size_t alloc_size;
uint8_t *samples;
size_t fill_size;
return SR_ERR_ARG;
}
- outc = g_malloc0(sizeof(struct out_context));
+ outc = g_malloc0(sizeof(*outc));
outc->filename = g_strdup(o->filename);
o->priv = outc;
g_key_file_set_integer(meta, devgroup, "total analog", enabled_analog_channels);
outc->analog_ch_count = enabled_analog_channels;
- alloc_size = sizeof(gint) * outc->analog_ch_count;
+ alloc_size = sizeof(gint) * outc->analog_ch_count + 1;
outc->analog_index_map = g_malloc0(alloc_size);
index = 0;
* archive update calls, and decouple the srzip output module
* from implementation details in other acquisition device
* drivers and input modules.
+ *
+ * Avoid allocating zero bytes, to not depend on platform
+ * specific malloc(0) return behaviour. Avoid division by zero,
+ * holding a local buffer won't harm when no data is seen later
+ * during execution. This simplifies other locations.
*/
alloc_size = CHUNK_SIZE;
- outc->logic_buff.unit_size = logic_channels;
- outc->logic_buff.unit_size += 8 - 1;
- outc->logic_buff.unit_size /= 8;
+ outc->logic_buff.zip_unit_size = logic_channels;
+ outc->logic_buff.zip_unit_size += 8 - 1;
+ outc->logic_buff.zip_unit_size /= 8;
outc->logic_buff.samples = g_try_malloc0(alloc_size);
if (!outc->logic_buff.samples)
return SR_ERR_MALLOC;
- alloc_size /= outc->logic_buff.unit_size;
+ if (outc->logic_buff.zip_unit_size)
+ alloc_size /= outc->logic_buff.zip_unit_size;
outc->logic_buff.alloc_size = alloc_size;
outc->logic_buff.fill_size = 0;
- alloc_size = sizeof(outc->analog_buff[0]) * outc->analog_ch_count;
+ alloc_size = sizeof(outc->analog_buff[0]) * outc->analog_ch_count + 1;
outc->analog_buff = g_malloc0(alloc_size);
for (index = 0; index < outc->analog_ch_count; index++) {
alloc_size = CHUNK_SIZE;
* @returns SR_OK et al error codes.
*/
static int zip_append_queue(const struct sr_output *o,
- uint8_t *buf, size_t unitsize, size_t length, gboolean flush)
+ const uint8_t *buf, size_t unitsize, size_t length,
+ gboolean flush)
{
struct out_context *outc;
struct logic_buff *buff;
size_t send_size, remain, copy_size;
- uint8_t *wrptr, *rdptr;
+ const uint8_t *rdptr;
+ uint8_t *wrptr;
int ret;
outc = o->priv;
buff = &outc->logic_buff;
- if (length && unitsize != buff->unit_size)
+ if (length && unitsize != buff->zip_unit_size) {
+ sr_warn("Unexpected unit size, discarding logic data.");
return SR_ERR_ARG;
+ }
/*
* Queue most recently received samples to the local buffer.
* Flush to the ZIP archive when the buffer space is exhausted.
*/
rdptr = buf;
- send_size = length / buff->unit_size;
+ send_size = buff->zip_unit_size ? length / buff->zip_unit_size : 0;
while (send_size) {
remain = buff->alloc_size - buff->fill_size;
if (remain) {
- wrptr = &buff->samples[buff->fill_size * buff->unit_size];
+ wrptr = &buff->samples[buff->fill_size * buff->zip_unit_size];
copy_size = MIN(send_size, remain);
send_size -= copy_size;
buff->fill_size += copy_size;
- memcpy(wrptr, rdptr, copy_size * buff->unit_size);
- rdptr += copy_size * buff->unit_size;
+ memcpy(wrptr, rdptr, copy_size * buff->zip_unit_size);
+ rdptr += copy_size * buff->zip_unit_size;
remain -= copy_size;
}
if (send_size && !remain) {
- ret = zip_append(o, buff->samples, buff->unit_size,
- buff->fill_size * buff->unit_size);
+ ret = zip_append(o, buff->samples, buff->zip_unit_size,
+ buff->fill_size * buff->zip_unit_size);
if (ret != SR_OK)
return ret;
buff->fill_size = 0;
/* Flush to the ZIP archive if the caller wants us to. */
if (flush && buff->fill_size) {
- ret = zip_append(o, buff->samples, buff->unit_size,
- buff->fill_size * buff->unit_size);
+ ret = zip_append(o, buff->samples, buff->zip_unit_size,
+ buff->fill_size * buff->zip_unit_size);
if (ret != SR_OK)
return ret;
buff->fill_size = 0;
outc->zip_created = TRUE;
}
logic = packet->payload;
- ret = zip_append_queue(o, logic->data,
- logic->unitsize, logic->length, FALSE);
+ ret = zip_append_queue(o,
+ logic->data, logic->unitsize, logic->length,
+ FALSE);
if (ret != SR_OK)
return ret;
break;