* Set one or more options in a decoder instance. * * Handled options are removed from the hash. * * @param di Decoder instance. * @param options A GHashTable of options to set. * * @return SRD_OK upon success, a (negative) error code otherwise. * * @since 0.1.0 */
| 92 | * @since 0.1.0 |
| 93 | */ |
| 94 | SRD_API int srd_inst_option_set(struct srd_decoder_inst *di, |
| 95 | GHashTable *options) |
| 96 | { |
| 97 | struct srd_decoder_option *sdo; |
| 98 | PyObject *py_di_options, *py_optval; |
| 99 | GVariant *value; |
| 100 | GSList *l; |
| 101 | double val_double; |
| 102 | gint64 val_int; |
| 103 | int ret; |
| 104 | const char *val_str; |
| 105 | PyGILState_STATE gstate; |
| 106 | |
| 107 | if (!di) { |
| 108 | srd_err("Invalid decoder instance."); |
| 109 | return SRD_ERR_ARG; |
| 110 | } |
| 111 | |
| 112 | if (!options) { |
| 113 | srd_err("Invalid options GHashTable."); |
| 114 | return SRD_ERR_ARG; |
| 115 | } |
| 116 | |
| 117 | gstate = PyGILState_Ensure(); |
| 118 | |
| 119 | if (!PyObject_HasAttrString(di->decoder->py_dec, "options")) { |
| 120 | /* Decoder has no options. */ |
| 121 | PyGILState_Release(gstate); |
| 122 | if (g_hash_table_size(options) == 0) { |
| 123 | /* No options provided. */ |
| 124 | return SRD_OK; |
| 125 | } else { |
| 126 | srd_err("Protocol decoder has no options."); |
| 127 | return SRD_ERR_ARG; |
| 128 | } |
| 129 | return SRD_OK; |
| 130 | } |
| 131 | |
| 132 | ret = SRD_ERR_PYTHON; |
| 133 | py_optval = NULL; |
| 134 | |
| 135 | /* |
| 136 | * The 'options' tuple is a class variable, but we need to |
| 137 | * change it. Changing it directly will affect the entire class, |
| 138 | * so we need to create a new object for it, and populate that |
| 139 | * instead. |
| 140 | */ |
| 141 | if (!(py_di_options = PyObject_GetAttrString(di->py_inst, "options"))) |
| 142 | goto err_out; |
| 143 | Py_DECREF(py_di_options); |
| 144 | py_di_options = PyDict_New(); |
| 145 | PyObject_SetAttrString(di->py_inst, "options", py_di_options); |
| 146 | |
| 147 | for (l = di->decoder->options; l; l = l->next) { |
| 148 | sdo = l->data; |
| 149 | if ((value = g_hash_table_lookup(options, sdo->id))) { |
| 150 | /* A value was supplied for this option. */ |
| 151 | if (!g_variant_type_equal(g_variant_get_type(value), |
no test coverage detected