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