]> sigrok.org Git - libsigrokdecode.git/blob - type_decoder.c
lpc: improve performance, use proper .wait() condition
[libsigrokdecode.git] / type_decoder.c
1 /*
2  * This file is part of the libsigrokdecode project.
3  *
4  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22 #include "libsigrokdecode.h"
23 #include <inttypes.h>
24
25 /** @cond PRIVATE */
26 extern SRD_PRIV GSList *sessions;
27 /** @endcond */
28
29 typedef struct {
30         PyObject_HEAD
31 } srd_Decoder;
32
33 /* This is only used for nicer srd_dbg() output. */
34 SRD_PRIV const char *output_type_name(unsigned int idx)
35 {
36         static const char names[][16] = {
37                 "OUTPUT_ANN",
38                 "OUTPUT_PYTHON",
39                 "OUTPUT_BINARY",
40                 "OUTPUT_META",
41                 "(invalid)"
42         };
43
44         return names[MIN(idx, G_N_ELEMENTS(names) - 1)];
45 }
46
47 static void release_annotation(struct srd_proto_data_annotation *pda)
48 {
49         if (!pda)
50                 return;
51         if (pda->ann_text)
52                 g_strfreev(pda->ann_text);
53 }
54
55 static int convert_annotation(struct srd_decoder_inst *di, PyObject *obj,
56                 struct srd_proto_data *pdata)
57 {
58         PyObject *py_tmp;
59         struct srd_pd_output *pdo;
60         struct srd_proto_data_annotation *pda;
61         int ann_class;
62         char **ann_text;
63         PyGILState_STATE gstate;
64
65         gstate = PyGILState_Ensure();
66
67         /* Should be a list of [annotation class, [string, ...]]. */
68         if (!PyList_Check(obj)) {
69                 srd_err("Protocol decoder %s submitted an annotation that"
70                         " is not a list", di->decoder->name);
71                 goto err;
72         }
73
74         /* Should have 2 elements. */
75         if (PyList_Size(obj) != 2) {
76                 srd_err("Protocol decoder %s submitted annotation list with "
77                         "%zd elements instead of 2", di->decoder->name,
78                         PyList_Size(obj));
79                 goto err;
80         }
81
82         /*
83          * The first element should be an integer matching a previously
84          * registered annotation class.
85          */
86         py_tmp = PyList_GetItem(obj, 0);
87         if (!PyLong_Check(py_tmp)) {
88                 srd_err("Protocol decoder %s submitted annotation list, but "
89                         "first element was not an integer.", di->decoder->name);
90                 goto err;
91         }
92         ann_class = PyLong_AsLong(py_tmp);
93         if (!(pdo = g_slist_nth_data(di->decoder->annotations, ann_class))) {
94                 srd_err("Protocol decoder %s submitted data to unregistered "
95                         "annotation class %d.", di->decoder->name, ann_class);
96                 goto err;
97         }
98
99         /* Second element must be a list. */
100         py_tmp = PyList_GetItem(obj, 1);
101         if (!PyList_Check(py_tmp)) {
102                 srd_err("Protocol decoder %s submitted annotation list, but "
103                         "second element was not a list.", di->decoder->name);
104                 goto err;
105         }
106         if (py_strseq_to_char(py_tmp, &ann_text) != SRD_OK) {
107                 srd_err("Protocol decoder %s submitted annotation list, but "
108                         "second element was malformed.", di->decoder->name);
109                 goto err;
110         }
111
112         pda = pdata->data;
113         pda->ann_class = ann_class;
114         pda->ann_text = ann_text;
115
116         PyGILState_Release(gstate);
117
118         return SRD_OK;
119
120 err:
121         PyGILState_Release(gstate);
122
123         return SRD_ERR_PYTHON;
124 }
125
126 static void release_binary(struct srd_proto_data_binary *pdb)
127 {
128         if (!pdb)
129                 return;
130         g_free((void *)pdb->data);
131 }
132
133 static int convert_binary(struct srd_decoder_inst *di, PyObject *obj,
134                 struct srd_proto_data *pdata)
135 {
136         struct srd_proto_data_binary *pdb;
137         PyObject *py_tmp;
138         Py_ssize_t size;
139         int bin_class;
140         char *class_name, *buf;
141         PyGILState_STATE gstate;
142
143         gstate = PyGILState_Ensure();
144
145         /* Should be a list of [binary class, bytes]. */
146         if (!PyList_Check(obj)) {
147                 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_BINARY.",
148                         di->decoder->name);
149                 goto err;
150         }
151
152         /* Should have 2 elements. */
153         if (PyList_Size(obj) != 2) {
154                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list "
155                                 "with %zd elements instead of 2", di->decoder->name,
156                                 PyList_Size(obj));
157                 goto err;
158         }
159
160         /* The first element should be an integer. */
161         py_tmp = PyList_GetItem(obj, 0);
162         if (!PyLong_Check(py_tmp)) {
163                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
164                         "but first element was not an integer.", di->decoder->name);
165                 goto err;
166         }
167         bin_class = PyLong_AsLong(py_tmp);
168         if (!(class_name = g_slist_nth_data(di->decoder->binary, bin_class))) {
169                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY with "
170                         "unregistered binary class %d.", di->decoder->name, bin_class);
171                 goto err;
172         }
173
174         /* Second element should be bytes. */
175         py_tmp = PyList_GetItem(obj, 1);
176         if (!PyBytes_Check(py_tmp)) {
177                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, "
178                         "but second element was not bytes.", di->decoder->name);
179                 goto err;
180         }
181
182         /* Consider an empty set of bytes a bug. */
183         if (PyBytes_Size(py_tmp) == 0) {
184                 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY "
185                                 "with empty data set.", di->decoder->name);
186                 goto err;
187         }
188
189         if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
190                 goto err;
191
192         PyGILState_Release(gstate);
193
194         pdb = pdata->data;
195         pdb->bin_class = bin_class;
196         pdb->size = size;
197         if (!(pdb->data = g_try_malloc(pdb->size)))
198                 return SRD_ERR_MALLOC;
199         memcpy((void *)pdb->data, (const void *)buf, pdb->size);
200
201         return SRD_OK;
202
203 err:
204         PyGILState_Release(gstate);
205
206         return SRD_ERR_PYTHON;
207 }
208
209 static inline struct srd_decoder_inst *srd_sess_inst_find_by_obj(
210         struct srd_session *sess, const GSList *stack, const PyObject *obj)
211 {
212         const GSList *l;
213         struct srd_decoder_inst *tmp, *di;
214
215         if (!sess)
216                 return NULL;
217
218         di = NULL;
219         for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
220                 tmp = l->data;
221                 if (tmp->py_inst == obj)
222                         di = tmp;
223                 else if (tmp->next_di)
224                         di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
225         }
226
227         return di;
228 }
229
230 /**
231  * Find a decoder instance by its Python object.
232  *
233  * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
234  * This will recurse to find the instance anywhere in the stack tree of all
235  * sessions.
236  *
237  * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
238  *              stack to search. To start searching at the bottom level of
239  *              decoder instances, pass NULL.
240  * @param obj The Python class instantiation.
241  *
242  * @return Pointer to struct srd_decoder_inst, or NULL if not found.
243  *
244  * @since 0.1.0
245  */
246 static inline struct srd_decoder_inst *srd_inst_find_by_obj(
247                 const GSList *stack, const PyObject *obj)
248 {
249         struct srd_decoder_inst *di;
250         struct srd_session *sess;
251         GSList *l;
252
253         /* Performance shortcut: Handle the most common case first. */
254         sess = sessions->data;
255         di = sess->di_list->data;
256         if (di->py_inst == obj)
257                 return di;
258
259         di = NULL;
260         for (l = sessions; di == NULL && l != NULL; l = l->next) {
261                 sess = l->data;
262                 di = srd_sess_inst_find_by_obj(sess, stack, obj);
263         }
264
265         return di;
266 }
267
268 static int convert_meta(struct srd_proto_data *pdata, PyObject *obj)
269 {
270         long long intvalue;
271         double dvalue;
272         PyGILState_STATE gstate;
273
274         gstate = PyGILState_Ensure();
275
276         if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_INT64)) {
277                 if (!PyLong_Check(obj)) {
278                         PyErr_Format(PyExc_TypeError, "This output was registered "
279                                         "as 'int', but something else was passed.");
280                         goto err;
281                 }
282                 intvalue = PyLong_AsLongLong(obj);
283                 if (PyErr_Occurred())
284                         goto err;
285                 pdata->data = g_variant_new_int64(intvalue);
286         } else if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_DOUBLE)) {
287                 if (!PyFloat_Check(obj)) {
288                         PyErr_Format(PyExc_TypeError, "This output was registered "
289                                         "as 'float', but something else was passed.");
290                         goto err;
291                 }
292                 dvalue = PyFloat_AsDouble(obj);
293                 if (PyErr_Occurred())
294                         goto err;
295                 pdata->data = g_variant_new_double(dvalue);
296         }
297
298         PyGILState_Release(gstate);
299
300         return SRD_OK;
301
302 err:
303         PyGILState_Release(gstate);
304
305         return SRD_ERR_PYTHON;
306 }
307
308 static void release_meta(GVariant *gvar)
309 {
310         if (!gvar)
311                 return;
312         g_variant_unref(gvar);
313 }
314
315 static PyObject *Decoder_put(PyObject *self, PyObject *args)
316 {
317         GSList *l;
318         PyObject *py_data, *py_res;
319         struct srd_decoder_inst *di, *next_di;
320         struct srd_pd_output *pdo;
321         struct srd_proto_data pdata;
322         struct srd_proto_data_annotation pda;
323         struct srd_proto_data_binary pdb;
324         uint64_t start_sample, end_sample;
325         int output_id;
326         struct srd_pd_callback *cb;
327         PyGILState_STATE gstate;
328
329         py_data = NULL;
330
331         gstate = PyGILState_Ensure();
332
333         if (!(di = srd_inst_find_by_obj(NULL, self))) {
334                 /* Shouldn't happen. */
335                 srd_dbg("put(): self instance not found.");
336                 goto err;
337         }
338
339         if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
340                 &output_id, &py_data)) {
341                 /*
342                  * This throws an exception, but by returning NULL here we let
343                  * Python raise it. This results in a much better trace in
344                  * controller.c on the decode() method call.
345                  */
346                 goto err;
347         }
348
349         if (!(l = g_slist_nth(di->pd_output, output_id))) {
350                 srd_err("Protocol decoder %s submitted invalid output ID %d.",
351                         di->decoder->name, output_id);
352                 goto err;
353         }
354         pdo = l->data;
355
356         /* Upon SRD_OUTPUT_PYTHON for stacked PDs, we have a nicer log message later. */
357         if (pdo->output_type != SRD_OUTPUT_PYTHON && di->next_di != NULL) {
358                 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on "
359                          "oid %d (%s).", di->inst_id, start_sample, end_sample,
360                          output_type_name(pdo->output_type), output_id,
361                          pdo->proto_id);
362         }
363
364         pdata.start_sample = start_sample;
365         pdata.end_sample = end_sample;
366         pdata.pdo = pdo;
367         pdata.data = NULL;
368
369         switch (pdo->output_type) {
370         case SRD_OUTPUT_ANN:
371                 /* Annotations are only fed to callbacks. */
372                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
373                         pdata.data = &pda;
374                         /* Convert from PyDict to srd_proto_data_annotation. */
375                         if (convert_annotation(di, py_data, &pdata) != SRD_OK) {
376                                 /* An error was already logged. */
377                                 break;
378                         }
379                         Py_BEGIN_ALLOW_THREADS
380                         cb->cb(&pdata, cb->cb_data);
381                         Py_END_ALLOW_THREADS
382                         release_annotation(pdata.data);
383                 }
384                 break;
385         case SRD_OUTPUT_PYTHON:
386                 for (l = di->next_di; l; l = l->next) {
387                         next_di = l->data;
388                         srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s "
389                                  "on oid %d (%s) to instance %s.", di->inst_id,
390                                  start_sample,
391                                  end_sample, output_type_name(pdo->output_type),
392                                  output_id, pdo->proto_id, next_di->inst_id);
393                         if (!(py_res = PyObject_CallMethod(
394                                 next_di->py_inst, "decode", "KKO", start_sample,
395                                 end_sample, py_data))) {
396                                 srd_exception_catch("Calling %s decode() failed",
397                                                         next_di->inst_id);
398                         }
399                         Py_XDECREF(py_res);
400                 }
401                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
402                         /*
403                          * Frontends aren't really supposed to get Python
404                          * callbacks, but it's useful for testing.
405                          */
406                         pdata.data = py_data;
407                         cb->cb(&pdata, cb->cb_data);
408                 }
409                 break;
410         case SRD_OUTPUT_BINARY:
411                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
412                         pdata.data = &pdb;
413                         /* Convert from PyDict to srd_proto_data_binary. */
414                         if (convert_binary(di, py_data, &pdata) != SRD_OK) {
415                                 /* An error was already logged. */
416                                 break;
417                         }
418                         Py_BEGIN_ALLOW_THREADS
419                         cb->cb(&pdata, cb->cb_data);
420                         Py_END_ALLOW_THREADS
421                         release_binary(pdata.data);
422                 }
423                 break;
424         case SRD_OUTPUT_META:
425                 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
426                         /* Annotations need converting from PyObject. */
427                         if (convert_meta(&pdata, py_data) != SRD_OK) {
428                                 /* An exception was already set up. */
429                                 break;
430                         }
431                         Py_BEGIN_ALLOW_THREADS
432                         cb->cb(&pdata, cb->cb_data);
433                         Py_END_ALLOW_THREADS
434                         release_meta(pdata.data);
435                 }
436                 break;
437         default:
438                 srd_err("Protocol decoder %s submitted invalid output type %d.",
439                         di->decoder->name, pdo->output_type);
440                 break;
441         }
442
443         PyGILState_Release(gstate);
444
445         Py_RETURN_NONE;
446
447 err:
448         PyGILState_Release(gstate);
449
450         return NULL;
451 }
452
453 static PyObject *Decoder_register(PyObject *self, PyObject *args,
454                 PyObject *kwargs)
455 {
456         struct srd_decoder_inst *di;
457         struct srd_pd_output *pdo;
458         PyObject *py_new_output_id;
459         PyTypeObject *meta_type_py;
460         const GVariantType *meta_type_gv;
461         int output_type;
462         char *proto_id, *meta_name, *meta_descr;
463         char *keywords[] = { "output_type", "proto_id", "meta", NULL };
464         PyGILState_STATE gstate;
465         gboolean is_meta;
466         GSList *l;
467         struct srd_pd_output *cmp;
468
469         gstate = PyGILState_Ensure();
470
471         meta_type_py = NULL;
472         meta_type_gv = NULL;
473         meta_name = meta_descr = NULL;
474
475         if (!(di = srd_inst_find_by_obj(NULL, self))) {
476                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
477                 goto err;
478         }
479
480         /* Default to instance ID, which defaults to class ID. */
481         proto_id = di->inst_id;
482         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s(Oss)", keywords,
483                         &output_type, &proto_id,
484                         &meta_type_py, &meta_name, &meta_descr)) {
485                 /* Let Python raise this exception. */
486                 goto err;
487         }
488
489         /* Check if the meta value's type is supported. */
490         is_meta = output_type == SRD_OUTPUT_META;
491         if (is_meta) {
492                 if (meta_type_py == &PyLong_Type)
493                         meta_type_gv = G_VARIANT_TYPE_INT64;
494                 else if (meta_type_py == &PyFloat_Type)
495                         meta_type_gv = G_VARIANT_TYPE_DOUBLE;
496                 else {
497                         PyErr_Format(PyExc_TypeError, "Unsupported type.");
498                         goto err;
499                 }
500         }
501
502         pdo = NULL;
503         for (l = di->pd_output; l; l = l->next) {
504                 cmp = l->data;
505                 if (cmp->output_type != output_type)
506                         continue;
507                 if (strcmp(cmp->proto_id, proto_id) != 0)
508                         continue;
509                 if (is_meta && cmp->meta_type != meta_type_gv)
510                         continue;
511                 if (is_meta && strcmp(cmp->meta_name, meta_name) != 0)
512                         continue;
513                 if (is_meta && strcmp(cmp->meta_descr, meta_descr) != 0)
514                         continue;
515                 pdo = cmp;
516                 break;
517         }
518         if (pdo) {
519                 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
520                 PyGILState_Release(gstate);
521                 return py_new_output_id;
522         }
523
524         pdo = g_malloc(sizeof(struct srd_pd_output));
525
526         /* pdo_id is just a simple index, nothing is deleted from this list anyway. */
527         pdo->pdo_id = g_slist_length(di->pd_output);
528         pdo->output_type = output_type;
529         pdo->di = di;
530         pdo->proto_id = g_strdup(proto_id);
531
532         if (output_type == SRD_OUTPUT_META) {
533                 pdo->meta_type = meta_type_gv;
534                 pdo->meta_name = g_strdup(meta_name);
535                 pdo->meta_descr = g_strdup(meta_descr);
536         }
537
538         di->pd_output = g_slist_append(di->pd_output, pdo);
539         py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
540
541         PyGILState_Release(gstate);
542
543         srd_dbg("Instance %s creating new output type %s as oid %d (%s).",
544                 di->inst_id, output_type_name(output_type), pdo->pdo_id,
545                 proto_id);
546
547         return py_new_output_id;
548
549 err:
550         PyGILState_Release(gstate);
551
552         return NULL;
553 }
554
555 static int get_term_type(const char *v)
556 {
557         switch (v[0]) {
558         case 'h':
559                 return SRD_TERM_HIGH;
560         case 'l':
561                 return SRD_TERM_LOW;
562         case 'r':
563                 return SRD_TERM_RISING_EDGE;
564         case 'f':
565                 return SRD_TERM_FALLING_EDGE;
566         case 'e':
567                 return SRD_TERM_EITHER_EDGE;
568         case 'n':
569                 return SRD_TERM_NO_EDGE;
570         default:
571                 return -1;
572         }
573
574         return -1;
575 }
576
577 /**
578  * Get the pin values at the current sample number.
579  *
580  * @param di The decoder instance to use. Must not be NULL.
581  *           The number of channels must be >= 1.
582  *
583  * @return A newly allocated PyTuple containing the pin values at the
584  *         current sample number.
585  */
586 static PyObject *get_current_pinvalues(const struct srd_decoder_inst *di)
587 {
588         int i;
589         uint8_t sample;
590         const uint8_t *sample_pos;
591         int byte_offset, bit_offset;
592         PyObject *py_pinvalues;
593         PyGILState_STATE gstate;
594
595         if (!di) {
596                 srd_err("Invalid decoder instance.");
597                 return NULL;
598         }
599
600         gstate = PyGILState_Ensure();
601
602         py_pinvalues = PyTuple_New(di->dec_num_channels);
603
604         for (i = 0; i < di->dec_num_channels; i++) {
605                 /* A channelmap value of -1 means "unused optional channel". */
606                 if (di->dec_channelmap[i] == -1) {
607                         /* Value of unused channel is 0xff, instead of 0 or 1. */
608                         PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(0xff));
609                 } else {
610                         sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
611                         byte_offset = di->dec_channelmap[i] / 8;
612                         bit_offset = di->dec_channelmap[i] % 8;
613                         sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
614                         PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(sample));
615                 }
616         }
617
618         PyGILState_Release(gstate);
619
620         return py_pinvalues;
621 }
622
623 /**
624  * Create a list of terms in the specified condition.
625  *
626  * If there are no terms in the condition, 'term_list' will be NULL.
627  *
628  * @param di The decoder instance to use. Must not be NULL.
629  * @param py_dict A Python dict containing terms. Must not be NULL.
630  * @param term_list Pointer to a GSList which will be set to the newly
631  *                  created list of terms. Must not be NULL.
632  *
633  * @return SRD_OK upon success, a negative error code otherwise.
634  */
635 static int create_term_list(struct srd_decoder_inst *di,
636         PyObject *py_dict, GSList **term_list)
637 {
638         Py_ssize_t pos = 0;
639         PyObject *py_key, *py_value;
640         struct srd_term *term;
641         int64_t num_samples_to_skip;
642         char *term_str;
643         PyGILState_STATE gstate;
644
645         if (!py_dict || !term_list)
646                 return SRD_ERR_ARG;
647
648         /* "Create" an empty GSList of terms. */
649         *term_list = NULL;
650
651         gstate = PyGILState_Ensure();
652
653         /* Iterate over all items in the current dict. */
654         while (PyDict_Next(py_dict, &pos, &py_key, &py_value)) {
655                 /* Check whether the current key is a string or a number. */
656                 if (PyLong_Check(py_key)) {
657                         /* The key is a number. */
658                         /* Get the value string. */
659                         if ((py_pydictitem_as_str(py_dict, py_key, &term_str)) != SRD_OK) {
660                                 srd_err("Failed to get the value.");
661                                 goto err;
662                         }
663                         term = g_malloc(sizeof(struct srd_term));
664                         term->type = get_term_type(term_str);
665                         term->channel = PyLong_AsLong(py_key);
666                         if (term->channel < 0 || term->channel >= di->dec_num_channels)
667                                 term->type = SRD_TERM_ALWAYS_FALSE;
668                         g_free(term_str);
669                 } else if (PyUnicode_Check(py_key)) {
670                         /* The key is a string. */
671                         /* TODO: Check if the key is "skip". */
672                         if ((py_pydictitem_as_long(py_dict, py_key, &num_samples_to_skip)) != SRD_OK) {
673                                 srd_err("Failed to get number of samples to skip.");
674                                 goto err;
675                         }
676                         term = g_malloc(sizeof(struct srd_term));
677                         term->type = SRD_TERM_SKIP;
678                         term->num_samples_to_skip = num_samples_to_skip;
679                         term->num_samples_already_skipped = 0;
680                         if (num_samples_to_skip < 0)
681                                 term->type = SRD_TERM_ALWAYS_FALSE;
682                 } else {
683                         srd_err("Term key is neither a string nor a number.");
684                         goto err;
685                 }
686
687                 /* Add the term to the list of terms. */
688                 *term_list = g_slist_append(*term_list, term);
689         }
690
691         PyGILState_Release(gstate);
692
693         return SRD_OK;
694
695 err:
696         PyGILState_Release(gstate);
697
698         return SRD_ERR;
699 }
700
701 /**
702  * Replace the current condition list with the new one.
703  *
704  * @param self TODO. Must not be NULL.
705  * @param args TODO. Must not be NULL.
706  *
707  * @retval SRD_OK The new condition list was set successfully.
708  * @retval SRD_ERR There was an error setting the new condition list.
709  *                 The contents of di->condition_list are undefined.
710  * @retval 9999 TODO.
711  */
712 static int set_new_condition_list(PyObject *self, PyObject *args)
713 {
714         struct srd_decoder_inst *di;
715         GSList *term_list;
716         PyObject *py_conditionlist, *py_conds, *py_dict;
717         int i, num_conditions, ret;
718         PyGILState_STATE gstate;
719
720         if (!self || !args)
721                 return SRD_ERR_ARG;
722
723         gstate = PyGILState_Ensure();
724
725         /* Get the decoder instance. */
726         if (!(di = srd_inst_find_by_obj(NULL, self))) {
727                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
728                 goto err;
729         }
730
731         /*
732          * Return an error condition from .wait() when termination is
733          * requested, such that decode() will terminate.
734          */
735         if (di->want_wait_terminate) {
736                 srd_dbg("%s: %s: Skip (want_term).", di->inst_id, __func__);
737                 goto err;
738         }
739
740         /*
741          * Parse the argument of self.wait() into 'py_conds', and check
742          * the data type. The argument is optional, None is assumed in
743          * its absence. None or an empty dict or an empty list mean that
744          * there is no condition, and the next available sample shall
745          * get returned to the caller.
746          */
747         py_conds = Py_None;
748         if (!PyArg_ParseTuple(args, "|O", &py_conds)) {
749                 /* Let Python raise this exception. */
750                 goto err;
751         }
752         if (py_conds == Py_None) {
753                 /* 'py_conds' is None. */
754                 goto ret_9999;
755         } else if (PyList_Check(py_conds)) {
756                 /* 'py_conds' is a list. */
757                 py_conditionlist = py_conds;
758                 num_conditions = PyList_Size(py_conditionlist);
759                 if (num_conditions == 0)
760                         goto ret_9999; /* The PD invoked self.wait([]). */
761                 Py_INCREF(py_conditionlist);
762         } else if (PyDict_Check(py_conds)) {
763                 /* 'py_conds' is a dict. */
764                 if (PyDict_Size(py_conds) == 0)
765                         goto ret_9999; /* The PD invoked self.wait({}). */
766                 /* Make a list and put the dict in there for convenience. */
767                 py_conditionlist = PyList_New(1);
768                 Py_INCREF(py_conds);
769                 PyList_SetItem(py_conditionlist, 0, py_conds);
770                 num_conditions = 1;
771         } else {
772                 srd_err("Condition list is neither a list nor a dict.");
773                 goto err;
774         }
775
776         /* Free the old condition list. */
777         condition_list_free(di);
778
779         ret = SRD_OK;
780
781         /* Iterate over the conditions, set di->condition_list accordingly. */
782         for (i = 0; i < num_conditions; i++) {
783                 /* Get a condition (dict) from the condition list. */
784                 py_dict = PyList_GetItem(py_conditionlist, i);
785                 if (!PyDict_Check(py_dict)) {
786                         srd_err("Condition is not a dict.");
787                         ret = SRD_ERR;
788                         break;
789                 }
790
791                 /* Create the list of terms in this condition. */
792                 if ((ret = create_term_list(di, py_dict, &term_list)) < 0)
793                         break;
794
795                 /* Add the new condition to the PD instance's condition list. */
796                 di->condition_list = g_slist_append(di->condition_list, term_list);
797         }
798
799         Py_DecRef(py_conditionlist);
800
801         PyGILState_Release(gstate);
802
803         return ret;
804
805 err:
806         PyGILState_Release(gstate);
807
808         return SRD_ERR;
809
810 ret_9999:
811         PyGILState_Release(gstate);
812
813         return 9999;
814 }
815
816 /**
817  * Create a SKIP condition list for condition-less .wait() calls.
818  *
819  * @param di Decoder instance.
820  * @param count Number of samples to skip.
821  *
822  * @retval SRD_OK The new condition list was set successfully.
823  * @retval SRD_ERR There was an error setting the new condition list.
824  *                 The contents of di->condition_list are undefined.
825  *
826  * This routine is a reduced and specialized version of the @ref
827  * set_new_condition_list() and @ref create_term_list() routines which
828  * gets invoked when .wait() was called without specifications for
829  * conditions. This minor duplication of the SKIP term list creation
830  * simplifies the logic and avoids the creation of expensive Python
831  * objects with "constant" values which the caller did not pass in the
832  * first place. It results in maximum sharing of match handling code
833  * paths.
834  */
835 static int set_skip_condition(struct srd_decoder_inst *di, uint64_t count)
836 {
837         struct srd_term *term;
838         GSList *term_list;
839
840         condition_list_free(di);
841         term = g_malloc(sizeof(*term));
842         term->type = SRD_TERM_SKIP;
843         term->num_samples_to_skip = count;
844         term->num_samples_already_skipped = 0;
845         term_list = g_slist_append(NULL, term);
846         di->condition_list = g_slist_append(di->condition_list, term_list);
847
848         return SRD_OK;
849 }
850
851 static PyObject *Decoder_wait(PyObject *self, PyObject *args)
852 {
853         int ret;
854         uint64_t skip_count;
855         unsigned int i;
856         gboolean found_match;
857         struct srd_decoder_inst *di;
858         PyObject *py_pinvalues, *py_matched, *py_samplenum;
859         PyGILState_STATE gstate;
860
861         if (!self || !args)
862                 return NULL;
863
864         gstate = PyGILState_Ensure();
865
866         if (!(di = srd_inst_find_by_obj(NULL, self))) {
867                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
868                 PyGILState_Release(gstate);
869                 Py_RETURN_NONE;
870         }
871
872         ret = set_new_condition_list(self, args);
873         if (ret < 0) {
874                 srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
875                 goto err;
876         }
877         if (ret == 9999) {
878                 /*
879                  * Empty condition list, automatic match. Arrange for the
880                  * execution of regular match handling code paths such that
881                  * the next available sample is returned to the caller.
882                  * Make sure to skip one sample when "anywhere within the
883                  * stream", yet make sure to not skip sample number 0.
884                  */
885                 if (di->abs_cur_samplenum)
886                         skip_count = 1;
887                 else if (!di->condition_list)
888                         skip_count = 0;
889                 else
890                         skip_count = 1;
891                 ret = set_skip_condition(di, skip_count);
892                 if (ret < 0) {
893                         srd_dbg("%s: %s: Cannot setup condition-less wait().",
894                                 di->inst_id, __func__);
895                         goto err;
896                 }
897         }
898
899         while (1) {
900
901                 Py_BEGIN_ALLOW_THREADS
902
903                 /* Wait for new samples to process, or termination request. */
904                 g_mutex_lock(&di->data_mutex);
905                 while (!di->got_new_samples && !di->want_wait_terminate)
906                         g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);
907
908                 /*
909                  * Check whether any of the current condition(s) match.
910                  * Arrange for termination requests to take a code path which
911                  * won't find new samples to process, pretends to have processed
912                  * previously stored samples, and returns to the main thread,
913                  * while the termination request still gets signalled.
914                  */
915                 found_match = FALSE;
916
917                 /* Ignore return value for now, should never be negative. */
918                 (void)process_samples_until_condition_match(di, &found_match);
919
920                 Py_END_ALLOW_THREADS
921
922                 /* If there's a match, set self.samplenum etc. and return. */
923                 if (found_match) {
924                         /* Set self.samplenum to the (absolute) sample number that matched. */
925                         py_samplenum = PyLong_FromUnsignedLongLong(di->abs_cur_samplenum);
926                         PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
927                         Py_DECREF(py_samplenum);
928
929                         if (di->match_array && di->match_array->len > 0) {
930                                 py_matched = PyTuple_New(di->match_array->len);
931                                 for (i = 0; i < di->match_array->len; i++)
932                                         PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i]));
933                                 PyObject_SetAttrString(di->py_inst, "matched", py_matched);
934                                 Py_DECREF(py_matched);
935                                 match_array_free(di);
936                         } else {
937                                 PyObject_SetAttrString(di->py_inst, "matched", Py_None);
938                         }
939
940                         py_pinvalues = get_current_pinvalues(di);
941
942                         g_mutex_unlock(&di->data_mutex);
943
944                         PyGILState_Release(gstate);
945
946                         return py_pinvalues;
947                 }
948
949                 /* No match, reset state for the next chunk. */
950                 di->got_new_samples = FALSE;
951                 di->handled_all_samples = TRUE;
952                 di->abs_start_samplenum = 0;
953                 di->abs_end_samplenum = 0;
954                 di->inbuf = NULL;
955                 di->inbuflen = 0;
956
957                 /* Signal the main thread that we handled all samples. */
958                 g_cond_signal(&di->handled_all_samples_cond);
959
960                 /*
961                  * When termination of wait() and decode() was requested,
962                  * then exit the loop after releasing the mutex.
963                  */
964                 if (di->want_wait_terminate) {
965                         srd_dbg("%s: %s: Will return from wait().",
966                                 di->inst_id, __func__);
967                         g_mutex_unlock(&di->data_mutex);
968                         goto err;
969                 }
970
971                 g_mutex_unlock(&di->data_mutex);
972         }
973
974         PyGILState_Release(gstate);
975
976         Py_RETURN_NONE;
977
978 err:
979         PyGILState_Release(gstate);
980
981         return NULL;
982 }
983
984 /**
985  * Return whether the specified channel was supplied to the decoder.
986  *
987  * @param self TODO. Must not be NULL.
988  * @param args TODO. Must not be NULL.
989  *
990  * @retval Py_True The channel has been supplied by the frontend.
991  * @retval Py_False The channel has been supplied by the frontend.
992  * @retval NULL An error occurred.
993  */
994 static PyObject *Decoder_has_channel(PyObject *self, PyObject *args)
995 {
996         int idx, count;
997         struct srd_decoder_inst *di;
998         PyGILState_STATE gstate;
999
1000         if (!self || !args)
1001                 return NULL;
1002
1003         gstate = PyGILState_Ensure();
1004
1005         if (!(di = srd_inst_find_by_obj(NULL, self))) {
1006                 PyErr_SetString(PyExc_Exception, "decoder instance not found");
1007                 goto err;
1008         }
1009
1010         /*
1011          * Get the integer argument of self.has_channel(). Check for
1012          * the range of supported PD input channel numbers.
1013          */
1014         if (!PyArg_ParseTuple(args, "i", &idx)) {
1015                 /* Let Python raise this exception. */
1016                 goto err;
1017         }
1018
1019         count = g_slist_length(di->decoder->channels) +
1020                 g_slist_length(di->decoder->opt_channels);
1021         if (idx < 0 || idx >= count) {
1022                 srd_err("Invalid index %d, PD channel count %d.", idx, count);
1023                 PyErr_SetString(PyExc_IndexError, "invalid channel index");
1024                 goto err;
1025         }
1026
1027         PyGILState_Release(gstate);
1028
1029         return (di->dec_channelmap[idx] == -1) ? Py_False : Py_True;
1030
1031 err:
1032         PyGILState_Release(gstate);
1033
1034         return NULL;
1035 }
1036
1037 static PyMethodDef Decoder_methods[] = {
1038         { "put", Decoder_put, METH_VARARGS,
1039           "Accepts a dictionary with the following keys: startsample, endsample, data" },
1040         { "register", (PyCFunction)(void(*)(void))Decoder_register, METH_VARARGS|METH_KEYWORDS,
1041                         "Register a new output stream" },
1042         { "wait", Decoder_wait, METH_VARARGS,
1043                         "Wait for one or more conditions to occur" },
1044         { "has_channel", Decoder_has_channel, METH_VARARGS,
1045                         "Report whether a channel was supplied" },
1046         {NULL, NULL, 0, NULL}
1047 };
1048
1049 /**
1050  * Create the sigrokdecode.Decoder type.
1051  *
1052  * @return The new type object.
1053  *
1054  * @private
1055  */
1056 SRD_PRIV PyObject *srd_Decoder_type_new(void)
1057 {
1058         PyType_Spec spec;
1059         PyType_Slot slots[] = {
1060                 { Py_tp_doc, "sigrok Decoder base class" },
1061                 { Py_tp_methods, Decoder_methods },
1062                 { Py_tp_new, (void *)&PyType_GenericNew },
1063                 { 0, NULL }
1064         };
1065         PyObject *py_obj;
1066         PyGILState_STATE gstate;
1067
1068         gstate = PyGILState_Ensure();
1069
1070         spec.name = "sigrokdecode.Decoder";
1071         spec.basicsize = sizeof(srd_Decoder);
1072         spec.itemsize = 0;
1073         spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1074         spec.slots = slots;
1075
1076         py_obj = PyType_FromSpec(&spec);
1077
1078         PyGILState_Release(gstate);
1079
1080         return py_obj;
1081 }