int xmmsv_coll_compare (xmmsv_t *a, xmmsv_t *b) { xmmsv_coll_type_t type; xmmsv_t *_a, *_b; type = xmmsv_coll_get_type (a); if (xmmsv_coll_get_type (b) != type) { return 0; } _a = xmmsv_coll_idlist_get (a); _b = xmmsv_coll_idlist_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } _a = xmmsv_coll_attributes_get (a); _b = xmmsv_coll_attributes_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } _a = xmmsv_coll_operands_get (a); _b = xmmsv_coll_operands_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } return 1; }
static VALUE c_attrs_each_value (VALUE self) { RbCollection *coll = NULL; xmmsv_t *attributes; VALUE tmp; tmp = rb_iv_get (self, "collection"); Data_Get_Struct (tmp, RbCollection, coll); attributes = xmmsv_coll_attributes_get (coll->real); xmmsv_dict_foreach (attributes, attr_each, XINT_TO_POINTER (EACH_VALUE)); return self; }
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; }
static void _xmms_coll_dump (xmmsv_t *coll, int indent) { xmmsv_t *attributes, *operands, *idlist; const char *type_str; printf ("/* collection */ {\n"); type_str = collection_type_string (xmmsv_coll_get_type (coll)); _xmmsv_coll_dump_indent (indent + 1); printf ("'type': '%s'", type_str); attributes = xmmsv_coll_attributes_get (coll); if (xmmsv_dict_get_size (attributes)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'attributes': "); xmmsv_dump_indented (attributes, indent + 1); } operands = xmmsv_coll_operands_get (coll); if (xmmsv_list_get_size (operands)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'operands': "); xmmsv_dump_indented (operands, indent + 1); } idlist = xmmsv_coll_idlist_get (coll); if (xmmsv_list_get_size (idlist)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'idlist': "); xmmsv_dump_indented (idlist, indent + 1); } printf ("\n"); _xmmsv_coll_dump_indent (indent); printf ("}"); }
static xmmsv_t * duplicate_coll_value (xmmsv_t *val) { xmmsv_t *dup_val, *attributes, *operands, *idlist, *copy; dup_val = xmmsv_new_coll (xmmsv_coll_get_type (val)); attributes = xmmsv_coll_attributes_get (val); copy = xmmsv_copy (attributes); xmmsv_coll_attributes_set (dup_val, copy); xmmsv_unref (copy); operands = xmmsv_coll_operands_get (val); copy = xmmsv_copy (operands); xmmsv_coll_operands_set (dup_val, copy); xmmsv_unref (copy); idlist = xmmsv_coll_idlist_get (val); copy = xmmsv_copy (idlist); xmmsv_coll_idlist_set (dup_val, copy); xmmsv_unref (copy); return dup_val; }
static bool _internal_put_on_bb_collection (xmmsv_t *bb, xmmsv_coll_t *coll) { xmmsv_list_iter_t *it; xmmsv_t *v, *attrs; int n; uint32_t ret; int32_t entry; xmmsv_coll_t *op; if (!bb || !coll) { return false; } /* push type */ if (!xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_get_type (coll))) return false; /* attribute counter and values */ attrs = xmmsv_coll_attributes_get (coll); n = 0; xmmsv_dict_foreach (attrs, _internal_put_on_bb_count_coll_attr, &n); if (!xmmsv_bitbuffer_put_bits (bb, 32, n)) return false; /* needs error checking! */ xmmsv_dict_foreach (attrs, _internal_put_on_bb_append_coll_attr, bb); attrs = NULL; /* no unref needed. */ /* idlist counter and content */ xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_idlist_get_size (coll)); xmmsv_get_list_iter (xmmsv_coll_idlist_get (coll), &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { if (!xmmsv_list_iter_entry_int (it, &entry)) { x_api_error ("Non integer in idlist", 0); } xmmsv_bitbuffer_put_bits (bb, 32, entry); } xmmsv_list_iter_explicit_destroy (it); /* operands counter and objects */ n = 0; if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) { n = xmmsv_list_get_size (xmmsv_coll_operands_get (coll)); } ret = xmmsv_bitbuffer_pos (bb); xmmsv_bitbuffer_put_bits (bb, 32, n); if (n > 0) { xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &it); while (xmmsv_list_iter_entry (it, &v)) { if (!xmmsv_get_coll (v, &op)) { x_api_error ("Non collection operand", 0); } _internal_put_on_bb_int32 (bb, XMMSV_TYPE_COLL); ret = _internal_put_on_bb_collection (bb, op); xmmsv_list_iter_next (it); } } return ret; }
/** Write the given operator to the database under the given id. * * @param session The medialib session connected to the DB. * @param collid The id under which to save the collection. * @param coll The structure of the collection to save. * @return The next free collection id. */ static guint xmms_collection_dbwrite_operator (xmms_medialib_session_t *session, guint collid, xmmsv_coll_t *coll) { gchar query[128]; guint *idlist; gint i; xmmsv_coll_t *op; xmmsv_t *attrs; gint newid, nextid; coll_dbwrite_t dbwrite_infos = { session, collid, 0 }; /* Write operator */ g_snprintf (query, sizeof (query), "INSERT INTO CollectionOperators VALUES(%d, %d)", collid, xmmsv_coll_get_type (coll)); xmms_medialib_select (session, query, NULL); /* Write attributes */ attrs = xmmsv_coll_attributes_get (coll); xmmsv_dict_foreach (attrs, dbwrite_coll_attributes, &dbwrite_infos); attrs = NULL; /* no unref needed. */ /* Write idlist */ idlist = xmmsv_coll_get_idlist (coll); for (i = 0; idlist[i] != 0; i++) { g_snprintf (query, sizeof (query), "INSERT INTO CollectionIdlists VALUES(%d, %d, %d)", collid, i, idlist[i]); xmms_medialib_select (session, query, NULL); } /* Save operands and connections (don't recurse in ref operand) */ newid = collid + 1; if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) { xmmsv_t *tmp; xmmsv_list_iter_t *iter; xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &iter); for (xmmsv_list_iter_first (iter); xmmsv_list_iter_valid (iter); xmmsv_list_iter_next (iter)) { xmmsv_list_iter_entry (iter, &tmp); xmmsv_get_coll (tmp, &op); nextid = xmms_collection_dbwrite_operator (session, newid, op); g_snprintf (query, sizeof (query), "INSERT INTO CollectionConnections VALUES(%d, %d)", newid, collid); xmms_medialib_select (session, query, NULL); newid = nextid; } xmmsv_list_iter_explicit_destroy (iter); } /* return next available id */ return newid; }
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; }