void dict_route_dictionary(t_dict_route *x, t_symbol *s) { t_dictionary *d = dictobj_findregistered_retain(s); if (!d) { object_error((t_object*)x, "unable to reference dictionary named %s", s); return; } if (proxy_getinlet((t_object*)x) == 0) { // left inlet : validate the input against the schema long validates = false; t_atom a; validates = dictobj_validate(x->schema_dict, d); atom_setsym(&a, s); if (validates) outlet_anything(x->outlet_dict, _sym_dictionary, 1, &a); else outlet_anything(x->outlet_nomatch, _sym_dictionary, 1, &a); } else { // right inlet : set the contents of the schema with a copy of the incoming dictionary if (d) { dictionary_clear(x->schema_dict); dictionary_clone_to_existing(d, x->schema_dict); } } dictobj_release(d); }
/** Called by _dict_recurse_dict() for each entry and _dict_recurse_array() for each index */ t_int32 _dict_recurse_value(t_dict_recurse *x, t_atom *value, t_int32 depth) { TRACE("_dict_recurse_value"); long type = atom_gettype(value); // ==== INT ==== if (type == A_LONG) { snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "%i", atom_getlong(value)); _dict_recurse_value_find(x, value, x->str_tmp); } // ==== FLOAT ==== else if (type == A_FLOAT) { snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "%i", atom_getfloat(value)); _dict_recurse_value_find(x, value, x->str_tmp); } // ==== SYMBOL / STRING ==== // NB: values in arrays are not A_SYM but A_OBJ else if ((type == A_SYM) || atomisstring(value)) { t_symbol *value_sym = atom_getsym(value); switch (x->command) { // == FIND A SYMBOL VALUE case CMD_FIND_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { POST(" %s \"%s\"", x->path, value_sym->s_name); x->count++; } break; // == FIND AN ENTRY case CMD_FIND_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { POST(" %s \"%s\"", x->path, value_sym->s_name); x->count++; } break; // == REPLACE A SYMBOL VALUE case CMD_REPLACE_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_chuckentry(x->dict_iter, x->key_iter); dictionary_appendsym(x->dict_iter, x->key_iter, x->replace_val_sym); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atom_setsym(value, x->replace_val_sym); } x->count++; if (x->a_verbose) { POST(" %s \"%s\" replaced by \"%s\"", x->path, value_sym->s_name, x->replace_val_sym->s_name); } } break; // == REPLACE AN ENTRY case CMD_REPLACE_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { dictionary_chuckentry(x->dict_iter, x->key_iter); dictionary_appendsym(x->dict_iter, x->replace_key_sym, x->replace_val_sym); x->count++; if (x->a_verbose) { POST(" %s \"%s\" replaced by (%s : %s)", x->path, value_sym->s_name, x->replace_key_sym->s_name, x->replace_val_sym->s_name); } } break; // == DELETE A SYMBOL VALUE case CMD_DELETE_VALUE_SYM: if (regexpr_match(x->search_val_expr, value_sym)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atomarray_chuckindex(x->array_iter, x->index_iter); } x->count++; if (x->a_verbose) { POST(" %s \"%s\" deleted", x->path, value_sym->s_name); } return VALUE_DEL; } break; // == DELETE A SYMBOL VALUE case CMD_DELETE_ENTRY: if (regexpr_match(x->search_key_expr, x->key_iter) && regexpr_match(x->search_val_expr, value_sym) && (x->type_iter == VALUE_TYPE_DICT)) { dictionary_deleteentry(x->dict_iter, x->key_iter); x->count++; if (x->a_verbose) { POST(" %s \"%s\" deleted", x->path, value_sym->s_name); } return VALUE_DEL; } break; // == DEFAULT: CMD_FIND_KEY or CMD_FIND_KEY_IN default: snprintf_zero(x->str_tmp, MAX_LEN_NUMBER, "\"%s\"", atom_getsym(value)->s_name); _dict_recurse_value_find(x, value, x->str_tmp); break; } } // ==== DICTIONARY ==== else if (atomisdictionary(value)) { t_dictionary *sub_dict = (t_dictionary *)atom_getobj(value); t_symbol *key_match = gensym(""); t_symbol *value_match = gensym(""); switch (x->command) { case CMD_FIND_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { x->count++; POST(" %s: dict containing (%s : %s)", x->path, key_match->s_name, value_match->s_name); } break; case CMD_REPLACE_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { t_dictionary *dict_cpy = dictionary_new(); dictionary_clone_to_existing(x->replace_dict, dict_cpy); // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); dictionary_appenddictionary(x->dict_iter, x->key_iter, (t_object *)dict_cpy); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { long array_len; t_atom *atom_arr; atomarray_getatoms(x->array_iter, &array_len, &atom_arr); atom_setobj(atom_arr + x->index_iter, dict_cpy); } x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): replaced by \"%s\"", x->path, key_match->s_name, value_match->s_name, x->replace_dict_sym->s_name); } return VALUE_NO_DEL; } break; case CMD_DELETE_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { // If the value is from a dictionary entry if (x->type_iter == VALUE_TYPE_DICT) { dictionary_deleteentry(x->dict_iter, x->key_iter); } // If the value is from an array else if (x->type_iter == VALUE_TYPE_ARRAY) { atomarray_chuckindex(x->array_iter, x->index_iter); object_free(sub_dict); } x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): deleted", x->path, key_match->s_name, value_match->s_name); } return VALUE_DEL; } break; case CMD_APPEND_IN_DICT_CONT_ENTRY: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match)) { dictionary_appendsym(sub_dict, x->replace_key_sym, x->replace_val_sym); x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): appended (%s : %s)", x->path, key_match->s_name, value_match->s_name, x->replace_key_sym->s_name, x->replace_val_sym->s_name); } } break; case CMD_APPEND_IN_DICT_CONT_ENTRY_D: if (_dict_recurse_match_dict(x, sub_dict, &key_match, &value_match) && dictionary_hasentry(x->replace_dict, x->replace_key_sym)) { t_symbol *key[2]; key[0] = x->replace_key_sym; key[1] = NULL; dictionary_copyentries(x->replace_dict, sub_dict, key); // NB: Strange it does not require the array size x->count++; if (x->a_verbose) { POST(" %s: dict containing (%s : %s): appended entry (%s : ...) from \"%s\"", x->path, key_match->s_name, value_match->s_name, x->replace_key_sym->s_name, x->replace_dict_sym->s_name); } } break; case CMD_APPEND_IN_DICT_FROM_KEY: if (regexpr_match(x->search_key_expr, x->key_iter) && (x->type_iter == VALUE_TYPE_DICT) && dictionary_hasentry(x->replace_dict, x->replace_key_sym)) { t_symbol *key[2]; key[0] = x->replace_key_sym; key[1] = NULL; dictionary_copyentries(x->replace_dict, sub_dict, key); // NB: Strange it does not require the array size x->count++; if (x->a_verbose) { POST(" %s: dict value: appended entry (%s : ...) from \"%s\"", x->path, x->replace_key_sym->s_name, x->replace_dict_sym->s_name); } } break; default: _dict_recurse_value_find(x, value, "_DICT_"); } // End of command "switch ..." _dict_recurse_dict(x, sub_dict, depth); } // End of dictionary "else if ..." // ==== ARRAY ==== else if (atomisatomarray(value)) { _dict_recurse_value_find(x, value, "_ARRAY_"); t_atomarray *atomarray = (t_atomarray *)atom_getobj(value); _dict_recurse_array(x, atomarray, depth); } return VALUE_NO_DEL; }