00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <ctype.h>
00021
00022 #include "xmmsc/xmmsc_idnumbers.h"
00023 #include "xmmsc/xmmsv.h"
00024 #include "xmmsc/xmmsv_coll.h"
00025 #include "xmmsc/xmmsc_util.h"
00026 #include "xmmspriv/xmms_list.h"
00027
00028
00029 struct xmmsv_coll_St {
00030
00031
00032 int ref;
00033
00034 xmmsv_coll_type_t type;
00035 xmmsv_t *operands;
00036 xmmsv_t *attributes;
00037 xmmsv_t *idlist;
00038
00039 int32_t *legacy_idlist;
00040 };
00041
00042
00043 static void xmmsv_coll_free (xmmsv_coll_t *coll);
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 xmmsv_coll_t *
00061 xmmsv_coll_ref (xmmsv_coll_t *coll)
00062 {
00063 x_return_val_if_fail (coll, NULL);
00064
00065 coll->ref++;
00066
00067 return coll;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 xmmsv_coll_t*
00078 xmmsv_coll_new (xmmsv_coll_type_t type)
00079 {
00080 xmmsv_coll_t *coll;
00081
00082 x_return_val_if_fail (type <= XMMS_COLLECTION_TYPE_LAST, NULL);
00083
00084 coll = x_new0 (xmmsv_coll_t, 1);
00085 if (!coll) {
00086 x_oom ();
00087 return NULL;
00088 }
00089
00090 coll->ref = 0;
00091 coll->type = type;
00092
00093 coll->idlist = xmmsv_new_list ();
00094 xmmsv_list_restrict_type (coll->idlist, XMMSV_TYPE_INT32);
00095
00096 coll->operands = xmmsv_new_list ();
00097 xmmsv_list_restrict_type (coll->operands, XMMSV_TYPE_COLL);
00098
00099 coll->attributes = xmmsv_new_dict ();
00100
00101 coll->legacy_idlist = NULL;
00102
00103
00104 xmmsv_coll_ref (coll);
00105
00106 return coll;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 static void
00117 xmmsv_coll_free (xmmsv_coll_t *coll)
00118 {
00119 x_return_if_fail (coll);
00120
00121
00122 xmmsv_unref (coll->operands);
00123 xmmsv_unref (coll->attributes);
00124 xmmsv_unref (coll->idlist);
00125 if (coll->legacy_idlist) {
00126 free (coll->legacy_idlist);
00127 }
00128
00129 free (coll);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 void
00140 xmmsv_coll_unref (xmmsv_coll_t *coll)
00141 {
00142 x_return_if_fail (coll);
00143 x_api_error_if (coll->ref < 1, "with a freed collection",);
00144
00145 coll->ref--;
00146 if (coll->ref == 0) {
00147 xmmsv_coll_free (coll);
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void
00161 xmmsv_coll_set_idlist (xmmsv_coll_t *coll, int ids[])
00162 {
00163 unsigned int i;
00164
00165 xmmsv_list_clear (coll->idlist);
00166 for (i = 0; ids[i]; i++) {
00167 xmmsv_list_append_int (coll->idlist, ids[i]);
00168 }
00169 }
00170
00171 static int
00172 _xmmsv_coll_operand_find (xmmsv_list_iter_t *it, xmmsv_coll_t *op)
00173 {
00174 xmmsv_coll_t *c;
00175 xmmsv_t *v;
00176
00177 while (xmmsv_list_iter_valid (it)) {
00178 xmmsv_list_iter_entry (it, &v);
00179 if (xmmsv_get_coll (v, &c)) {
00180 if (c == op) {
00181 return 1;
00182 }
00183 }
00184 xmmsv_list_iter_next (it);
00185 }
00186 return 0;
00187 }
00188
00189
00190
00191
00192
00193
00194 void
00195 xmmsv_coll_add_operand (xmmsv_coll_t *coll, xmmsv_coll_t *op)
00196 {
00197 xmmsv_list_iter_t *it;
00198 xmmsv_t *v;
00199 x_return_if_fail (coll);
00200 x_return_if_fail (op);
00201
00202
00203 if (!xmmsv_get_list_iter (coll->operands, &it))
00204 return;
00205
00206 if (_xmmsv_coll_operand_find (it, op)) {
00207 x_api_warning ("with an operand already in operand list");
00208 xmmsv_list_iter_explicit_destroy (it);
00209 return;
00210 }
00211
00212 xmmsv_list_iter_explicit_destroy (it);
00213
00214 v = xmmsv_new_coll (op);
00215 x_return_if_fail (v);
00216 xmmsv_list_append (coll->operands, v);
00217 xmmsv_unref (v);
00218 }
00219
00220
00221
00222
00223
00224
00225 void
00226 xmmsv_coll_remove_operand (xmmsv_coll_t *coll, xmmsv_coll_t *op)
00227 {
00228 xmmsv_list_iter_t *it;
00229
00230 x_return_if_fail (coll);
00231 x_return_if_fail (op);
00232
00233 if (!xmmsv_get_list_iter (coll->operands, &it))
00234 return;
00235
00236 if (_xmmsv_coll_operand_find (it, op)) {
00237 xmmsv_list_iter_remove (it);
00238 } else {
00239 x_api_warning ("with an operand not in operand list");
00240 }
00241 xmmsv_list_iter_explicit_destroy (it);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 int
00252 xmmsv_coll_idlist_append (xmmsv_coll_t *coll, int id)
00253 {
00254 x_return_val_if_fail (coll, 0);
00255
00256 return xmmsv_list_append_int (coll->idlist, id);
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266 int
00267 xmmsv_coll_idlist_insert (xmmsv_coll_t *coll, int index, int id)
00268 {
00269 x_return_val_if_fail (coll, 0);
00270
00271 return xmmsv_list_insert_int (coll->idlist, index, id);
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 int
00282 xmmsv_coll_idlist_move (xmmsv_coll_t *coll, int index, int newindex)
00283 {
00284 x_return_val_if_fail (coll, 0);
00285
00286 return xmmsv_list_move (coll->idlist, index, newindex);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 int
00296 xmmsv_coll_idlist_remove (xmmsv_coll_t *coll, int index)
00297 {
00298 x_return_val_if_fail (coll, 0);
00299
00300 return xmmsv_list_remove (coll->idlist, index);
00301 }
00302
00303
00304
00305
00306
00307
00308 int
00309 xmmsv_coll_idlist_clear (xmmsv_coll_t *coll)
00310 {
00311 x_return_val_if_fail (coll, 0);
00312
00313 return xmmsv_list_clear (coll->idlist);
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 int
00324 xmmsv_coll_idlist_get_index (xmmsv_coll_t *coll, int index, int32_t *val)
00325 {
00326 x_return_val_if_fail (coll, 0);
00327
00328 return xmmsv_list_get_int (coll->idlist, index, val);
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338 int
00339 xmmsv_coll_idlist_set_index (xmmsv_coll_t *coll, int index, int32_t val)
00340 {
00341 x_return_val_if_fail (coll, 0);
00342
00343 return xmmsv_list_set_int (coll->idlist, index, val);
00344 }
00345
00346
00347
00348
00349
00350
00351 size_t
00352 xmmsv_coll_idlist_get_size (xmmsv_coll_t *coll)
00353 {
00354 x_return_val_if_fail (coll, 0);
00355
00356 return xmmsv_list_get_size (coll->idlist);
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 xmmsv_coll_type_t
00367 xmmsv_coll_get_type (xmmsv_coll_t *coll)
00368 {
00369 x_return_val_if_fail (coll, -1);
00370
00371 return coll->type;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 const int32_t*
00390 xmmsv_coll_get_idlist (xmmsv_coll_t *coll)
00391 {
00392 xmmsv_list_iter_t *it;
00393 unsigned int i;
00394 int32_t entry;
00395
00396 x_return_null_if_fail (coll);
00397
00398
00399 if (coll->legacy_idlist) {
00400 free (coll->legacy_idlist);
00401 }
00402 coll->legacy_idlist = calloc (xmmsv_coll_idlist_get_size (coll) + 1,
00403 sizeof (int32_t));
00404
00405
00406 for (xmmsv_get_list_iter (coll->idlist, &it), i = 0;
00407 xmmsv_list_iter_valid (it);
00408 xmmsv_list_iter_next (it), i++) {
00409 xmmsv_list_iter_entry_int (it, &entry);
00410 coll->legacy_idlist[i] = entry;
00411 }
00412 coll->legacy_idlist[i] = 0;
00413
00414 return coll->legacy_idlist;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 xmmsv_t *
00429 xmmsv_coll_idlist_get (xmmsv_coll_t *coll)
00430 {
00431 x_return_null_if_fail (coll);
00432
00433 return coll->idlist;
00434 }
00435
00436 xmmsv_t *
00437 xmmsv_coll_operands_get (xmmsv_coll_t *coll)
00438 {
00439 x_return_val_if_fail (coll, NULL);
00440
00441 return coll->operands;
00442 }
00443
00444 xmmsv_t *
00445 xmmsv_coll_attributes_get (xmmsv_coll_t *coll)
00446 {
00447 x_return_val_if_fail (coll, NULL);
00448
00449 return coll->attributes;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459 void
00460 xmmsv_coll_attribute_set (xmmsv_coll_t *coll, const char *key, const char *value)
00461 {
00462 xmmsv_t *v;
00463
00464 v = xmmsv_new_string (value);
00465 x_return_if_fail (v);
00466
00467 xmmsv_dict_set (coll->attributes, key, v);
00468 xmmsv_unref (v);
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 int
00481 xmmsv_coll_attribute_remove (xmmsv_coll_t *coll, const char *key)
00482 {
00483 return xmmsv_dict_remove (coll->attributes, key);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 int
00498 xmmsv_coll_attribute_get (xmmsv_coll_t *coll, const char *key, char **value)
00499 {
00500 if (xmmsv_dict_entry_get_string (coll->attributes, key, value)) {
00501 return 1;
00502 }
00503 *value = NULL;
00504 return 0;
00505 }
00506
00507
00508
00509 struct attr_fe_data {
00510 xmmsv_coll_attribute_foreach_func func;
00511 void *userdata;
00512 };
00513
00514 static void
00515 attr_fe_func (const char *key, xmmsv_t *val, void *user_data)
00516 {
00517 struct attr_fe_data *d = user_data;
00518 const char *v;
00519 int r;
00520
00521 r = xmmsv_get_string (val, &v);
00522 x_return_if_fail (r)
00523
00524 d->func (key, v, d->userdata);
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 void
00538 xmmsv_coll_attribute_foreach (xmmsv_coll_t *coll,
00539 xmmsv_coll_attribute_foreach_func func,
00540 void *user_data)
00541 {
00542 struct attr_fe_data d = {func, user_data};
00543 xmmsv_dict_foreach (coll->attributes, attr_fe_func, &d);
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 xmmsv_coll_t*
00555 xmmsv_coll_universe ()
00556 {
00557 xmmsv_coll_t *univ = xmmsv_coll_new (XMMS_COLLECTION_TYPE_REFERENCE);
00558 xmmsv_coll_attribute_set (univ, "reference", "All Media");
00559
00560
00561 return univ;
00562 }
00563
00564