XMMS2
coll.c
Go to the documentation of this file.
1/* XMMS2 - X Music Multiplexer System
2 * Copyright (C) 2003-2011 XMMS2 Team
3 *
4 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <ctype.h>
21
23#include "xmmsc/xmmsv.h"
24#include "xmmsc/xmmsv_coll.h"
25#include "xmmsc/xmmsc_util.h"
26#include "xmmspriv/xmms_list.h"
27
28
29struct xmmsv_coll_St {
30
31 /* refcounting */
32 int ref;
33
35 xmmsv_t *operands;
36 xmmsv_t *attributes;
37 xmmsv_t *idlist;
38
39 int32_t *legacy_idlist;
40};
41
42
43static void xmmsv_coll_free (xmmsv_coll_t *coll);
44
45
46/**
47 * @defgroup CollectionStructure CollectionStructure
48 * @ingroup Collections
49 * @brief The API to be used to work with collection structures.
50 *
51 * @{
52 */
53
54/**
55 * Increases the references for the #xmmsv_coll_t
56 *
57 * @param coll the collection to reference.
58 * @return coll
59 */
62{
63 x_return_val_if_fail (coll, NULL);
64
65 coll->ref++;
66
67 return coll;
68}
69
70/**
71 * Allocate a new collection of the given type.
72 * The pointer will have to be deallocated using #xmmsv_coll_unref.
73 *
74 * @param type the #xmmsv_coll_type_t specifying the type of collection to create.
75 * @return a pointer to the newly created collection, or NULL if the type is invalid.
76 */
79{
80 xmmsv_coll_t *coll;
81
83
84 coll = x_new0 (xmmsv_coll_t, 1);
85 if (!coll) {
86 x_oom ();
87 return NULL;
88 }
89
90 coll->ref = 0;
91 coll->type = type;
92
93 coll->idlist = xmmsv_new_list ();
95
96 coll->operands = xmmsv_new_list ();
98
99 coll->attributes = xmmsv_new_dict ();
100
101 coll->legacy_idlist = NULL;
102
103 /* user must give this back */
104 xmmsv_coll_ref (coll);
105
106 return coll;
107}
108
109/**
110 * Free the memory owned by the collection.
111 * You probably want to use #xmmsv_coll_unref instead, which handles
112 * reference counting.
113 *
114 * @param coll the collection to free.
115 */
116static void
117xmmsv_coll_free (xmmsv_coll_t *coll)
118{
119 x_return_if_fail (coll);
120
121 /* Unref all the operands and attributes */
122 xmmsv_unref (coll->operands);
123 xmmsv_unref (coll->attributes);
124 xmmsv_unref (coll->idlist);
125 if (coll->legacy_idlist) {
126 free (coll->legacy_idlist);
127 }
128
129 free (coll);
130}
131
132/**
133 * Decreases the references for the #xmmsv_coll_t
134 * When the number of references reaches 0 it will
135 * be freed and all its operands unreferenced as well.
136 *
137 * @param coll the collection to unref.
138 */
139void
141{
142 x_return_if_fail (coll);
143 x_api_error_if (coll->ref < 1, "with a freed collection",);
144
145 coll->ref--;
146 if (coll->ref == 0) {
147 xmmsv_coll_free (coll);
148 }
149}
150
151
152/**
153 * Set the list of ids in the given collection.
154 * The list must be 0-terminated.
155 * Note that the idlist is only relevant for idlist collections.
156 *
157 * @param coll the collection to modify.
158 * @param ids the 0-terminated list of ids to store in the collection.
159 */
160void
162{
163 unsigned int i;
164
165 xmmsv_list_clear (coll->idlist);
166 for (i = 0; ids[i]; i++) {
167 xmmsv_list_append_int (coll->idlist, ids[i]);
168 }
169}
170
171static int
172_xmmsv_coll_operand_find (xmmsv_list_iter_t *it, xmmsv_coll_t *op)
173{
174 xmmsv_coll_t *c;
175 xmmsv_t *v;
176
177 while (xmmsv_list_iter_valid (it)) {
178 xmmsv_list_iter_entry (it, &v);
179 if (xmmsv_get_coll (v, &c)) {
180 if (c == op) {
181 return 1;
182 }
183 }
185 }
186 return 0;
187}
188
189/**
190 * Add the operand to the given collection.
191 * @param coll The collection to add the operand to.
192 * @param op The operand to add.
193 */
194void
196{
198 xmmsv_t *v;
199 x_return_if_fail (coll);
200 x_return_if_fail (op);
201
202 /* we used to check if it already existed here before */
203 if (!xmmsv_get_list_iter (coll->operands, &it))
204 return;
205
206 if (_xmmsv_coll_operand_find (it, op)) {
207 x_api_warning ("with an operand already in operand list");
209 return;
210 }
211
213
214 v = xmmsv_new_coll (op);
216 xmmsv_list_append (coll->operands, v);
217 xmmsv_unref (v);
218}
219
220/**
221 * Remove all the occurences of the operand in the given collection.
222 * @param coll The collection to remove the operand from.
223 * @param op The operand to remove.
224 */
225void
227{
229
230 x_return_if_fail (coll);
231 x_return_if_fail (op);
232
233 if (!xmmsv_get_list_iter (coll->operands, &it))
234 return;
235
236 if (_xmmsv_coll_operand_find (it, op)) {
238 } else {
239 x_api_warning ("with an operand not in operand list");
240 }
242}
243
244
245/**
246 * Append a value to the idlist.
247 * @param coll The collection to update.
248 * @param id The id to append to the idlist.
249 * @return TRUE on success, false otherwise.
250 */
251int
253{
254 x_return_val_if_fail (coll, 0);
255
256 return xmmsv_list_append_int (coll->idlist, id);
257}
258
259/**
260 * Insert a value at a given position in the idlist.
261 * @param coll The collection to update.
262 * @param id The id to insert in the idlist.
263 * @param index The position at which to insert the value.
264 * @return TRUE on success, false otherwise.
265 */
266int
267xmmsv_coll_idlist_insert (xmmsv_coll_t *coll, int index, int id)
268{
269 x_return_val_if_fail (coll, 0);
270
271 return xmmsv_list_insert_int (coll->idlist, index, id);
272}
273
274/**
275 * Move a value of the idlist to a new position.
276 * @param coll The collection to update.
277 * @param index The index of the value to move.
278 * @param newindex The newindex to which to move the value.
279 * @return TRUE on success, false otherwise.
280 */
281int
282xmmsv_coll_idlist_move (xmmsv_coll_t *coll, int index, int newindex)
283{
284 x_return_val_if_fail (coll, 0);
285
286 return xmmsv_list_move (coll->idlist, index, newindex);
287}
288
289/**
290 * Remove the value at a given index from the idlist.
291 * @param coll The collection to update.
292 * @param index The index at which to remove the value.
293 * @return TRUE on success, false otherwise.
294 */
295int
297{
298 x_return_val_if_fail (coll, 0);
299
300 return xmmsv_list_remove (coll->idlist, index);
301}
302
303/**
304 * Empties the idlist.
305 * @param coll The collection to update.
306 * @return TRUE on success, false otherwise.
307 */
308int
310{
311 x_return_val_if_fail (coll, 0);
312
313 return xmmsv_list_clear (coll->idlist);
314}
315
316/**
317 * Retrieves the value at the given position in the idlist.
318 * @param coll The collection to update.
319 * @param index The position of the value to retrieve.
320 * @param val The pointer at which to store the found value.
321 * @return TRUE on success, false otherwise.
322 */
323int
324xmmsv_coll_idlist_get_index (xmmsv_coll_t *coll, int index, int32_t *val)
325{
326 x_return_val_if_fail (coll, 0);
327
328 return xmmsv_list_get_int (coll->idlist, index, val);
329}
330
331/**
332 * Sets the value at the given position in the idlist.
333 * @param coll The collection to update.
334 * @param index The position of the value to set.
335 * @param val The new value.
336 * @return TRUE on success, false otherwise.
337 */
338int
339xmmsv_coll_idlist_set_index (xmmsv_coll_t *coll, int index, int32_t val)
340{
341 x_return_val_if_fail (coll, 0);
342
343 return xmmsv_list_set_int (coll->idlist, index, val);
344}
345
346/**
347 * Get the size of the idlist.
348 * @param coll The collection to update.
349 * @return The size of the idlist.
350 */
351size_t
353{
354 x_return_val_if_fail (coll, 0);
355
356 return xmmsv_list_get_size (coll->idlist);
357}
358
359
360
361/**
362 * Return the type of the collection.
363 * @param coll The collection to consider.
364 * @return The #xmmsv_coll_type_t of the collection, or -1 if invalid.
365 */
368{
369 x_return_val_if_fail (coll, -1);
370
371 return coll->type;
372}
373
374/**
375 * Return the list of ids stored in the collection.
376 * The list is owned by the collection.
377 * Note that this must not be confused with the content of the
378 * collection, which must be queried using xmmsc_coll_query_ids!
379 *
380 * Also note that this function is deprecated (use xmmsv_coll_idlist_get
381 * instead) and that changes to the returned array will be ignored. The array
382 * is also not updated when the idlist is changed using the supplied functions.
383 * Additionally every call to this function allocates a new array, so calling
384 * it repetitively will be a performance penalty.
385 *
386 * @param coll The collection to consider.
387 * @return The 0-terminated list of ids.
388 */
389const int32_t*
391{
393 unsigned int i;
394 int32_t entry;
395
397
398 /* free and allocate a new legacy list */
399 if (coll->legacy_idlist) {
400 free (coll->legacy_idlist);
401 }
402 coll->legacy_idlist = calloc (xmmsv_coll_idlist_get_size (coll) + 1,
403 sizeof (int32_t));
404
405 /* copy contents to legacy list */
406 for (xmmsv_get_list_iter (coll->idlist, &it), i = 0;
408 xmmsv_list_iter_next (it), i++) {
409 xmmsv_list_iter_entry_int (it, &entry);
410 coll->legacy_idlist[i] = entry;
411 }
412 coll->legacy_idlist[i] = 0;
413
414 return coll->legacy_idlist;
415}
416
417/**
418 * Return the list of ids stored in the collection.
419 * This function does not increase the refcount of the list, the reference is
420 * still owned by the collection.
421 *
422 * Note that this must not be confused with the content of the collection,
423 * which must be queried using xmmsc_coll_query_ids!
424 *
425 * @param coll The collection to consider.
426 * @return The 0-terminated list of ids.
427 */
428xmmsv_t *
430{
432
433 return coll->idlist;
434}
435
436xmmsv_t *
438{
439 x_return_val_if_fail (coll, NULL);
440
441 return coll->operands;
442}
443
444xmmsv_t *
446{
447 x_return_val_if_fail (coll, NULL);
448
449 return coll->attributes;
450}
451
452/**
453 * Set an attribute in the given collection.
454 *
455 * @param coll The collection in which to set the attribute.
456 * @param key The name of the attribute to set.
457 * @param value The value of the attribute.
458 */
459void
460xmmsv_coll_attribute_set (xmmsv_coll_t *coll, const char *key, const char *value)
461{
462 xmmsv_t *v;
463
464 v = xmmsv_new_string (value);
466
467 xmmsv_dict_set (coll->attributes, key, v);
468 xmmsv_unref (v);
469}
470
471/**
472 * Remove an attribute from the given collection.
473 * The return value indicated whether the attribute was found (and
474 * removed)
475 *
476 * @param coll The collection to remove the attribute from.
477 * @param key The name of the attribute to remove.
478 * @return 1 upon success, 0 otherwise
479 */
480int
482{
483 return xmmsv_dict_remove (coll->attributes, key);
484}
485
486/**
487 * Retrieve the value of the attribute of the given collection.
488 * The return value is 1 if the attribute was found and 0 otherwise.
489 * The value of the attribute is owned by the collection and must not
490 * be freed by the caller.
491 *
492 * @param coll The collection to retrieve the attribute from.
493 * @param key The name of the attribute.
494 * @param value The value of the attribute if found (owned by the collection).
495 * @return 1 if the attribute was found, 0 otherwise
496 */
497int
498xmmsv_coll_attribute_get (xmmsv_coll_t *coll, const char *key, char **value)
499{
500 if (xmmsv_dict_entry_get_string (coll->attributes, key, value)) {
501 return 1;
502 }
503 *value = NULL;
504 return 0;
505}
506
507
508
509struct attr_fe_data {
511 void *userdata;
512};
513
514static void
515attr_fe_func (const char *key, xmmsv_t *val, void *user_data)
516{
517 struct attr_fe_data *d = user_data;
518 const char *v;
519 int r;
520
521 r = xmmsv_get_string (val, &v);
523
524 d->func (key, v, d->userdata);
525}
526/**
527 * Iterate over all key/value-pair of the collection attributes.
528 *
529 * Calls specified function for each key/value-pair of the attribute list.
530 *
531 * void function (const char *key, const char *value, void *user_data);
532 *
533 * @param coll the #xmmsv_coll_t.
534 * @param func function that is called for each key/value-pair
535 * @param user_data extra data passed to func
536 */
537void
540 void *user_data)
541{
542 struct attr_fe_data d = {func, user_data};
543 xmmsv_dict_foreach (coll->attributes, attr_fe_func, &d);
544}
545
546/**
547 * Return a collection referencing the whole media library,
548 * that is a reference to the "All Media" collection.
549 * The returned structure must be unref'd using #xmmsv_coll_unref
550 * after usage.
551 *
552 * @return a collection referring to the "All Media" collection.
553 */
556{
558 xmmsv_coll_attribute_set (univ, "reference", "All Media");
559 /* FIXME: namespace? */
560
561 return univ;
562}
563
564/** @} */
void xmmsv_coll_remove_operand(xmmsv_coll_t *coll, xmmsv_coll_t *op)
Remove all the occurences of the operand in the given collection.
Definition: coll.c:226
xmmsv_t * xmmsv_coll_idlist_get(xmmsv_coll_t *coll)
Return the list of ids stored in the collection.
Definition: coll.c:429
int xmmsv_coll_idlist_remove(xmmsv_coll_t *coll, int index)
Remove the value at a given index from the idlist.
Definition: coll.c:296
int xmmsv_coll_attribute_remove(xmmsv_coll_t *coll, const char *key)
Remove an attribute from the given collection.
Definition: coll.c:481
xmmsv_coll_type_t xmmsv_coll_get_type(xmmsv_coll_t *coll)
Return the type of the collection.
Definition: coll.c:367
const int32_t * xmmsv_coll_get_idlist(xmmsv_coll_t *coll)
Return the list of ids stored in the collection.
Definition: coll.c:390
xmmsv_coll_t * xmmsv_coll_ref(xmmsv_coll_t *coll)
Increases the references for the xmmsv_coll_t.
Definition: coll.c:61
xmmsv_t * xmmsv_coll_operands_get(xmmsv_coll_t *coll)
Definition: coll.c:437
void xmmsv_coll_unref(xmmsv_coll_t *coll)
Decreases the references for the xmmsv_coll_t When the number of references reaches 0 it will be free...
Definition: coll.c:140
int xmmsv_coll_idlist_clear(xmmsv_coll_t *coll)
Empties the idlist.
Definition: coll.c:309
size_t xmmsv_coll_idlist_get_size(xmmsv_coll_t *coll)
Get the size of the idlist.
Definition: coll.c:352
void xmmsv_coll_attribute_set(xmmsv_coll_t *coll, const char *key, const char *value)
Set an attribute in the given collection.
Definition: coll.c:460
void xmmsv_coll_attribute_foreach(xmmsv_coll_t *coll, xmmsv_coll_attribute_foreach_func func, void *user_data)
Iterate over all key/value-pair of the collection attributes.
Definition: coll.c:538
void xmmsv_coll_set_idlist(xmmsv_coll_t *coll, int ids[])
Set the list of ids in the given collection.
Definition: coll.c:161
int xmmsv_coll_idlist_insert(xmmsv_coll_t *coll, int index, int id)
Insert a value at a given position in the idlist.
Definition: coll.c:267
int xmmsv_coll_idlist_get_index(xmmsv_coll_t *coll, int index, int32_t *val)
Retrieves the value at the given position in the idlist.
Definition: coll.c:324
int xmmsv_coll_idlist_append(xmmsv_coll_t *coll, int id)
Append a value to the idlist.
Definition: coll.c:252
int xmmsv_coll_idlist_set_index(xmmsv_coll_t *coll, int index, int32_t val)
Sets the value at the given position in the idlist.
Definition: coll.c:339
xmmsv_t * xmmsv_coll_attributes_get(xmmsv_coll_t *coll)
Definition: coll.c:445
xmmsv_coll_t * xmmsv_coll_new(xmmsv_coll_type_t type)
Allocate a new collection of the given type.
Definition: coll.c:78
void xmmsv_coll_add_operand(xmmsv_coll_t *coll, xmmsv_coll_t *op)
Add the operand to the given collection.
Definition: coll.c:195
int xmmsv_coll_attribute_get(xmmsv_coll_t *coll, const char *key, char **value)
Retrieve the value of the attribute of the given collection.
Definition: coll.c:498
xmmsv_coll_t * xmmsv_coll_universe()
Return a collection referencing the whole media library, that is a reference to the "All Media" colle...
Definition: coll.c:555
int xmmsv_coll_idlist_move(xmmsv_coll_t *coll, int index, int newindex)
Move a value of the idlist to a new position.
Definition: coll.c:282
int xmmsv_dict_foreach(xmmsv_t *dictv, xmmsv_dict_foreach_func func, void *user_data)
Apply a function to each key-element pair in the list.
Definition: value.c:1853
int xmmsv_dict_set(xmmsv_t *dictv, const char *key, xmmsv_t *val)
Insert an element under the given key in the dict xmmsv_t.
Definition: value.c:1752
int xmmsv_dict_entry_get_string(xmmsv_t *val, const char *key, const char **r)
xmmsv_t * xmmsv_new_dict(void)
Allocates a new dict xmmsv_t.
Definition: value.c:268
int xmmsv_dict_remove(xmmsv_t *dictv, const char *key)
Remove the element corresponding to a given key in the dict xmmsv_t (if it exists).
Definition: value.c:1803
int xmmsv_get_list_iter(const xmmsv_t *val, xmmsv_list_iter_t **it)
Retrieves a list iterator from a list xmmsv_t.
Definition: value.c:926
void xmmsv_list_iter_next(xmmsv_list_iter_t *it)
Advance the iterator to the next element in the list.
Definition: value.c:1553
struct xmmsv_list_iter_St xmmsv_list_iter_t
Definition: xmmsv_list.h:69
int xmmsv_list_iter_remove(xmmsv_list_iter_t *it)
Remove the element in the list at the position pointed at by the iterator.
Definition: value.c:1652
int xmmsv_list_iter_entry(xmmsv_list_iter_t *it, xmmsv_t **val)
Get the element currently pointed at by the iterator.
Definition: value.c:1495
void xmmsv_list_iter_explicit_destroy(xmmsv_list_iter_t *it)
Explicitly free list iterator.
Definition: value.c:1478
int xmmsv_list_iter_valid(xmmsv_list_iter_t *it)
Check whether the iterator is valid and points to a valid element.
Definition: value.c:1512
int xmmsv_list_iter_entry_int(xmmsv_list_iter_t *it, int32_t *val)
xmmsv_t * xmmsv_new_list(void)
Allocates a new list xmmsv_t.
Definition: value.c:250
int xmmsv_list_remove(xmmsv_t *listv, int pos)
Remove the element at the given position from the list xmmsv_t.
Definition: value.c:1300
int xmmsv_list_append_int(xmmsv_t *v, int32_t val)
int xmmsv_list_get_int(xmmsv_t *v, int pos, int32_t *val)
int xmmsv_list_restrict_type(xmmsv_t *listv, xmmsv_type_t type)
Definition: value.c:1413
int xmmsv_list_get_size(xmmsv_t *listv)
Return the size of the list.
Definition: value.c:1403
int xmmsv_list_move(xmmsv_t *listv, int old_pos, int new_pos)
Move the element from position #old to position #new.
Definition: value.c:1323
int xmmsv_list_set_int(xmmsv_t *v, int pos, int32_t val)
int xmmsv_list_clear(xmmsv_t *listv)
Empty the list from all its elements.
Definition: value.c:1356
int xmmsv_list_insert_int(xmmsv_t *v, int pos, int32_t val)
int xmmsv_list_append(xmmsv_t *listv, xmmsv_t *val)
Append an element to the end of the list xmmsv_t.
Definition: value.c:1340
void xmmsv_unref(xmmsv_t *val)
Decreases the references for the xmmsv_t When the number of references reaches 0 it will be freed.
Definition: value.c:303
int xmmsv_get_coll(const xmmsv_t *val, xmmsv_coll_t **coll)
Retrieves a collection from the value.
Definition: value.c:883
xmmsv_t * xmmsv_new_string(const char *s)
Allocates a new string xmmsv_t.
Definition: value.c:180
int xmmsv_get_string(const xmmsv_t *val, const char **r)
Retrieves a string from the value.
Definition: value.c:863
struct xmmsv_St xmmsv_t
Definition: xmmsv_general.h:48
xmmsv_t * xmmsv_new_coll(xmmsv_coll_t *coll)
Allocates a new collection xmmsv_t.
Definition: value.c:202
@ XMMSV_TYPE_COLL
Definition: xmmsv_general.h:40
@ XMMSV_TYPE_INT32
Definition: xmmsv_general.h:38
xmmsv_coll_type_t
@ XMMS_COLLECTION_TYPE_REFERENCE
@ XMMS_COLLECTION_TYPE_LAST
#define x_return_null_if_fail(expr)
Definition: xmmsc_util.h:14
#define x_return_val_if_fail(expr, val)
Definition: xmmsc_util.h:13
#define x_return_if_fail(expr)
Definition: xmmsc_util.h:12
#define x_new0(type, num)
Definition: xmmsc_util.h:16
#define x_oom()
Definition: xmmsc_util.h:15
void(* xmmsv_coll_attribute_foreach_func)(const char *key, const char *value, void *udata)
Definition: xmmsv_coll.h:30
struct xmmsv_coll_St xmmsv_coll_t
Definition: xmmsv_coll.h:28