spiflash: add MX25L8006 device type
[libsigrokdecode/gsi.git] / type_decoder.c
blob6932cdef49537eb37a3cd17b7f96d20ae844f1da
1 /*
2 * This file is part of the libsigrokdecode project.
4 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
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.
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.
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/>.
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>
25 /** @cond PRIVATE */
26 extern SRD_PRIV GSList *sessions;
27 /** @endcond */
29 typedef struct {
30 PyObject_HEAD
31 } srd_Decoder;
33 /* This is only used for nicer srd_dbg() output. */
34 SRD_PRIV const char *output_type_name(unsigned int idx)
36 static const char *names[] = {
37 "OUTPUT_ANN",
38 "OUTPUT_PYTHON",
39 "OUTPUT_BINARY",
40 "OUTPUT_LOGIC",
41 "OUTPUT_META",
42 "(invalid)"
45 return names[MIN(idx, G_N_ELEMENTS(names) - 1)];
48 static void release_annotation(struct srd_proto_data_annotation *pda)
50 if (!pda)
51 return;
52 if (pda->ann_text)
53 g_strfreev(pda->ann_text);
56 static int convert_annotation(struct srd_decoder_inst *di, PyObject *obj,
57 struct srd_proto_data *pdata)
59 PyObject *py_tmp;
60 struct srd_pd_output *pdo;
61 struct srd_proto_data_annotation *pda;
62 int ann_class;
63 char **ann_text;
64 PyGILState_STATE gstate;
66 gstate = PyGILState_Ensure();
68 /* Should be a list of [annotation class, [string, ...]]. */
69 if (!PyList_Check(obj)) {
70 srd_err("Protocol decoder %s submitted an annotation that is not a list",
71 di->decoder->name);
72 goto err;
75 /* Should have 2 elements. */
76 if (PyList_Size(obj) != 2) {
77 ssize_t sz = PyList_Size(obj);
78 srd_err("Protocol decoder %s submitted annotation list with %zd elements instead of 2",
79 di->decoder->name, sz);
80 goto err;
84 * The first element should be an integer matching a previously
85 * registered annotation class.
87 py_tmp = PyList_GetItem(obj, 0);
88 if (!PyLong_Check(py_tmp)) {
89 srd_err("Protocol decoder %s submitted annotation list, but first element was not an integer.",
90 di->decoder->name);
91 goto err;
93 ann_class = PyLong_AsLong(py_tmp);
94 if (!(pdo = g_slist_nth_data(di->decoder->annotations, ann_class))) {
95 srd_err("Protocol decoder %s submitted data to unregistered annotation class %d.",
96 di->decoder->name, ann_class);
97 goto err;
100 /* Second element must be a list. */
101 py_tmp = PyList_GetItem(obj, 1);
102 if (!PyList_Check(py_tmp)) {
103 srd_err("Protocol decoder %s submitted annotation list, but second element was not a list.",
104 di->decoder->name);
105 goto err;
107 if (py_strseq_to_char(py_tmp, &ann_text) != SRD_OK) {
108 srd_err("Protocol decoder %s submitted annotation list, but second element was malformed.",
109 di->decoder->name);
110 goto err;
113 pda = pdata->data;
114 pda->ann_class = ann_class;
115 pda->ann_text = ann_text;
117 PyGILState_Release(gstate);
119 return SRD_OK;
121 err:
122 PyGILState_Release(gstate);
124 return SRD_ERR_PYTHON;
127 static void release_logic(struct srd_proto_data_logic *pdl)
129 if (!pdl)
130 return;
131 g_free((void *)pdl->data);
134 static int convert_logic(struct srd_decoder_inst *di, PyObject *obj,
135 struct srd_proto_data *pdata)
137 struct srd_proto_data_logic *pdl;
138 PyObject *py_tmp;
139 Py_ssize_t size;
140 int logic_group;
141 char *group_name, *buf;
142 PyGILState_STATE gstate;
144 gstate = PyGILState_Ensure();
146 /* Should be a list of [logic group, bytes]. */
147 if (!PyList_Check(obj)) {
148 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_LOGIC.",
149 di->decoder->name);
150 goto err;
153 /* Should have 2 elements. */
154 if (PyList_Size(obj) != 2) {
155 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC list "
156 "with %zd elements instead of 2", di->decoder->name,
157 PyList_Size(obj));
158 goto err;
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_LOGIC list, "
165 "but first element was not an integer.", di->decoder->name);
166 goto err;
168 logic_group = PyLong_AsLong(py_tmp);
169 if (!(group_name = g_slist_nth_data(di->decoder->logic_output_channels, logic_group))) {
170 srd_err("Protocol decoder %s submitted SRD_OUTPUT_LOGIC with "
171 "unregistered logic group %d.", di->decoder->name, logic_group);
172 goto err;
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_LOGIC list, "
179 "but second element was not bytes.", di->decoder->name);
180 goto err;
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_LOGIC "
186 "with empty data set.", di->decoder->name);
187 goto err;
190 if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
191 goto err;
193 PyGILState_Release(gstate);
195 pdl = pdata->data;
196 pdl->logic_group = logic_group;
197 /* pdl->repeat_count is set by the caller as it depends on the sample range */
198 if (!(pdl->data = g_try_malloc(size)))
199 return SRD_ERR_MALLOC;
200 memcpy((void *)pdl->data, (const void *)buf, size);
202 return SRD_OK;
204 err:
205 PyGILState_Release(gstate);
207 return SRD_ERR_PYTHON;
210 static void release_binary(struct srd_proto_data_binary *pdb)
212 if (!pdb)
213 return;
214 g_free((void *)pdb->data);
217 static int convert_binary(struct srd_decoder_inst *di, PyObject *obj,
218 struct srd_proto_data *pdata)
220 struct srd_proto_data_binary *pdb;
221 PyObject *py_tmp;
222 Py_ssize_t size;
223 int bin_class;
224 char *class_name, *buf;
225 PyGILState_STATE gstate;
227 gstate = PyGILState_Ensure();
229 /* Should be a list of [binary class, bytes]. */
230 if (!PyList_Check(obj)) {
231 srd_err("Protocol decoder %s submitted non-list for SRD_OUTPUT_BINARY.",
232 di->decoder->name);
233 goto err;
236 /* Should have 2 elements. */
237 if (PyList_Size(obj) != 2) {
238 ssize_t sz = PyList_Size(obj);
239 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list with %zd elements instead of 2",
240 di->decoder->name, sz);
241 goto err;
244 /* The first element should be an integer. */
245 py_tmp = PyList_GetItem(obj, 0);
246 if (!PyLong_Check(py_tmp)) {
247 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, but first element was not an integer.",
248 di->decoder->name);
249 goto err;
251 bin_class = PyLong_AsLong(py_tmp);
252 if (!(class_name = g_slist_nth_data(di->decoder->binary, bin_class))) {
253 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY with unregistered binary class %d.",
254 di->decoder->name, bin_class);
255 goto err;
258 /* Second element should be bytes. */
259 py_tmp = PyList_GetItem(obj, 1);
260 if (!PyBytes_Check(py_tmp)) {
261 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY list, but second element was not bytes.",
262 di->decoder->name);
263 goto err;
266 /* Consider an empty set of bytes a bug. */
267 if (PyBytes_Size(py_tmp) == 0) {
268 srd_err("Protocol decoder %s submitted SRD_OUTPUT_BINARY with empty data set.",
269 di->decoder->name);
270 goto err;
273 if (PyBytes_AsStringAndSize(py_tmp, &buf, &size) == -1)
274 goto err;
276 PyGILState_Release(gstate);
278 pdb = pdata->data;
279 pdb->bin_class = bin_class;
280 pdb->size = size;
281 if (!(pdb->data = g_try_malloc(pdb->size)))
282 return SRD_ERR_MALLOC;
283 memcpy((void *)pdb->data, (const void *)buf, pdb->size);
285 return SRD_OK;
287 err:
288 PyGILState_Release(gstate);
290 return SRD_ERR_PYTHON;
293 static inline struct srd_decoder_inst *srd_sess_inst_find_by_obj(
294 struct srd_session *sess, const GSList *stack, const PyObject *obj)
296 const GSList *l;
297 struct srd_decoder_inst *tmp, *di;
299 if (!sess)
300 return NULL;
302 di = NULL;
303 for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) {
304 tmp = l->data;
305 if (tmp->py_inst == obj)
306 di = tmp;
307 else if (tmp->next_di)
308 di = srd_sess_inst_find_by_obj(sess, tmp->next_di, obj);
311 return di;
315 * Find a decoder instance by its Python object.
317 * I.e. find that instance's instantiation of the sigrokdecode.Decoder class.
318 * This will recurse to find the instance anywhere in the stack tree of all
319 * sessions.
321 * @param stack Pointer to a GSList of struct srd_decoder_inst, indicating the
322 * stack to search. To start searching at the bottom level of
323 * decoder instances, pass NULL.
324 * @param obj The Python class instantiation.
326 * @return Pointer to struct srd_decoder_inst, or NULL if not found.
328 * @since 0.1.0
330 static inline struct srd_decoder_inst *srd_inst_find_by_obj(
331 const GSList *stack, const PyObject *obj)
333 struct srd_decoder_inst *di;
334 struct srd_session *sess;
335 GSList *l;
337 /* Performance shortcut: Handle the most common case first. */
338 sess = sessions->data;
339 di = sess->di_list->data;
340 if (di->py_inst == obj)
341 return di;
343 di = NULL;
344 for (l = sessions; di == NULL && l != NULL; l = l->next) {
345 sess = l->data;
346 di = srd_sess_inst_find_by_obj(sess, stack, obj);
349 return di;
352 static int convert_meta(struct srd_proto_data *pdata, PyObject *obj)
354 long long intvalue;
355 double dvalue;
356 PyGILState_STATE gstate;
358 gstate = PyGILState_Ensure();
360 if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_INT64)) {
361 if (!PyLong_Check(obj)) {
362 PyErr_Format(PyExc_TypeError,
363 "This output was registered as 'int', but something else was passed.");
364 goto err;
366 intvalue = PyLong_AsLongLong(obj);
367 if (PyErr_Occurred())
368 goto err;
369 pdata->data = g_variant_new_int64(intvalue);
370 } else if (g_variant_type_equal(pdata->pdo->meta_type, G_VARIANT_TYPE_DOUBLE)) {
371 if (!PyFloat_Check(obj)) {
372 PyErr_Format(PyExc_TypeError,
373 "This output was registered as 'float', but something else was passed.");
374 goto err;
376 dvalue = PyFloat_AsDouble(obj);
377 if (PyErr_Occurred())
378 goto err;
379 pdata->data = g_variant_new_double(dvalue);
382 PyGILState_Release(gstate);
384 return SRD_OK;
386 err:
387 PyGILState_Release(gstate);
389 return SRD_ERR_PYTHON;
392 static void release_meta(GVariant *gvar)
394 if (!gvar)
395 return;
396 g_variant_unref(gvar);
399 PyDoc_STRVAR(Decoder_put_doc,
400 "Put an annotation for the specified span of samples.\n"
401 "\n"
402 "Arguments: start and end sample number, stream id, annotation data.\n"
403 "Annotation data's layout depends on the output stream type."
406 static PyObject *Decoder_put(PyObject *self, PyObject *args)
408 GSList *l;
409 PyObject *py_data, *py_res;
410 struct srd_decoder_inst *di, *next_di;
411 struct srd_pd_output *pdo;
412 struct srd_proto_data pdata;
413 struct srd_proto_data_annotation pda;
414 struct srd_proto_data_binary pdb;
415 struct srd_proto_data_logic pdl;
416 uint64_t start_sample, end_sample;
417 int output_id;
418 struct srd_pd_callback *cb;
419 PyGILState_STATE gstate;
421 py_data = NULL;
423 gstate = PyGILState_Ensure();
425 if (!(di = srd_inst_find_by_obj(NULL, self))) {
426 /* Shouldn't happen. */
427 srd_dbg("put(): self instance not found.");
428 goto err;
431 if (!PyArg_ParseTuple(args, "KKiO", &start_sample, &end_sample,
432 &output_id, &py_data)) {
434 * This throws an exception, but by returning NULL here we let
435 * Python raise it. This results in a much better trace in
436 * controller.c on the decode() method call.
438 goto err;
441 if (!(l = g_slist_nth(di->pd_output, output_id))) {
442 srd_err("Protocol decoder %s submitted invalid output ID %d.",
443 di->decoder->name, output_id);
444 goto err;
446 pdo = l->data;
448 /* Upon SRD_OUTPUT_PYTHON for stacked PDs, we have a nicer log message later. */
449 if (pdo->output_type != SRD_OUTPUT_PYTHON && di->next_di != NULL) {
450 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s on "
451 "oid %d (%s).", di->inst_id, start_sample, end_sample,
452 output_type_name(pdo->output_type), output_id,
453 pdo->proto_id);
456 pdata.start_sample = start_sample;
457 pdata.end_sample = end_sample;
458 pdata.pdo = pdo;
459 pdata.data = NULL;
461 switch (pdo->output_type) {
462 case SRD_OUTPUT_ANN:
463 /* Annotations are only fed to callbacks. */
464 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
465 pdata.data = &pda;
466 /* Convert from PyDict to srd_proto_data_annotation. */
467 if (convert_annotation(di, py_data, &pdata) != SRD_OK) {
468 /* An error was already logged. */
469 break;
471 Py_BEGIN_ALLOW_THREADS
472 cb->cb(&pdata, cb->cb_data);
473 Py_END_ALLOW_THREADS
474 release_annotation(pdata.data);
476 break;
477 case SRD_OUTPUT_PYTHON:
478 for (l = di->next_di; l; l = l->next) {
479 next_di = l->data;
480 srd_spew("Instance %s put %" PRIu64 "-%" PRIu64 " %s "
481 "on oid %d (%s) to instance %s.", di->inst_id,
482 start_sample,
483 end_sample, output_type_name(pdo->output_type),
484 output_id, pdo->proto_id, next_di->inst_id);
485 py_res = PyObject_CallMethod(next_di->py_inst, "decode",
486 "KKO", start_sample, end_sample, py_data);
487 if (!py_res) {
488 srd_exception_catch("Calling %s decode() failed",
489 next_di->inst_id);
491 Py_XDECREF(py_res);
493 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
495 * Frontends aren't really supposed to get Python
496 * callbacks, but it's useful for testing.
498 pdata.data = py_data;
499 cb->cb(&pdata, cb->cb_data);
501 break;
502 case SRD_OUTPUT_BINARY:
503 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
504 pdata.data = &pdb;
505 /* Convert from PyDict to srd_proto_data_binary. */
506 if (convert_binary(di, py_data, &pdata) != SRD_OK) {
507 /* An error was already logged. */
508 break;
510 Py_BEGIN_ALLOW_THREADS
511 cb->cb(&pdata, cb->cb_data);
512 Py_END_ALLOW_THREADS
513 release_binary(pdata.data);
515 break;
516 case SRD_OUTPUT_LOGIC:
517 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
518 pdata.data = &pdl;
519 /* Convert from PyDict to srd_proto_data_logic. */
520 if (convert_logic(di, py_data, &pdata) != SRD_OK) {
521 /* An error was already logged. */
522 break;
524 if (end_sample <= start_sample) {
525 srd_err("Ignored SRD_OUTPUT_LOGIC with invalid sample range.");
526 break;
528 pdl.repeat_count = (end_sample - start_sample) - 1;
529 Py_BEGIN_ALLOW_THREADS
530 cb->cb(&pdata, cb->cb_data);
531 Py_END_ALLOW_THREADS
532 release_logic(pdata.data);
534 break;
535 case SRD_OUTPUT_META:
536 if ((cb = srd_pd_output_callback_find(di->sess, pdo->output_type))) {
537 /* Annotations need converting from PyObject. */
538 if (convert_meta(&pdata, py_data) != SRD_OK) {
539 /* An exception was already set up. */
540 break;
542 Py_BEGIN_ALLOW_THREADS
543 cb->cb(&pdata, cb->cb_data);
544 Py_END_ALLOW_THREADS
545 release_meta(pdata.data);
547 break;
548 default:
549 srd_err("Protocol decoder %s submitted invalid output type %d.",
550 di->decoder->name, pdo->output_type);
551 break;
554 PyGILState_Release(gstate);
556 Py_RETURN_NONE;
558 err:
559 PyGILState_Release(gstate);
561 return NULL;
564 PyDoc_STRVAR(Decoder_register_doc,
565 "Register a new output stream."
568 static PyObject *Decoder_register(PyObject *self,
569 PyObject *args, PyObject *kwargs)
571 struct srd_decoder_inst *di;
572 struct srd_pd_output *pdo;
573 PyObject *py_new_output_id;
574 PyTypeObject *meta_type_py;
575 const GVariantType *meta_type_gv;
576 int output_type;
577 char *proto_id, *meta_name, *meta_descr;
578 char *keywords[] = { "output_type", "proto_id", "meta", NULL };
579 PyGILState_STATE gstate;
580 gboolean is_meta;
581 GSList *l;
582 struct srd_pd_output *cmp;
584 gstate = PyGILState_Ensure();
586 meta_type_py = NULL;
587 meta_type_gv = NULL;
588 meta_name = meta_descr = NULL;
590 if (!(di = srd_inst_find_by_obj(NULL, self))) {
591 PyErr_SetString(PyExc_Exception, "decoder instance not found");
592 goto err;
595 /* Default to instance ID, which defaults to class ID. */
596 proto_id = di->inst_id;
597 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|s(Oss)", keywords,
598 &output_type, &proto_id,
599 &meta_type_py, &meta_name, &meta_descr)) {
600 /* Let Python raise this exception. */
601 goto err;
604 /* Check if the meta value's type is supported. */
605 is_meta = output_type == SRD_OUTPUT_META;
606 if (is_meta) {
607 if (meta_type_py == &PyLong_Type)
608 meta_type_gv = G_VARIANT_TYPE_INT64;
609 else if (meta_type_py == &PyFloat_Type)
610 meta_type_gv = G_VARIANT_TYPE_DOUBLE;
611 else {
612 PyErr_Format(PyExc_TypeError, "Unsupported type.");
613 goto err;
617 pdo = NULL;
618 for (l = di->pd_output; l; l = l->next) {
619 cmp = l->data;
620 if (cmp->output_type != output_type)
621 continue;
622 if (strcmp(cmp->proto_id, proto_id) != 0)
623 continue;
624 if (is_meta && cmp->meta_type != meta_type_gv)
625 continue;
626 if (is_meta && strcmp(cmp->meta_name, meta_name) != 0)
627 continue;
628 if (is_meta && strcmp(cmp->meta_descr, meta_descr) != 0)
629 continue;
630 pdo = cmp;
631 break;
633 if (pdo) {
634 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
635 PyGILState_Release(gstate);
636 return py_new_output_id;
639 pdo = g_malloc(sizeof(struct srd_pd_output));
641 /* pdo_id is just a simple index, nothing is deleted from this list anyway. */
642 pdo->pdo_id = g_slist_length(di->pd_output);
643 pdo->output_type = output_type;
644 pdo->di = di;
645 pdo->proto_id = g_strdup(proto_id);
647 if (output_type == SRD_OUTPUT_META) {
648 pdo->meta_type = meta_type_gv;
649 pdo->meta_name = g_strdup(meta_name);
650 pdo->meta_descr = g_strdup(meta_descr);
653 di->pd_output = g_slist_append(di->pd_output, pdo);
654 py_new_output_id = Py_BuildValue("i", pdo->pdo_id);
656 PyGILState_Release(gstate);
658 srd_dbg("Instance %s creating new output type %s as oid %d (%s).",
659 di->inst_id, output_type_name(output_type), pdo->pdo_id,
660 proto_id);
662 return py_new_output_id;
664 err:
665 PyGILState_Release(gstate);
667 return NULL;
670 static int get_term_type(const char *v)
672 switch (v[0]) {
673 case 'h':
674 return SRD_TERM_HIGH;
675 case 'l':
676 return SRD_TERM_LOW;
677 case 'r':
678 return SRD_TERM_RISING_EDGE;
679 case 'f':
680 return SRD_TERM_FALLING_EDGE;
681 case 'e':
682 return SRD_TERM_EITHER_EDGE;
683 case 'n':
684 return SRD_TERM_NO_EDGE;
685 default:
686 return -1;
689 return -1;
693 * Get the pin values at the current sample number.
695 * @param di The decoder instance to use. Must not be NULL.
696 * The number of channels must be >= 1.
698 * @return A newly allocated PyTuple containing the pin values at the
699 * current sample number.
701 static PyObject *get_current_pinvalues(const struct srd_decoder_inst *di)
703 int i;
704 uint8_t sample;
705 const uint8_t *sample_pos;
706 int byte_offset, bit_offset;
707 PyObject *py_pinvalues;
708 PyGILState_STATE gstate;
710 if (!di) {
711 srd_err("Invalid decoder instance.");
712 return NULL;
715 gstate = PyGILState_Ensure();
717 py_pinvalues = PyTuple_New(di->dec_num_channels);
719 for (i = 0; i < di->dec_num_channels; i++) {
720 /* A channelmap value of -1 means "unused optional channel". */
721 if (di->dec_channelmap[i] == -1) {
722 /* Value of unused channel is 0xff, instead of 0 or 1. */
723 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(0xff));
724 } else {
725 sample_pos = di->inbuf + ((di->abs_cur_samplenum - di->abs_start_samplenum) * di->data_unitsize);
726 byte_offset = di->dec_channelmap[i] / 8;
727 bit_offset = di->dec_channelmap[i] % 8;
728 sample = *(sample_pos + byte_offset) & (1 << bit_offset) ? 1 : 0;
729 PyTuple_SetItem(py_pinvalues, i, PyLong_FromUnsignedLong(sample));
733 PyGILState_Release(gstate);
735 return py_pinvalues;
739 * Create a list of terms in the specified condition.
741 * If there are no terms in the condition, 'term_list' will be NULL.
743 * @param di The decoder instance to use. Must not be NULL.
744 * @param py_dict A Python dict containing terms. Must not be NULL.
745 * @param term_list Pointer to a GSList which will be set to the newly
746 * created list of terms. Must not be NULL.
748 * @return SRD_OK upon success, a negative error code otherwise.
750 static int create_term_list(struct srd_decoder_inst *di,
751 PyObject *py_dict, GSList **term_list)
753 Py_ssize_t pos = 0;
754 PyObject *py_key, *py_value;
755 struct srd_term *term;
756 int64_t num_samples_to_skip;
757 char *term_str;
758 PyGILState_STATE gstate;
760 if (!py_dict || !term_list)
761 return SRD_ERR_ARG;
763 /* "Create" an empty GSList of terms. */
764 *term_list = NULL;
766 gstate = PyGILState_Ensure();
768 /* Iterate over all items in the current dict. */
769 while (PyDict_Next(py_dict, &pos, &py_key, &py_value)) {
770 /* Check whether the current key is a string or a number. */
771 if (PyLong_Check(py_key)) {
772 /* The key is a number. */
773 /* Get the value string. */
774 if ((py_pydictitem_as_str(py_dict, py_key, &term_str)) != SRD_OK) {
775 srd_err("Failed to get the value.");
776 goto err;
778 term = g_malloc(sizeof(struct srd_term));
779 term->type = get_term_type(term_str);
780 term->channel = PyLong_AsLong(py_key);
781 if (term->channel < 0 || term->channel >= di->dec_num_channels)
782 term->type = SRD_TERM_ALWAYS_FALSE;
783 g_free(term_str);
784 } else if (PyUnicode_Check(py_key)) {
785 /* The key is a string. */
786 /* TODO: Check if the key is "skip". */
787 if ((py_pydictitem_as_long(py_dict, py_key, &num_samples_to_skip)) != SRD_OK) {
788 srd_err("Failed to get number of samples to skip.");
789 goto err;
791 term = g_malloc(sizeof(struct srd_term));
792 term->type = SRD_TERM_SKIP;
793 term->num_samples_to_skip = num_samples_to_skip;
794 term->num_samples_already_skipped = 0;
795 if (num_samples_to_skip < 0)
796 term->type = SRD_TERM_ALWAYS_FALSE;
797 } else {
798 srd_err("Term key is neither a string nor a number.");
799 goto err;
802 /* Add the term to the list of terms. */
803 *term_list = g_slist_append(*term_list, term);
806 PyGILState_Release(gstate);
808 return SRD_OK;
810 err:
811 PyGILState_Release(gstate);
813 return SRD_ERR;
817 * Replace the current condition list with the new one.
819 * @param self TODO. Must not be NULL.
820 * @param args TODO. Must not be NULL.
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 * @retval 9999 TODO.
827 static int set_new_condition_list(PyObject *self, PyObject *args)
829 struct srd_decoder_inst *di;
830 GSList *term_list;
831 PyObject *py_conditionlist, *py_conds, *py_dict;
832 int i, num_conditions, ret;
833 PyGILState_STATE gstate;
835 if (!self || !args)
836 return SRD_ERR_ARG;
838 gstate = PyGILState_Ensure();
840 /* Get the decoder instance. */
841 if (!(di = srd_inst_find_by_obj(NULL, self))) {
842 PyErr_SetString(PyExc_Exception, "decoder instance not found");
843 goto err;
847 * Return an error condition from .wait() when termination is
848 * requested, such that decode() will terminate.
850 if (di->want_wait_terminate) {
851 srd_dbg("%s: %s: Skip (want_term).", di->inst_id, __func__);
852 goto err;
856 * Parse the argument of self.wait() into 'py_conds', and check
857 * the data type. The argument is optional, None is assumed in
858 * its absence. None or an empty dict or an empty list mean that
859 * there is no condition, and the next available sample shall
860 * get returned to the caller.
862 py_conds = Py_None;
863 if (!PyArg_ParseTuple(args, "|O", &py_conds)) {
864 /* Let Python raise this exception. */
865 goto err;
867 if (py_conds == Py_None) {
868 /* 'py_conds' is None. */
869 goto ret_9999;
870 } else if (PyList_Check(py_conds)) {
871 /* 'py_conds' is a list. */
872 py_conditionlist = py_conds;
873 num_conditions = PyList_Size(py_conditionlist);
874 if (num_conditions == 0)
875 goto ret_9999; /* The PD invoked self.wait([]). */
876 Py_INCREF(py_conditionlist);
877 } else if (PyDict_Check(py_conds)) {
878 /* 'py_conds' is a dict. */
879 if (PyDict_Size(py_conds) == 0)
880 goto ret_9999; /* The PD invoked self.wait({}). */
881 /* Make a list and put the dict in there for convenience. */
882 py_conditionlist = PyList_New(1);
883 Py_INCREF(py_conds);
884 PyList_SetItem(py_conditionlist, 0, py_conds);
885 num_conditions = 1;
886 } else {
887 srd_err("Condition list is neither a list nor a dict.");
888 goto err;
891 /* Free the old condition list. */
892 condition_list_free(di);
894 ret = SRD_OK;
896 /* Iterate over the conditions, set di->condition_list accordingly. */
897 for (i = 0; i < num_conditions; i++) {
898 /* Get a condition (dict) from the condition list. */
899 py_dict = PyList_GetItem(py_conditionlist, i);
900 if (!PyDict_Check(py_dict)) {
901 srd_err("Condition is not a dict.");
902 ret = SRD_ERR;
903 break;
906 /* Create the list of terms in this condition. */
907 if ((ret = create_term_list(di, py_dict, &term_list)) < 0)
908 break;
910 /* Add the new condition to the PD instance's condition list. */
911 di->condition_list = g_slist_append(di->condition_list, term_list);
914 Py_DecRef(py_conditionlist);
916 PyGILState_Release(gstate);
918 return ret;
920 err:
921 PyGILState_Release(gstate);
923 return SRD_ERR;
925 ret_9999:
926 PyGILState_Release(gstate);
928 return 9999;
932 * Create a SKIP condition list for condition-less .wait() calls.
934 * @param di Decoder instance.
935 * @param count Number of samples to skip.
937 * @retval SRD_OK The new condition list was set successfully.
938 * @retval SRD_ERR There was an error setting the new condition list.
939 * The contents of di->condition_list are undefined.
941 * This routine is a reduced and specialized version of the @ref
942 * set_new_condition_list() and @ref create_term_list() routines which
943 * gets invoked when .wait() was called without specifications for
944 * conditions. This minor duplication of the SKIP term list creation
945 * simplifies the logic and avoids the creation of expensive Python
946 * objects with "constant" values which the caller did not pass in the
947 * first place. It results in maximum sharing of match handling code
948 * paths.
950 static int set_skip_condition(struct srd_decoder_inst *di, uint64_t count)
952 struct srd_term *term;
953 GSList *term_list;
955 condition_list_free(di);
956 term = g_malloc(sizeof(*term));
957 term->type = SRD_TERM_SKIP;
958 term->num_samples_to_skip = count;
959 term->num_samples_already_skipped = 0;
960 term_list = g_slist_append(NULL, term);
961 di->condition_list = g_slist_append(di->condition_list, term_list);
963 return SRD_OK;
966 PyDoc_STRVAR(Decoder_wait_doc,
967 "Wait for one or more conditions to occur.\n"
968 "\n"
969 "Returns the sample data at the next position where the condition\n"
970 "is seen. When the optional condition is missing or empty, the next\n"
971 "sample number is used. The condition can be a dictionary with one\n"
972 "condition's details, or a list of dictionaries specifying multiple\n"
973 "conditions of which at least one condition must be true. Dicts can\n"
974 "contain one or more key/value pairs, all of which must be true for\n"
975 "the dict's condition to be considered true. The key either is a\n"
976 "channel index or a keyword, the value is the operation's parameter.\n"
977 "\n"
978 "Supported parameters for channel number keys: 'h', 'l', 'r', 'f',\n"
979 "or 'e' for level or edge conditions. Other supported keywords:\n"
980 "'skip' to advance over the given number of samples.\n"
983 static PyObject *Decoder_wait(PyObject *self, PyObject *args)
985 int ret;
986 uint64_t skip_count;
987 unsigned int i;
988 gboolean found_match;
989 struct srd_decoder_inst *di;
990 PyObject *py_pinvalues, *py_matched, *py_samplenum;
991 PyGILState_STATE gstate;
993 if (!self || !args)
994 return NULL;
996 gstate = PyGILState_Ensure();
998 if (!(di = srd_inst_find_by_obj(NULL, self))) {
999 PyErr_SetString(PyExc_Exception, "decoder instance not found");
1000 PyGILState_Release(gstate);
1001 Py_RETURN_NONE;
1004 ret = set_new_condition_list(self, args);
1005 if (ret < 0) {
1006 srd_dbg("%s: %s: Aborting wait().", di->inst_id, __func__);
1007 goto err;
1009 if (ret == 9999) {
1011 * Empty condition list, automatic match. Arrange for the
1012 * execution of regular match handling code paths such that
1013 * the next available sample is returned to the caller.
1014 * Make sure to skip one sample when "anywhere within the
1015 * stream", yet make sure to not skip sample number 0.
1017 if (di->abs_cur_samplenum)
1018 skip_count = 1;
1019 else if (!di->condition_list)
1020 skip_count = 0;
1021 else
1022 skip_count = 1;
1023 ret = set_skip_condition(di, skip_count);
1024 if (ret < 0) {
1025 srd_dbg("%s: %s: Cannot setup condition-less wait().",
1026 di->inst_id, __func__);
1027 goto err;
1031 while (1) {
1033 Py_BEGIN_ALLOW_THREADS
1035 /* Wait for new samples to process, or termination request. */
1036 g_mutex_lock(&di->data_mutex);
1037 while (!di->got_new_samples && !di->want_wait_terminate)
1038 g_cond_wait(&di->got_new_samples_cond, &di->data_mutex);
1041 * Check whether any of the current condition(s) match.
1042 * Arrange for termination requests to take a code path which
1043 * won't find new samples to process, pretends to have processed
1044 * previously stored samples, and returns to the main thread,
1045 * while the termination request still gets signalled.
1047 found_match = FALSE;
1049 /* Ignore return value for now, should never be negative. */
1050 (void)process_samples_until_condition_match(di, &found_match);
1052 Py_END_ALLOW_THREADS
1054 /* If there's a match, set self.samplenum etc. and return. */
1055 if (found_match) {
1056 /* Set self.samplenum to the (absolute) sample number that matched. */
1057 py_samplenum = PyLong_FromUnsignedLongLong(di->abs_cur_samplenum);
1058 PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
1059 Py_DECREF(py_samplenum);
1061 if (di->match_array && di->match_array->len > 0) {
1062 py_matched = PyTuple_New(di->match_array->len);
1063 for (i = 0; i < di->match_array->len; i++)
1064 PyTuple_SetItem(py_matched, i, PyBool_FromLong(di->match_array->data[i]));
1065 PyObject_SetAttrString(di->py_inst, "matched", py_matched);
1066 Py_DECREF(py_matched);
1067 match_array_free(di);
1068 } else {
1069 PyObject_SetAttrString(di->py_inst, "matched", Py_None);
1072 py_pinvalues = get_current_pinvalues(di);
1074 g_mutex_unlock(&di->data_mutex);
1076 PyGILState_Release(gstate);
1078 return py_pinvalues;
1081 /* No match, reset state for the next chunk. */
1082 di->got_new_samples = FALSE;
1083 di->handled_all_samples = TRUE;
1084 di->abs_start_samplenum = 0;
1085 di->abs_end_samplenum = 0;
1086 di->inbuf = NULL;
1087 di->inbuflen = 0;
1089 /* Signal the main thread that we handled all samples. */
1090 g_cond_signal(&di->handled_all_samples_cond);
1093 * When EOF was provided externally, communicate the
1094 * Python EOFError exception to .decode() and return
1095 * from the .wait() method call. This is motivated by
1096 * the use of Python context managers, so that .decode()
1097 * methods can "close" incompletely accumulated data
1098 * when the sample data is exhausted.
1100 if (di->communicate_eof) {
1101 /* Advance self.samplenum to the (absolute) last sample number. */
1102 py_samplenum = PyLong_FromUnsignedLongLong(di->abs_cur_samplenum);
1103 PyObject_SetAttrString(di->py_inst, "samplenum", py_samplenum);
1104 Py_DECREF(py_samplenum);
1105 /* Raise an EOFError Python exception. */
1106 srd_dbg("%s: %s: Raising EOF from wait().",
1107 di->inst_id, __func__);
1108 g_mutex_unlock(&di->data_mutex);
1109 PyErr_SetString(PyExc_EOFError, "samples exhausted");
1110 goto err;
1114 * When termination of wait() and decode() was requested,
1115 * then exit the loop after releasing the mutex.
1117 if (di->want_wait_terminate) {
1118 srd_dbg("%s: %s: Will return from wait().",
1119 di->inst_id, __func__);
1120 g_mutex_unlock(&di->data_mutex);
1121 goto err;
1124 g_mutex_unlock(&di->data_mutex);
1127 PyGILState_Release(gstate);
1129 Py_RETURN_NONE;
1131 err:
1132 PyGILState_Release(gstate);
1134 return NULL;
1137 PyDoc_STRVAR(Decoder_has_channel_doc,
1138 "Check whether input data is supplied for a given channel.\n"
1139 "\n"
1140 "Argument: A channel index.\n"
1141 "Returns: A boolean, True if the channel is connected,\n"
1142 "False if the channel is open (won't see any input data).\n"
1146 * Return whether the specified channel was supplied to the decoder.
1148 * @param self TODO. Must not be NULL.
1149 * @param args TODO. Must not be NULL.
1151 * @retval Py_True The channel has been supplied by the frontend.
1152 * @retval Py_False The channel has been supplied by the frontend.
1153 * @retval NULL An error occurred.
1155 static PyObject *Decoder_has_channel(PyObject *self, PyObject *args)
1157 int idx, count;
1158 struct srd_decoder_inst *di;
1159 PyGILState_STATE gstate;
1160 PyObject *bool_ret;
1162 if (!self || !args)
1163 return NULL;
1165 gstate = PyGILState_Ensure();
1167 if (!(di = srd_inst_find_by_obj(NULL, self))) {
1168 PyErr_SetString(PyExc_Exception, "decoder instance not found");
1169 goto err;
1173 * Get the integer argument of self.has_channel(). Check for
1174 * the range of supported PD input channel numbers.
1176 if (!PyArg_ParseTuple(args, "i", &idx)) {
1177 /* Let Python raise this exception. */
1178 goto err;
1181 count = g_slist_length(di->decoder->channels) +
1182 g_slist_length(di->decoder->opt_channels);
1183 if (idx < 0 || idx >= count) {
1184 srd_err("Invalid index %d, PD channel count %d.", idx, count);
1185 PyErr_SetString(PyExc_IndexError, "invalid channel index");
1186 goto err;
1189 PyGILState_Release(gstate);
1191 bool_ret = (di->dec_channelmap[idx] == -1) ? Py_False : Py_True;
1192 Py_INCREF(bool_ret);
1193 return bool_ret;
1195 err:
1196 PyGILState_Release(gstate);
1198 return NULL;
1201 PyDoc_STRVAR(Decoder_doc, "sigrok Decoder base class");
1203 static PyMethodDef Decoder_methods[] = {
1204 { "put",
1205 Decoder_put, METH_VARARGS,
1206 Decoder_put_doc,
1208 { "register",
1209 (PyCFunction)(void(*)(void))Decoder_register, METH_VARARGS | METH_KEYWORDS,
1210 Decoder_register_doc,
1212 { "wait",
1213 Decoder_wait, METH_VARARGS,
1214 Decoder_wait_doc,
1216 { "has_channel",
1217 Decoder_has_channel, METH_VARARGS,
1218 Decoder_has_channel_doc,
1220 ALL_ZERO,
1224 * Create the sigrokdecode.Decoder type.
1226 * @return The new type object.
1228 * @private
1230 SRD_PRIV PyObject *srd_Decoder_type_new(void)
1232 PyType_Spec spec;
1233 PyType_Slot slots[] = {
1234 { Py_tp_doc, Decoder_doc },
1235 { Py_tp_methods, Decoder_methods },
1236 { Py_tp_new, (void *)&PyType_GenericNew },
1237 ALL_ZERO,
1239 PyObject *py_obj;
1240 PyGILState_STATE gstate;
1242 gstate = PyGILState_Ensure();
1244 spec.name = "sigrokdecode.Decoder";
1245 spec.basicsize = sizeof(srd_Decoder);
1246 spec.itemsize = 0;
1247 spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
1248 spec.slots = slots;
1250 py_obj = PyType_FromSpec(&spec);
1252 PyGILState_Release(gstate);
1254 return py_obj;