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