X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=instance.c;h=0a930bf184ca7a7c7ff6cfc499d2d74762ce81c6;hb=8830db5df55241e1ea775a70671ecb11235cf3c1;hp=92959635b5e34ad95771714c921bdded3e8d0b3a;hpb=a3a2a26d2a93d1fe7a3bb2e8eb732509c8c905e6;p=libsigrokdecode.git diff --git a/instance.c b/instance.c index 9295963..0a930bf 100644 --- a/instance.c +++ b/instance.c @@ -224,19 +224,22 @@ static gint compare_probe_id(const struct srd_probe *a, const char *probe_id) * @param new_probes A GHashTable of probes to set. Key is probe name, value is * the probe number. Samples passed to this instance will be * arranged in this order. + * @param unit_size Number of bytes per sample in the data stream to be passed + * to the decoder. The highest probe index specified in the + * probe map must lie within a sample unit. * * @return SRD_OK upon success, a (negative) error code otherwise. * * @since 0.1.0 */ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di, - GHashTable *new_probes) + GHashTable *new_probes, int unit_size) { GVariant *probe_val; GList *l; GSList *sl; struct srd_probe *p; - int *new_probemap, new_probenum, num_required_probes, num_probes, i; + int *new_probemap, new_probenum, num_required_probes, i; char *probe_id; srd_dbg("set probes called for instance %s with list of %d probes", @@ -267,7 +270,6 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di, for (i = 0; i < di->dec_num_probes; i++) new_probemap[i] = -1; - num_probes = 0; for (l = g_hash_table_get_keys(new_probes); l; l = l->next) { probe_id = l->data; probe_val = g_hash_table_lookup(new_probes, probe_id); @@ -279,6 +281,12 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di, return SRD_ERR_ARG; } new_probenum = g_variant_get_int32(probe_val); + if (new_probenum >= 8 * unit_size) { + srd_err("Probe index %d not within data unit (%d bit).", + new_probenum, 8 * unit_size); + g_free(new_probemap); + return SRD_ERR_ARG; + } if (!(sl = g_slist_find_custom(di->decoder->probes, probe_id, (GCompareFunc)compare_probe_id))) { /* Fall back on optional probes. */ @@ -294,9 +302,8 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di, new_probemap[p->order] = new_probenum; srd_dbg("Setting probe mapping: %s (index %d) = probe %d.", p->id, p->order, new_probenum); - num_probes++; } - di->data_unitsize = (num_probes + 7) / 8; + di->data_unitsize = unit_size; srd_dbg("Final probe map:"); num_required_probes = g_slist_length(di->decoder->probes); @@ -305,6 +312,16 @@ SRD_API int srd_inst_probe_set_all(struct srd_decoder_inst *di, (i < num_required_probes) ? "required" : "optional"); } + /* Report an error if not all required probes were specified. */ + for (i = 0; i < num_required_probes; i++) { + if (new_probemap[i] != -1) + continue; + p = g_slist_nth(di->decoder->probes, i)->data; + srd_err("Required probe '%s' (index %d) was not specified.", + p->id, i); + return SRD_ERR; + } + g_free(di->dec_probemap); di->dec_probemap = new_probemap; @@ -373,8 +390,18 @@ SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess, } for (i = 0; i < di->dec_num_probes; i++) di->dec_probemap[i] = i; + di->data_unitsize = (di->dec_num_probes + 7) / 8; + /* + * Will be used to prepare a sample at every iteration + * of the instance's decode() method. + */ + if (!(di->probe_samples = g_try_malloc(di->dec_num_probes))) { + srd_err("Failed to g_malloc() sample buffer."); + g_free(di->dec_probemap); + g_free(di); + return NULL; + } } - di->data_unitsize = (di->dec_num_probes + 7) / 8; /* Create a new instance of this decoder class. */ if (!(di->py_inst = PyObject_CallObject(dec->py_dec, NULL))) { @@ -402,15 +429,16 @@ SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess, * Stack a decoder instance on top of another. * * @param sess The session holding the protocol decoder instances. - * @param di_from The instance to move. - * @param di_to The instance on top of which di_from will be stacked. + * @param di_bottom The instance on top of which di_top will be stacked. + * @param di_top The instance to go on top. * * @return SRD_OK upon success, a (negative) error code otherwise. * * @since 0.3.0 */ SRD_API int srd_inst_stack(struct srd_session *sess, - struct srd_decoder_inst *di_from, struct srd_decoder_inst *di_to) + struct srd_decoder_inst *di_bottom, + struct srd_decoder_inst *di_top) { if (session_is_valid(sess) != SRD_OK) { @@ -418,18 +446,20 @@ SRD_API int srd_inst_stack(struct srd_session *sess, return SRD_ERR_ARG; } - if (!di_from || !di_to) { + if (!di_bottom || !di_top) { srd_err("Invalid from/to instance pair."); return SRD_ERR_ARG; } - if (g_slist_find(sess->di_list, di_to)) { + if (g_slist_find(sess->di_list, di_top)) { /* Remove from the unstacked list. */ - sess->di_list = g_slist_remove(sess->di_list, di_to); + sess->di_list = g_slist_remove(sess->di_list, di_top); } /* Stack on top of source di. */ - di_from->next_di = g_slist_append(di_from->next_di, di_to); + di_bottom->next_di = g_slist_append(di_bottom->next_di, di_top); + + srd_dbg("Stacked %s on top of %s.", di_top->inst_id, di_bottom->inst_id); return SRD_OK; }