bool Dict::const_iterator::equal( const const_iterator& rh ) const { // _equal returns false if it_'s == 0 if ( !valid() && !rh.valid() ) { return true; } if ( dict_ == rh.dict_ ) { const char *rh_key, *key; xmmsv_dict_iter_pair( rh.it_, &rh_key, NULL ); xmmsv_dict_iter_pair( it_, &key, NULL ); return (std::strcmp( key, rh_key ) == 0); } return false; }
static bool _internal_put_on_bb_value_dict (xmmsv_t *bb, xmmsv_t *v) { xmmsv_dict_iter_t *it; const char *key; xmmsv_t *entry; uint32_t ret, offset, count; if (!xmmsv_get_dict_iter (v, &it)) { return false; } /* store a dummy value, store the real count once it's known */ offset = xmmsv_bitbuffer_pos (bb); xmmsv_bitbuffer_put_bits (bb, 32, 0); count = 0; while (xmmsv_dict_iter_valid (it)) { xmmsv_dict_iter_pair (it, &key, &entry); ret = _internal_put_on_bb_string (bb, key); ret = xmmsv_bitbuffer_serialize_value (bb, entry); xmmsv_dict_iter_next (it); count++; } /* overwrite with real size */ xmmsv_bitbuffer_put_bits_at (bb, 32, count, offset); return ret; }
static int32_t xmms_visualization_client_set_properties (xmms_visualization_t *vis, int32_t id, xmmsv_t* prop, xmms_error_t *err) { xmms_vis_client_t *c; xmmsv_dict_iter_t *it; const gchar *key, *valstr; xmmsv_t *value; x_fetch_client (id); if (!xmmsv_get_type (prop) == XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "properties must be sent as a dict!"); } else { /* record every pair */ xmmsv_get_dict_iter (prop, &it); while (xmmsv_dict_iter_valid (it)) { if (!xmmsv_dict_iter_pair (it, &key, &value)) { xmms_error_set (err, XMMS_ERROR_INVAL, "key-value property pair could not be read!"); } else if (!xmmsv_get_string (value, &valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property value could not be read!"); } else if (!property_set (&c->prop, key, valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property could not be set!"); } xmmsv_dict_iter_next (it); } /* TODO: propagate new format to xform! */ } x_release_client (); return (++c->format); }
static VALUE c_dict_aref (VALUE self, VALUE key) { RbDict *dict = NULL; xmmsv_dict_iter_t *it; xmmsv_t *value; const char *ckey; int s; Check_Type (key, T_SYMBOL); Data_Get_Struct (self, RbDict, dict); ckey = rb_id2name (SYM2ID (key)); xmmsv_get_dict_iter (dict->real, &it); s = xmmsv_dict_iter_find (it, ckey); if (!s) return Qnil; xmmsv_dict_iter_pair (it, NULL, &value); return extract_value (self, value); }
static xmms_fetch_spec_t * xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *spec; xmmsv_dict_iter_t *it; s4_sourcepref_t *sp; xmmsv_t *org_data; gint org_idx; if (!xmmsv_dict_get (fetch, "data", &org_data)) { xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize."); return NULL; } if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict."); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->type = FETCH_ORGANIZE; spec->data.organize.count = xmmsv_dict_get_size (org_data); spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count); spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count); org_idx = 0; xmmsv_get_dict_iter (org_data, &it); while (xmmsv_dict_iter_valid (it)) { xmms_fetch_spec_t *orgee; const gchar *str; xmmsv_t *entry; xmmsv_dict_iter_pair (it, &str, &entry); orgee = xmms_fetch_spec_new (entry, info, sp, err); if (xmms_error_iserror (err)) { xmms_fetch_spec_free (spec); spec = NULL; break; } spec->data.organize.keys[org_idx] = str; spec->data.organize.data[org_idx] = orgee; org_idx++; xmmsv_dict_iter_next (it); } xmmsv_dict_iter_explicit_destroy (it); s4_sourcepref_unref (sp); return spec; }
/* dumps a recursive key-source-val dict */ void print_entry (const gchar *key, xmmsv_t *dict, void *udata) { xmmsv_t *v; const gchar *source; if (xmmsv_get_type (dict) == XMMSV_TYPE_DICT) { xmmsv_dict_iter_t *it; xmmsv_get_dict_iter (dict, &it); while (xmmsv_dict_iter_valid (it)) { xmmsv_dict_iter_pair (it, &source, &v); switch (xmmsv_get_type (v)) { case XMMSV_TYPE_STRING: print_entry_string (v, key, source); break; case XMMSV_TYPE_INT32: { gint i; xmmsv_get_int (v, &i); print_info ("[%s] %s = %d", source, key, i); break; } default: print_info ("[%s] %s = (unknown data)", source, key); break; } xmmsv_dict_iter_next (it); } } }
/* Applies an aggregation function to the leafs in an xmmsv dict tree */ static xmmsv_t * aggregate_result (xmmsv_t *val, gint depth, aggregate_function_t aggr_func) { xmmsv_dict_iter_t *it; if (depth == 0) { return aggregate_data (val, aggr_func); } if (val == NULL && depth > 0) { return xmmsv_new_dict(); } /* If it's a dict we call this function recursively on all its values */ xmmsv_get_dict_iter (val, &it); while (xmmsv_dict_iter_valid (it)) { xmmsv_t *entry; xmmsv_dict_iter_pair (it, NULL, &entry); xmmsv_ref (entry); entry = aggregate_result (entry, depth - 1, aggr_func); xmmsv_dict_iter_set (it, entry); xmmsv_unref (entry); xmmsv_dict_iter_next (it); } return val; }
void Dict::const_iterator::copy( const const_iterator& rh ) { const char* key = 0; xmmsv_get_dict_iter( dict_, &it_ ); xmmsv_dict_iter_pair( rh.it_, &key, NULL ); xmmsv_dict_iter_find( it_, key ); }
/** * Helper function to transform a key-source-value dict-of-dict * #xmmsv_t (formerly a propdict) to a regular key-value dict, given a * list of source preference. * * @param propdict A key-source-value dict-of-dict #xmmsv_t. * @param src_prefs A list of source names or patterns. Must be * NULL-terminated. If this argument is NULL, the * default source preferences is used. * @return An #xmmsv_t containing a simple key-value dict. Must be * unreffed manually when done. */ xmmsv_t * xmmsv_propdict_to_dict (xmmsv_t *propdict, const char **src_prefs) { xmmsv_t *dict, *source_dict, *value, *best_value; xmmsv_dict_iter_t *key_it, *source_it; const char *key, *source; const char **local_prefs; int match_index, best_index; dict = xmmsv_new_dict (); local_prefs = src_prefs ? src_prefs : xmmsv_default_source_pref; xmmsv_get_dict_iter (propdict, &key_it); while (xmmsv_dict_iter_valid (key_it)) { xmmsv_dict_iter_pair (key_it, &key, &source_dict); best_value = NULL; best_index = -1; xmmsv_get_dict_iter (source_dict, &source_it); while (xmmsv_dict_iter_valid (source_it)) { xmmsv_dict_iter_pair (source_it, &source, &value); match_index = find_match_index (source, local_prefs); /* keep first match or better match */ if (match_index >= 0 && (best_index < 0 || match_index < best_index)) { best_value = value; best_index = match_index; } xmmsv_dict_iter_next (source_it); } /* Note: we do not insert a key-value pair if no source matches */ if (best_value) { xmmsv_dict_set (dict, key, best_value); } xmmsv_dict_iter_next (key_it); } return dict; }
const Dict::const_iterator::value_type& Dict::const_iterator::operator*() const { static value_type value; const char* key; xmmsv_t* val; xmmsv_dict_iter_pair( it_, &key, &val ); Dict::Variant var; getValue( var, val ); value = value_type( key, var ); return value; }
static void parse_attributes (xmmsv_t *coll, xmmsv_t *attrs) { xmmsv_dict_iter_t *it; xmmsv_t *entry; const char *key; assert (xmmsv_is_type (attrs, XMMSV_TYPE_DICT)); assert (xmmsv_get_dict_iter (attrs, &it)); while (xmmsv_dict_iter_pair (it, &key, &entry)) { xmmsv_coll_attribute_set_value (coll, key, entry); xmmsv_dict_iter_next (it); } }
xmmsv_coll_t * xmmsv_coll_copy (xmmsv_coll_t *orig_coll) { xmmsv_coll_t *new_coll, *coll_elem; xmmsv_list_iter_t *it; xmmsv_dict_iter_t *itd; xmmsv_t *v, *list, *dict; const char *key; int32_t i; const char *s; new_coll = xmmsv_coll_new (xmmsv_coll_get_type (orig_coll)); list = xmmsv_coll_idlist_get (orig_coll); x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL); while (xmmsv_list_iter_valid (it)) { xmmsv_list_iter_entry (it, &v); xmmsv_get_int (v, &i); xmmsv_coll_idlist_append (new_coll, i); xmmsv_list_iter_next (it); } xmmsv_list_iter_explicit_destroy (it); list = xmmsv_coll_operands_get (orig_coll); x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL); while (xmmsv_list_iter_valid (it)) { xmmsv_list_iter_entry (it, &v); xmmsv_get_coll (v, &coll_elem); xmmsv_coll_add_operand (new_coll, xmmsv_coll_copy (coll_elem)); xmmsv_list_iter_next (it); } xmmsv_list_iter_explicit_destroy (it); dict = xmmsv_coll_attributes_get (orig_coll); x_return_val_if_fail (xmmsv_get_dict_iter (dict, &itd), NULL); while (xmmsv_dict_iter_valid (itd)) { xmmsv_dict_iter_pair (itd, &key, &v); xmmsv_get_string (v, &s); xmmsv_coll_attribute_set (new_coll, key, s); xmmsv_dict_iter_next (itd); } xmmsv_dict_iter_explicit_destroy (itd); return new_coll; }
xmmsv_t * duplicate_dict_value (xmmsv_t *val) { xmmsv_t *dup_val; xmmsv_dict_iter_t *it; const char *key; xmmsv_t *v; xmmsv_t *new_elem; x_return_val_if_fail (xmmsv_get_dict_iter (val, &it), NULL); dup_val = xmmsv_new_dict (); while (xmmsv_dict_iter_pair (it, &key, &v)) { new_elem = xmmsv_copy (v); xmmsv_dict_set (dup_val, key, new_elem); xmmsv_unref (new_elem); xmmsv_dict_iter_next (it); } xmmsv_dict_iter_explicit_destroy (it); return dup_val; }
/** * Encodes an url with arguments stored in dict args. * * The encoded url is allocated using malloc and has to be freed by the user. * * @param url The url to encode. * @param args The dict with arguments, or NULL. * @return The encoded url */ char * xmmsc_medialib_encode_url_full (const char *url, xmmsv_t *args) { static const char hex[16] = "0123456789abcdef"; int i = 0, j = 0, extra = 0, l; char *res; xmmsv_dict_iter_t *it; x_api_error_if (!url, "with a NULL url", NULL); if (args) { if (!xmmsv_dict_foreach (args, _sum_len_string_dict, (void *) &extra)) { return NULL; } } /* Provide enough room for the worst-case scenario (all characters of the URL must be encoded), the args, and a \0. */ res = malloc (strlen (url) * 3 + 1 + extra); if (!res) { return NULL; } for (i = 0; url[i]; i++) { unsigned char chr = url[i]; if (GOODCHAR (chr)) { res[j++] = chr; } else if (chr == ' ') { res[j++] = '+'; } else { res[j++] = '%'; res[j++] = hex[((chr & 0xf0) >> 4)]; res[j++] = hex[(chr & 0x0f)]; } } if (args) { for (xmmsv_get_dict_iter (args, &it), i = 0; xmmsv_dict_iter_valid (it); xmmsv_dict_iter_next (it), i++) { const char *arg, *key; xmmsv_t *val; xmmsv_dict_iter_pair (it, &key, &val); l = strlen (key); res[j] = (i == 0) ? '?' : '&'; j++; memcpy (&res[j], key, l); j += l; if (xmmsv_get_string (val, &arg)) { l = strlen (arg); res[j] = '='; j++; memcpy (&res[j], arg, l); j += l; } } } res[j] = '\0'; return res; }
/** * This function will make a pretty string about the information in * xmmsv dict. * * @param target A allocated char * * @param len Length of target * @param fmt A format string to use. You can insert items from the dict by * using specialformat "${field}". * @param val The #xmmsv_t that contains the dict. * * @returns The number of chars written to target */ int xmmsv_dict_format (char *target, int len, const char *fmt, xmmsv_t *val) { const char *pos; if (!target) { return 0; } if (!fmt) { return 0; } memset (target, 0, len); pos = fmt; while (strlen (target) + 1 < len) { char *next_key, *key, *end; int keylen; xmmsv_dict_iter_t *it; xmmsv_t *v; next_key = strstr (pos, "${"); if (!next_key) { strncat (target, pos, len - strlen (target) - 1); break; } strncat (target, pos, MIN (next_key - pos, len - strlen (target) - 1)); keylen = strcspn (next_key + 2, "}"); key = malloc (keylen + 1); if (!key) { fprintf (stderr, "Unable to allocate %u bytes of memory, OOM?", keylen); break; } memset (key, 0, keylen + 1); strncpy (key, next_key + 2, keylen); xmmsv_get_dict_iter (val, &it); if (strcmp (key, "seconds") == 0) { int64_t duration; if (xmmsv_dict_iter_find (it, "duration")) { xmmsv_dict_iter_pair (it, NULL, &v); xmmsv_get_int (v, &duration); } else { duration = 0; } if (!duration) { strncat (target, "00", len - strlen (target) - 1); } else { char seconds[21]; /* rounding */ duration += 500; snprintf (seconds, sizeof (seconds), "%02" PRId64, (duration/1000)%60); strncat (target, seconds, len - strlen (target) - 1); } } else if (strcmp (key, "minutes") == 0) { int64_t duration; if (xmmsv_dict_iter_find (it, "duration")) { xmmsv_dict_iter_pair (it, NULL, &v); xmmsv_get_int (v, &duration); } else { duration = 0; } if (!duration) { strncat (target, "00", len - strlen (target) - 1); } else { char minutes[21]; /* rounding */ duration += 500; snprintf (minutes, sizeof (minutes), "%02" PRId64, duration/60000); strncat (target, minutes, len - strlen (target) - 1); } } else { const char *result = NULL; char tmp[21]; if (xmmsv_dict_iter_find (it, key)) { xmmsv_dict_iter_pair (it, NULL, &v); xmmsv_type_t type = xmmsv_get_type (v); if (type == XMMSV_TYPE_STRING) { xmmsv_get_string (v, &result); } else if (type == XMMSV_TYPE_INT64) { int64_t i; xmmsv_get_int (v, &i); snprintf (tmp, 21, "%" PRId64, i); result = tmp; } else if (type == XMMSV_TYPE_FLOAT) { float f; xmmsv_get_float (v, &f); snprintf (tmp, 12, "%.6f", f); result = tmp; } } if (result) strncat (target, result, len - strlen (target) - 1); } free (key); end = strchr (next_key, '}'); if (!end) { break; } pos = end + 1; } return strlen (target); }
/** * TODO: Should check for '/' in the key, and set source if found. */ static void populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content) { xmms_medialib_session_t *session; xmms_medialib_entry_t entry = 0; xmmsv_list_iter_t *lit; session = xmms_medialib_session_begin (medialib); xmmsv_get_list_iter (content, &lit); while (xmmsv_list_iter_valid (lit)) { xmmsv_dict_iter_t *dit; xmms_error_t err; xmmsv_t *dict; xmms_error_reset (&err); xmmsv_list_iter_entry (lit, &dict); if (xmmsv_dict_has_key (dict, "url")) { const gchar *url; xmmsv_dict_entry_get_string (dict, "url", &url); entry = xmms_medialib_entry_new (session, url, &err); } else { gchar *url; url = g_strdup_printf ("file://%d.mp3", entry + 1); entry = xmms_medialib_entry_new (session, url, &err); g_free (url); } xmmsv_get_dict_iter (dict, &dit); while (xmmsv_dict_iter_valid (dit)) { const gchar *key, *source; gchar **parts; xmmsv_t *container; xmmsv_dict_iter_pair (dit, &key, &container); parts = g_strsplit (key, "/", 2); key = (parts[1] != NULL) ? parts[1] : key; source = (parts[1] != NULL) ? parts[0] : NULL; if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) { const gchar *value; xmmsv_get_string (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_str_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_str (session, entry, key, value); } } else { gint32 value; xmmsv_get_int (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_int_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_int (session, entry, key, value); } } g_strfreev (parts); xmmsv_dict_iter_next (dit); } xmmsv_list_iter_next (lit); } xmms_medialib_session_commit (session); }
static bool _internal_get_from_bb_collection_alloc (xmmsv_t *bb, xmmsv_coll_t **coll) { int i; int32_t type; int32_t n_items; int id; int32_t *idlist = NULL; xmmsv_t *dict, *attrs; xmmsv_dict_iter_t *it; /* Get the type and create the collection */ if (!_internal_get_from_bb_int32_positive (bb, &type)) { return false; } *coll = xmmsv_coll_new (type); /* Get the attributes */ if (!_internal_get_from_bb_value_dict_alloc (bb, &dict)) { return false; } attrs = xmmsv_coll_attributes_get (*coll); xmmsv_get_dict_iter (dict, &it); while (xmmsv_dict_iter_valid (it)) { const char *key; xmmsv_t *value; xmmsv_dict_iter_pair (it, &key, &value); xmmsv_dict_set (attrs, key, value); xmmsv_dict_iter_next (it); } xmmsv_unref (dict); /* Get the idlist */ if (!_internal_get_from_bb_int32_positive (bb, &n_items)) { goto err; } if (!(idlist = x_new (int32_t, n_items + 1))) { goto err; } for (i = 0; i < n_items; i++) { if (!_internal_get_from_bb_int32 (bb, &id)) { goto err; } idlist[i] = id; } idlist[i] = 0; xmmsv_coll_set_idlist (*coll, idlist); free (idlist); idlist = NULL; /* Get the operands */ if (!_internal_get_from_bb_int32_positive (bb, &n_items)) { goto err; } for (i = 0; i < n_items; i++) { xmmsv_coll_t *operand; if (!_internal_get_from_bb_int32_positive (bb, &type) || type != XMMSV_TYPE_COLL || !_internal_get_from_bb_collection_alloc (bb, &operand)) { goto err; } xmmsv_coll_add_operand (*coll, operand); xmmsv_coll_unref (operand); } return true; err: if (idlist != NULL) { free (idlist); } xmmsv_coll_unref (*coll); return false; }