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 <stdarg.h>
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include <assert.h>
00023
00024 #include "xmmsc/xmmsv.h"
00025 #include "xmmsc/xmmsc_idnumbers.h"
00026 #include "xmmsc/xmmsc_errorcodes.h"
00027 #include "xmmsc/xmmsc_stdbool.h"
00028 #include "xmmsc/xmmsc_util.h"
00029 #include "xmmspriv/xmms_list.h"
00030
00031
00032
00033
00034 const char *default_source_pref[] = {
00035 "server",
00036 "client/*",
00037 "plugin/playlist",
00038 "plugin/id3v2",
00039 "plugin/segment",
00040 "plugin/*",
00041 "*",
00042 NULL
00043 };
00044
00045
00046 typedef struct xmmsv_list_St xmmsv_list_t;
00047 typedef struct xmmsv_dict_St xmmsv_dict_t;
00048
00049
00050 typedef struct xmmsv_bin_St {
00051 unsigned char *data;
00052 uint32_t len;
00053 } xmmsv_bin_t;
00054
00055 struct xmmsv_list_St {
00056 xmmsv_t **list;
00057 xmmsv_t *parent_value;
00058 int size;
00059 int allocated;
00060 bool restricted;
00061 xmmsv_type_t restricttype;
00062 x_list_t *iterators;
00063 };
00064
00065 static xmmsv_list_t *xmmsv_list_new (void);
00066 static void xmmsv_list_free (xmmsv_list_t *l);
00067 static int xmmsv_list_resize (xmmsv_list_t *l, int newsize);
00068 static int _xmmsv_list_insert (xmmsv_list_t *l, int pos, xmmsv_t *val);
00069 static int _xmmsv_list_append (xmmsv_list_t *l, xmmsv_t *val);
00070 static int _xmmsv_list_remove (xmmsv_list_t *l, int pos);
00071 static int _xmmsv_list_move (xmmsv_list_t *l, int old_pos, int new_pos);
00072 static void _xmmsv_list_clear (xmmsv_list_t *l);
00073
00074 static xmmsv_dict_t *xmmsv_dict_new (void);
00075 static void xmmsv_dict_free (xmmsv_dict_t *dict);
00076
00077
00078 struct xmmsv_list_iter_St {
00079 xmmsv_list_t *parent;
00080 int position;
00081 };
00082
00083 static xmmsv_list_iter_t *xmmsv_list_iter_new (xmmsv_list_t *l);
00084 static void xmmsv_list_iter_free (xmmsv_list_iter_t *it);
00085
00086
00087 static xmmsv_dict_iter_t *xmmsv_dict_iter_new (xmmsv_dict_t *d);
00088 static void xmmsv_dict_iter_free (xmmsv_dict_iter_t *it);
00089
00090
00091
00092 struct xmmsv_St {
00093 union {
00094 char *error;
00095 int32_t int32;
00096 char *string;
00097 xmmsv_coll_t *coll;
00098 xmmsv_bin_t bin;
00099 xmmsv_list_t *list;
00100 xmmsv_dict_t *dict;
00101
00102 struct {
00103 bool ro;
00104 unsigned char *buf;
00105 int alloclen;
00106 int len;
00107 int pos;
00108 } bit;
00109 } value;
00110 xmmsv_type_t type;
00111
00112 int ref;
00113 };
00114
00115
00116 static xmmsv_t *xmmsv_new (xmmsv_type_t type);
00117 static void xmmsv_free (xmmsv_t *val);
00118 static int absolutify_and_validate_pos (int *pos, int size, int allow_append);
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 xmmsv_t *
00129 xmmsv_new_none (void)
00130 {
00131 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_NONE);
00132 return val;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142 xmmsv_t *
00143 xmmsv_new_error (const char *errstr)
00144 {
00145 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_ERROR);
00146
00147 if (val) {
00148 val->value.error = strdup (errstr);
00149 }
00150
00151 return val;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 xmmsv_t *
00161 xmmsv_new_int (int32_t i)
00162 {
00163 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_INT32);
00164
00165 if (val) {
00166 val->value.int32 = i;
00167 }
00168
00169 return val;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 xmmsv_t *
00180 xmmsv_new_string (const char *s)
00181 {
00182 xmmsv_t *val;
00183
00184 x_return_val_if_fail (s, NULL);
00185 x_return_val_if_fail (xmmsv_utf8_validate (s), NULL);
00186
00187 val = xmmsv_new (XMMSV_TYPE_STRING);
00188 if (val) {
00189 val->value.string = strdup (s);
00190 }
00191
00192 return val;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 xmmsv_t *
00202 xmmsv_new_coll (xmmsv_coll_t *c)
00203 {
00204 xmmsv_t *val;
00205
00206 x_return_val_if_fail (c, NULL);
00207
00208 val = xmmsv_new (XMMSV_TYPE_COLL);
00209 if (val) {
00210 val->value.coll = c;
00211 xmmsv_coll_ref (c);
00212 }
00213
00214 return val;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 xmmsv_t *
00225 xmmsv_new_bin (const unsigned char *data, unsigned int len)
00226 {
00227 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_BIN);
00228
00229 if (val) {
00230
00231 val->value.bin.data = x_malloc (len);
00232 if (!val->value.bin.data) {
00233 free (val);
00234 x_oom ();
00235 return NULL;
00236 }
00237 memcpy (val->value.bin.data, data, len);
00238 val->value.bin.len = len;
00239 }
00240
00241 return val;
00242 }
00243
00244
00245
00246
00247
00248
00249 xmmsv_t *
00250 xmmsv_new_list (void)
00251 {
00252 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_LIST);
00253
00254 if (val) {
00255 val->value.list = xmmsv_list_new ();
00256 val->value.list->parent_value = val;
00257 }
00258
00259 return val;
00260 }
00261
00262
00263
00264
00265
00266
00267 xmmsv_t *
00268 xmmsv_new_dict (void)
00269 {
00270 xmmsv_t *val = xmmsv_new (XMMSV_TYPE_DICT);
00271
00272 if (val) {
00273 val->value.dict = xmmsv_dict_new ();
00274 }
00275
00276 return val;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 xmmsv_t *
00288 xmmsv_ref (xmmsv_t *val)
00289 {
00290 x_return_val_if_fail (val, NULL);
00291 val->ref++;
00292
00293 return val;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 void
00303 xmmsv_unref (xmmsv_t *val)
00304 {
00305 x_return_if_fail (val);
00306 x_api_error_if (val->ref < 1, "with a freed value",);
00307
00308 val->ref--;
00309 if (val->ref == 0) {
00310 xmmsv_free (val);
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319 static xmmsv_t *
00320 xmmsv_new (xmmsv_type_t type)
00321 {
00322 xmmsv_t *val;
00323
00324 val = x_new0 (xmmsv_t, 1);
00325 if (!val) {
00326 x_oom ();
00327 return NULL;
00328 }
00329
00330 val->type = type;
00331
00332 return xmmsv_ref (val);
00333 }
00334
00335
00336
00337
00338
00339 static void
00340 xmmsv_free (xmmsv_t *val)
00341 {
00342 x_return_if_fail (val);
00343
00344 switch (val->type) {
00345 case XMMSV_TYPE_NONE :
00346 case XMMSV_TYPE_END :
00347 case XMMSV_TYPE_INT32 :
00348 break;
00349 case XMMSV_TYPE_ERROR :
00350 free (val->value.error);
00351 val->value.error = NULL;
00352 break;
00353 case XMMSV_TYPE_STRING :
00354 free (val->value.string);
00355 val->value.string = NULL;
00356 break;
00357 case XMMSV_TYPE_COLL:
00358 xmmsv_coll_unref (val->value.coll);
00359 val->value.coll = NULL;
00360 break;
00361 case XMMSV_TYPE_BIN :
00362 free (val->value.bin.data);
00363 val->value.bin.len = 0;
00364 break;
00365 case XMMSV_TYPE_LIST:
00366 xmmsv_list_free (val->value.list);
00367 val->value.list = NULL;
00368 break;
00369 case XMMSV_TYPE_DICT:
00370 xmmsv_dict_free (val->value.dict);
00371 val->value.dict = NULL;
00372 break;
00373 case XMMSV_TYPE_BITBUFFER:
00374 if (!val->value.bit.ro && val->value.bit.buf) {
00375 free (val->value.bit.buf);
00376 }
00377 val->value.bit.buf = NULL;
00378 break;
00379 }
00380
00381 free (val);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391 xmmsv_type_t
00392 xmmsv_get_type (const xmmsv_t *val)
00393 {
00394 x_api_error_if (!val, "NULL value",
00395 XMMSV_TYPE_NONE);
00396
00397 return val->type;
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407 int
00408 xmmsv_is_type (const xmmsv_t *val, xmmsv_type_t t)
00409 {
00410 x_api_error_if (!val, "NULL value", 0);
00411
00412 return (xmmsv_get_type (val) == t);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 int
00425 xmmsv_is_error (const xmmsv_t *val)
00426 {
00427 return xmmsv_is_type (val, XMMSV_TYPE_ERROR);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 int
00437 xmmsv_is_list (const xmmsv_t *val)
00438 {
00439 return xmmsv_is_type (val, XMMSV_TYPE_LIST);
00440 }
00441
00442
00443
00444
00445
00446
00447
00448 int
00449 xmmsv_is_dict (const xmmsv_t *val)
00450 {
00451 return xmmsv_is_type (val, XMMSV_TYPE_DICT);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 const char *
00462 xmmsv_get_error_old (const xmmsv_t *val)
00463 {
00464 if (!val || val->type != XMMSV_TYPE_ERROR) {
00465 return NULL;
00466 }
00467
00468 return val->value.error;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 xmmsv_t *
00483 xmmsv_make_stringlist (char *array[], int num)
00484 {
00485 xmmsv_t *list, *elem;
00486 int i;
00487
00488 list = xmmsv_new_list ();
00489 if (array) {
00490 for (i = 0; (num >= 0 && i < num) || array[i]; i++) {
00491 elem = xmmsv_new_string (array[i]);
00492 xmmsv_list_append (list, elem);
00493 xmmsv_unref (elem);
00494 }
00495 }
00496
00497 return list;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507 xmmsv_type_t
00508 xmmsv_dict_entry_get_type (xmmsv_t *val, const char *key)
00509 {
00510 xmmsv_t *v;
00511
00512 if (!xmmsv_dict_get (val, key, &v)) {
00513 return XMMSV_TYPE_NONE;
00514 }
00515
00516 return xmmsv_get_type (v);
00517 }
00518
00519
00520
00521 #define GEN_DICT_EXTRACTOR_FUNC(typename, type) \
00522 int \
00523 xmmsv_dict_entry_get_##typename (xmmsv_t *val, const char *key, \
00524 type *r) \
00525 { \
00526 xmmsv_t *v; \
00527 if (!xmmsv_dict_get (val, key, &v)) { \
00528 return 0; \
00529 } \
00530 return xmmsv_get_##typename (v, r); \
00531 }
00532
00533 GEN_DICT_EXTRACTOR_FUNC (string, const char *)
00534 GEN_DICT_EXTRACTOR_FUNC (int, int32_t)
00535 GEN_DICT_EXTRACTOR_FUNC (coll, xmmsv_coll_t *)
00536
00537
00538 #define GEN_DICT_SET_FUNC(typename, type) \
00539 int \
00540 xmmsv_dict_set_##typename (xmmsv_t *dict, const char *key, type elem) \
00541 { \
00542 int ret; \
00543 xmmsv_t *v; \
00544 \
00545 v = xmmsv_new_##typename (elem); \
00546 ret = xmmsv_dict_set (dict, key, v); \
00547 xmmsv_unref (v); \
00548 \
00549 return ret; \
00550 }
00551
00552 GEN_DICT_SET_FUNC (string, const char *)
00553 GEN_DICT_SET_FUNC (int, int32_t)
00554 GEN_DICT_SET_FUNC (coll, xmmsv_coll_t *)
00555
00556
00557 #define GEN_DICT_ITER_EXTRACTOR_FUNC(typename, type) \
00558 int \
00559 xmmsv_dict_iter_pair_##typename (xmmsv_dict_iter_t *it, \
00560 const char **key, \
00561 type *r) \
00562 { \
00563 xmmsv_t *v; \
00564 if (!xmmsv_dict_iter_pair (it, key, &v)) { \
00565 return 0; \
00566 } \
00567 if (r) { \
00568 return xmmsv_get_##typename (v, r); \
00569 } else { \
00570 return 1; \
00571 } \
00572 }
00573
00574 GEN_DICT_ITER_EXTRACTOR_FUNC (string, const char *)
00575 GEN_DICT_ITER_EXTRACTOR_FUNC (int, int32_t)
00576 GEN_DICT_ITER_EXTRACTOR_FUNC (coll, xmmsv_coll_t *)
00577
00578
00579 #define GEN_DICT_ITER_SET_FUNC(typename, type) \
00580 int \
00581 xmmsv_dict_iter_set_##typename (xmmsv_dict_iter_t *it, type elem) \
00582 { \
00583 int ret; \
00584 xmmsv_t *v; \
00585 \
00586 v = xmmsv_new_##typename (elem); \
00587 ret = xmmsv_dict_iter_set (it, v); \
00588 xmmsv_unref (v); \
00589 \
00590 return ret; \
00591 }
00592
00593 GEN_DICT_ITER_SET_FUNC (string, const char *)
00594 GEN_DICT_ITER_SET_FUNC (int, int32_t)
00595 GEN_DICT_ITER_SET_FUNC (coll, xmmsv_coll_t *)
00596
00597
00598 #define GEN_LIST_EXTRACTOR_FUNC(typename, type) \
00599 int \
00600 xmmsv_list_get_##typename (xmmsv_t *val, int pos, type *r) \
00601 { \
00602 xmmsv_t *v; \
00603 if (!xmmsv_list_get (val, pos, &v)) { \
00604 return 0; \
00605 } \
00606 return xmmsv_get_##typename (v, r); \
00607 }
00608
00609 GEN_LIST_EXTRACTOR_FUNC (string, const char *)
00610 GEN_LIST_EXTRACTOR_FUNC (int, int32_t)
00611 GEN_LIST_EXTRACTOR_FUNC (coll, xmmsv_coll_t *)
00612
00613
00614 #define GEN_LIST_SET_FUNC(typename, type) \
00615 int \
00616 xmmsv_list_set_##typename (xmmsv_t *list, int pos, type elem) \
00617 { \
00618 int ret; \
00619 xmmsv_t *v; \
00620 \
00621 v = xmmsv_new_##typename (elem); \
00622 ret = xmmsv_list_set (list, pos, v); \
00623 xmmsv_unref (v); \
00624 \
00625 return ret; \
00626 }
00627
00628 GEN_LIST_SET_FUNC (string, const char *)
00629 GEN_LIST_SET_FUNC (int, int32_t)
00630 GEN_LIST_SET_FUNC (coll, xmmsv_coll_t *)
00631
00632
00633 #define GEN_LIST_INSERT_FUNC(typename, type) \
00634 int \
00635 xmmsv_list_insert_##typename (xmmsv_t *list, int pos, type elem) \
00636 { \
00637 int ret; \
00638 xmmsv_t *v; \
00639 \
00640 v = xmmsv_new_##typename (elem); \
00641 ret = xmmsv_list_insert (list, pos, v); \
00642 xmmsv_unref (v); \
00643 \
00644 return ret; \
00645 }
00646
00647 GEN_LIST_INSERT_FUNC (string, const char *)
00648 GEN_LIST_INSERT_FUNC (int, int32_t)
00649 GEN_LIST_INSERT_FUNC (coll, xmmsv_coll_t *)
00650
00651
00652 #define GEN_LIST_APPEND_FUNC(typename, type) \
00653 int \
00654 xmmsv_list_append_##typename (xmmsv_t *list, type elem) \
00655 { \
00656 int ret; \
00657 xmmsv_t *v; \
00658 \
00659 v = xmmsv_new_##typename (elem); \
00660 ret = xmmsv_list_append (list, v); \
00661 xmmsv_unref (v); \
00662 \
00663 return ret; \
00664 }
00665
00666 GEN_LIST_APPEND_FUNC (string, const char *)
00667 GEN_LIST_APPEND_FUNC (int, int32_t)
00668 GEN_LIST_APPEND_FUNC (coll, xmmsv_coll_t *)
00669
00670
00671 #define GEN_LIST_ITER_EXTRACTOR_FUNC(typename, type) \
00672 int \
00673 xmmsv_list_iter_entry_##typename (xmmsv_list_iter_t *it, type *r) \
00674 { \
00675 xmmsv_t *v; \
00676 if (!xmmsv_list_iter_entry (it, &v)) { \
00677 return 0; \
00678 } \
00679 return xmmsv_get_##typename (v, r); \
00680 }
00681
00682 GEN_LIST_ITER_EXTRACTOR_FUNC (string, const char *)
00683 GEN_LIST_ITER_EXTRACTOR_FUNC (int, int32_t)
00684 GEN_LIST_ITER_EXTRACTOR_FUNC (coll, xmmsv_coll_t *)
00685
00686
00687 #define GEN_LIST_ITER_INSERT_FUNC(typename, type) \
00688 int \
00689 xmmsv_list_iter_insert_##typename (xmmsv_list_iter_t *it, type elem) \
00690 { \
00691 int ret; \
00692 xmmsv_t *v; \
00693 \
00694 v = xmmsv_new_##typename (elem); \
00695 ret = xmmsv_list_iter_insert (it, v); \
00696 xmmsv_unref (v); \
00697 \
00698 return ret; \
00699 }
00700
00701 GEN_LIST_ITER_INSERT_FUNC (string, const char *)
00702 GEN_LIST_ITER_INSERT_FUNC (int, int32_t)
00703 GEN_LIST_ITER_INSERT_FUNC (coll, xmmsv_coll_t *)
00704
00705 static int
00706 source_match_pattern (const char *source, const char *pattern)
00707 {
00708 int match = 0;
00709 int lpos = strlen (pattern) - 1;
00710
00711 if (strcasecmp (pattern, source) == 0) {
00712 match = 1;
00713 } else if (lpos >= 0 && pattern[lpos] == '*' &&
00714 (lpos == 0 || strncasecmp (source, pattern, lpos) == 0)) {
00715 match = 1;
00716 }
00717
00718 return match;
00719 }
00720
00721
00722
00723
00724 static int
00725 find_match_index (const char *source, const char **src_prefs)
00726 {
00727 int i, match = -1;
00728
00729 for (i = 0; src_prefs[i]; i++) {
00730 if (source_match_pattern (source, src_prefs[i])) {
00731 match = i;
00732 break;
00733 }
00734 }
00735
00736 return match;
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 xmmsv_t *
00752 xmmsv_propdict_to_dict (xmmsv_t *propdict, const char **src_prefs)
00753 {
00754 xmmsv_t *dict, *source_dict, *value, *best_value;
00755 xmmsv_dict_iter_t *key_it, *source_it;
00756 const char *key, *source;
00757 const char **local_prefs;
00758 int match_index, best_index;
00759
00760 dict = xmmsv_new_dict ();
00761
00762 local_prefs = src_prefs ? src_prefs : default_source_pref;
00763
00764 xmmsv_get_dict_iter (propdict, &key_it);
00765 while (xmmsv_dict_iter_valid (key_it)) {
00766 xmmsv_dict_iter_pair (key_it, &key, &source_dict);
00767
00768 best_value = NULL;
00769 best_index = -1;
00770 xmmsv_get_dict_iter (source_dict, &source_it);
00771 while (xmmsv_dict_iter_valid (source_it)) {
00772 xmmsv_dict_iter_pair (source_it, &source, &value);
00773 match_index = find_match_index (source, local_prefs);
00774
00775 if (match_index >= 0 && (best_index < 0 ||
00776 match_index < best_index)) {
00777 best_value = value;
00778 best_index = match_index;
00779 }
00780 xmmsv_dict_iter_next (source_it);
00781 }
00782
00783
00784 if (best_value) {
00785 xmmsv_dict_set (dict, key, best_value);
00786 }
00787
00788 xmmsv_dict_iter_next (key_it);
00789 }
00790
00791 return dict;
00792 }
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 int
00804 xmmsv_get_error (const xmmsv_t *val, const char **r)
00805 {
00806 if (!val || val->type != XMMSV_TYPE_ERROR) {
00807 return 0;
00808 }
00809
00810 *r = val->value.error;
00811
00812 return 1;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822 int
00823 xmmsv_get_int (const xmmsv_t *val, int32_t *r)
00824 {
00825 if (!val || val->type != XMMSV_TYPE_INT32) {
00826 return 0;
00827 }
00828
00829 *r = val->value.int32;
00830
00831 return 1;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841 int
00842 xmmsv_get_uint (const xmmsv_t *val, uint32_t *r)
00843 {
00844 if (!val)
00845 return 0;
00846 if (val->type != XMMSV_TYPE_INT32)
00847 return 0;
00848
00849 *r = val->value.int32;
00850
00851 return 1;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 int
00863 xmmsv_get_string (const xmmsv_t *val, const char **r)
00864 {
00865 if (!val || val->type != XMMSV_TYPE_STRING) {
00866 return 0;
00867 }
00868
00869 *r = val->value.string;
00870
00871 return 1;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 int
00883 xmmsv_get_coll (const xmmsv_t *val, xmmsv_coll_t **c)
00884 {
00885 if (!val || val->type != XMMSV_TYPE_COLL) {
00886 return 0;
00887 }
00888
00889 *c = val->value.coll;
00890
00891 return 1;
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 int
00904 xmmsv_get_bin (const xmmsv_t *val, const unsigned char **r, unsigned int *rlen)
00905 {
00906 if (!val || val->type != XMMSV_TYPE_BIN) {
00907 return 0;
00908 }
00909
00910 *r = val->value.bin.data;
00911 *rlen = val->value.bin.len;
00912
00913 return 1;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 int
00926 xmmsv_get_list_iter (const xmmsv_t *val, xmmsv_list_iter_t **it)
00927 {
00928 xmmsv_list_iter_t *new_it;
00929
00930 if (!val || val->type != XMMSV_TYPE_LIST) {
00931 *it = NULL;
00932 return 0;
00933 }
00934
00935 new_it = xmmsv_list_iter_new (val->value.list);
00936 if (!new_it) {
00937 *it = NULL;
00938 return 0;
00939 }
00940
00941 *it = new_it;
00942
00943 return 1;
00944 }
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 int
00955 xmmsv_get_dict_iter (const xmmsv_t *val, xmmsv_dict_iter_t **it)
00956 {
00957 xmmsv_dict_iter_t *new_it;
00958
00959 if (!val || val->type != XMMSV_TYPE_DICT) {
00960 *it = NULL;
00961 return 0;
00962 }
00963
00964 new_it = xmmsv_dict_iter_new (val->value.dict);
00965 if (!new_it) {
00966 *it = NULL;
00967 return 0;
00968 }
00969
00970 *it = new_it;
00971
00972 return 1;
00973 }
00974
00975
00976
00977
00978 static xmmsv_list_t *
00979 xmmsv_list_new (void)
00980 {
00981 xmmsv_list_t *list;
00982
00983 list = x_new0 (xmmsv_list_t, 1);
00984 if (!list) {
00985 x_oom ();
00986 return NULL;
00987 }
00988
00989
00990
00991 return list;
00992 }
00993
00994 static void
00995 xmmsv_list_free (xmmsv_list_t *l)
00996 {
00997 xmmsv_list_iter_t *it;
00998 int i;
00999
01000
01001 while (l->iterators) {
01002 it = (xmmsv_list_iter_t *) l->iterators->data;
01003 xmmsv_list_iter_free (it);
01004 }
01005
01006
01007 for (i = 0; i < l->size; i++) {
01008 xmmsv_unref (l->list[i]);
01009 }
01010
01011 free (l->list);
01012 free (l);
01013 }
01014
01015 static int
01016 xmmsv_list_resize (xmmsv_list_t *l, int newsize)
01017 {
01018 xmmsv_t **newmem;
01019
01020 newmem = realloc (l->list, newsize * sizeof (xmmsv_t *));
01021
01022 if (newsize != 0 && newmem == NULL) {
01023 x_oom ();
01024 return 0;
01025 }
01026
01027 l->list = newmem;
01028 l->allocated = newsize;
01029
01030 return 1;
01031 }
01032
01033 static int
01034 _xmmsv_list_insert (xmmsv_list_t *l, int pos, xmmsv_t *val)
01035 {
01036 xmmsv_list_iter_t *it;
01037 x_list_t *n;
01038
01039 if (!absolutify_and_validate_pos (&pos, l->size, 1)) {
01040 return 0;
01041 }
01042
01043 if (l->restricted) {
01044 x_return_val_if_fail (xmmsv_is_type (val, l->restricttype), 0);
01045 }
01046
01047
01048 if (l->size == l->allocated) {
01049 int success;
01050 size_t double_size;
01051 if (l->allocated > 0) {
01052 double_size = l->allocated << 1;
01053 } else {
01054 double_size = 1;
01055 }
01056 success = xmmsv_list_resize (l, double_size);
01057 x_return_val_if_fail (success, 0);
01058 }
01059
01060
01061 if (l->size > pos) {
01062 memmove (l->list + pos + 1, l->list + pos,
01063 (l->size - pos) * sizeof (xmmsv_t *));
01064 }
01065
01066 l->list[pos] = xmmsv_ref (val);
01067 l->size++;
01068
01069
01070 for (n = l->iterators; n; n = n->next) {
01071 it = (xmmsv_list_iter_t *) n->data;
01072 if (it->position > pos) {
01073 it->position++;
01074 }
01075 }
01076
01077 return 1;
01078 }
01079
01080 static int
01081 _xmmsv_list_append (xmmsv_list_t *l, xmmsv_t *val)
01082 {
01083 return _xmmsv_list_insert (l, l->size, val);
01084 }
01085
01086 static int
01087 _xmmsv_list_remove (xmmsv_list_t *l, int pos)
01088 {
01089 xmmsv_list_iter_t *it;
01090 int half_size;
01091 x_list_t *n;
01092
01093
01094 if (!absolutify_and_validate_pos (&pos, l->size, 0)) {
01095 return 0;
01096 }
01097
01098 xmmsv_unref (l->list[pos]);
01099
01100 l->size--;
01101
01102
01103 if (pos < l->size) {
01104 memmove (l->list + pos, l->list + pos + 1,
01105 (l->size - pos) * sizeof (xmmsv_t *));
01106 }
01107
01108
01109 half_size = l->allocated >> 1;
01110 if (l->size <= half_size) {
01111 int success;
01112 success = xmmsv_list_resize (l, half_size);
01113 x_return_val_if_fail (success, 0);
01114 }
01115
01116
01117 for (n = l->iterators; n; n = n->next) {
01118 it = (xmmsv_list_iter_t *) n->data;
01119 if (it->position > pos) {
01120 it->position--;
01121 }
01122 }
01123
01124 return 1;
01125 }
01126
01127 static int
01128 _xmmsv_list_move (xmmsv_list_t *l, int old_pos, int new_pos)
01129 {
01130 xmmsv_t *v;
01131 xmmsv_list_iter_t *it;
01132 x_list_t *n;
01133
01134 if (!absolutify_and_validate_pos (&old_pos, l->size, 0)) {
01135 return 0;
01136 }
01137 if (!absolutify_and_validate_pos (&new_pos, l->size, 0)) {
01138 return 0;
01139 }
01140
01141 v = l->list[old_pos];
01142 if (old_pos < new_pos) {
01143 memmove (l->list + old_pos, l->list + old_pos + 1,
01144 (new_pos - old_pos) * sizeof (xmmsv_t *));
01145 l->list[new_pos] = v;
01146
01147
01148 for (n = l->iterators; n; n = n->next) {
01149 it = (xmmsv_list_iter_t *) n->data;
01150 if (it->position >= old_pos && it->position <= new_pos) {
01151 if (it->position == old_pos) {
01152 it->position = new_pos;
01153 } else {
01154 it->position--;
01155 }
01156 }
01157 }
01158 } else {
01159 memmove (l->list + new_pos + 1, l->list + new_pos,
01160 (old_pos - new_pos) * sizeof (xmmsv_t *));
01161 l->list[new_pos] = v;
01162
01163
01164 for (n = l->iterators; n; n = n->next) {
01165 it = (xmmsv_list_iter_t *) n->data;
01166 if (it->position >= new_pos && it->position <= old_pos) {
01167 if (it->position == old_pos) {
01168 it->position = new_pos;
01169 } else {
01170 it->position++;
01171 }
01172 }
01173 }
01174 }
01175
01176 return 1;
01177 }
01178
01179 static void
01180 _xmmsv_list_clear (xmmsv_list_t *l)
01181 {
01182 xmmsv_list_iter_t *it;
01183 x_list_t *n;
01184 int i;
01185
01186
01187 for (i = 0; i < l->size; i++) {
01188 xmmsv_unref (l->list[i]);
01189 }
01190
01191
01192 free (l->list);
01193 l->list = NULL;
01194
01195 l->size = 0;
01196 l->allocated = 0;
01197
01198
01199 for (n = l->iterators; n; n = n->next) {
01200 it = (xmmsv_list_iter_t *) n->data;
01201 it->position = 0;
01202 }
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 int
01218 xmmsv_list_get (xmmsv_t *listv, int pos, xmmsv_t **val)
01219 {
01220 xmmsv_list_t *l;
01221
01222 x_return_val_if_fail (listv, 0);
01223 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01224
01225 l = listv->value.list;
01226
01227
01228 if (!absolutify_and_validate_pos (&pos, l->size, 0)) {
01229 return 0;
01230 }
01231
01232 if (val) {
01233 *val = l->list[pos];
01234 }
01235
01236 return 1;
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 int
01249 xmmsv_list_set (xmmsv_t *listv, int pos, xmmsv_t *val)
01250 {
01251 xmmsv_t *old_val;
01252 xmmsv_list_t *l;
01253
01254 x_return_val_if_fail (listv, 0);
01255 x_return_val_if_fail (val, 0);
01256 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01257
01258 l = listv->value.list;
01259
01260 if (!absolutify_and_validate_pos (&pos, l->size, 0)) {
01261 return 0;
01262 }
01263
01264 old_val = l->list[pos];
01265 l->list[pos] = xmmsv_ref (val);
01266 xmmsv_unref (old_val);
01267
01268 return 1;
01269 }
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281 int
01282 xmmsv_list_insert (xmmsv_t *listv, int pos, xmmsv_t *val)
01283 {
01284 x_return_val_if_fail (listv, 0);
01285 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01286 x_return_val_if_fail (val, 0);
01287
01288 return _xmmsv_list_insert (listv->value.list, pos, val);
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 int
01300 xmmsv_list_remove (xmmsv_t *listv, int pos)
01301 {
01302 x_return_val_if_fail (listv, 0);
01303 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01304
01305 return _xmmsv_list_remove (listv->value.list, pos);
01306 }
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 int
01323 xmmsv_list_move (xmmsv_t *listv, int old_pos, int new_pos)
01324 {
01325 x_return_val_if_fail (listv, 0);
01326 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01327
01328 return _xmmsv_list_move (listv->value.list, old_pos, new_pos);
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 int
01340 xmmsv_list_append (xmmsv_t *listv, xmmsv_t *val)
01341 {
01342 x_return_val_if_fail (listv, 0);
01343 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01344 x_return_val_if_fail (val, 0);
01345
01346 return _xmmsv_list_append (listv->value.list, val);
01347 }
01348
01349
01350
01351
01352
01353
01354
01355 int
01356 xmmsv_list_clear (xmmsv_t *listv)
01357 {
01358 x_return_val_if_fail (listv, 0);
01359 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01360
01361 _xmmsv_list_clear (listv->value.list);
01362
01363 return 1;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 int
01375 xmmsv_list_foreach (xmmsv_t *listv, xmmsv_list_foreach_func func,
01376 void* user_data)
01377 {
01378 xmmsv_list_iter_t *it;
01379 xmmsv_t *v;
01380
01381 x_return_val_if_fail (listv, 0);
01382 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01383 x_return_val_if_fail (xmmsv_get_list_iter (listv, &it), 0);
01384
01385 while (xmmsv_list_iter_valid (it)) {
01386 xmmsv_list_iter_entry (it, &v);
01387 func (v, user_data);
01388 xmmsv_list_iter_next (it);
01389 }
01390
01391 xmmsv_list_iter_free (it);
01392
01393 return 1;
01394 }
01395
01396
01397
01398
01399
01400
01401
01402 int
01403 xmmsv_list_get_size (xmmsv_t *listv)
01404 {
01405 x_return_val_if_fail (listv, -1);
01406 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), -1);
01407
01408 return listv->value.list->size;
01409 }
01410
01411
01412 int
01413 xmmsv_list_restrict_type (xmmsv_t *listv, xmmsv_type_t type)
01414 {
01415 xmmsv_list_iter_t *it;
01416 xmmsv_t *v;
01417
01418 x_return_val_if_fail (listv, 0);
01419 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0);
01420
01421 x_return_val_if_fail (!listv->value.list->restricted, 0);
01422
01423 x_return_val_if_fail (xmmsv_get_list_iter (listv, &it), 0);
01424 while (xmmsv_list_iter_valid (it)) {
01425 xmmsv_list_iter_entry (it, &v);
01426 x_return_val_if_fail (xmmsv_is_type (v, type), 0);
01427 xmmsv_list_iter_next (it);
01428 }
01429
01430 xmmsv_list_iter_free (it);
01431
01432 listv->value.list->restricted = true;
01433 listv->value.list->restricttype = type;
01434
01435 return 1;
01436 }
01437
01438
01439 static xmmsv_list_iter_t *
01440 xmmsv_list_iter_new (xmmsv_list_t *l)
01441 {
01442 xmmsv_list_iter_t *it;
01443
01444 it = x_new0 (xmmsv_list_iter_t, 1);
01445 if (!it) {
01446 x_oom ();
01447 return NULL;
01448 }
01449
01450 it->parent = l;
01451 it->position = 0;
01452
01453
01454 l->iterators = x_list_prepend (l->iterators, it);
01455
01456 return it;
01457 }
01458
01459 static void
01460 xmmsv_list_iter_free (xmmsv_list_iter_t *it)
01461 {
01462
01463 it->parent->iterators = x_list_remove (it->parent->iterators, it);
01464 free (it);
01465 }
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 void
01478 xmmsv_list_iter_explicit_destroy (xmmsv_list_iter_t *it)
01479 {
01480 xmmsv_list_iter_free (it);
01481 }
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 int
01495 xmmsv_list_iter_entry (xmmsv_list_iter_t *it, xmmsv_t **val)
01496 {
01497 if (!xmmsv_list_iter_valid (it))
01498 return 0;
01499
01500 *val = it->parent->list[it->position];
01501
01502 return 1;
01503 }
01504
01505
01506
01507
01508
01509
01510
01511 int
01512 xmmsv_list_iter_valid (xmmsv_list_iter_t *it)
01513 {
01514 return it && (it->position < it->parent->size) && (it->position >= 0);
01515 }
01516
01517
01518
01519
01520
01521
01522 void
01523 xmmsv_list_iter_first (xmmsv_list_iter_t *it)
01524 {
01525 x_return_if_fail (it);
01526
01527 it->position = 0;
01528 }
01529
01530
01531
01532
01533
01534
01535 void
01536 xmmsv_list_iter_last (xmmsv_list_iter_t *it)
01537 {
01538 x_return_if_fail (it);
01539
01540 if (it->parent->size > 0) {
01541 it->position = it->parent->size - 1;
01542 } else {
01543 it->position = it->parent->size;
01544 }
01545 }
01546
01547
01548
01549
01550
01551
01552 void
01553 xmmsv_list_iter_next (xmmsv_list_iter_t *it)
01554 {
01555 x_return_if_fail (it);
01556
01557 if (it->position < it->parent->size) {
01558 it->position++;
01559 }
01560 }
01561
01562
01563
01564
01565
01566
01567 void
01568 xmmsv_list_iter_prev (xmmsv_list_iter_t *it)
01569 {
01570 x_return_if_fail (it);
01571
01572 if (it->position >= 0) {
01573 it->position--;
01574 }
01575 }
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586 int
01587 xmmsv_list_iter_seek (xmmsv_list_iter_t *it, int pos)
01588 {
01589 x_return_val_if_fail (it, 0);
01590
01591 if (!absolutify_and_validate_pos (&pos, it->parent->size, 1)) {
01592 return 0;
01593 }
01594 it->position = pos;
01595
01596 return 1;
01597 }
01598
01599
01600
01601
01602
01603
01604
01605 int
01606 xmmsv_list_iter_tell (const xmmsv_list_iter_t *it)
01607 {
01608 x_return_val_if_fail (it, -1);
01609
01610 return it->position;
01611 }
01612
01613
01614
01615
01616
01617
01618
01619 xmmsv_t*
01620 xmmsv_list_iter_get_parent (const xmmsv_list_iter_t *it)
01621 {
01622 x_return_val_if_fail (it, NULL);
01623
01624 return it->parent->parent_value;
01625 }
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635 int
01636 xmmsv_list_iter_insert (xmmsv_list_iter_t *it, xmmsv_t *val)
01637 {
01638 x_return_val_if_fail (it, 0);
01639 x_return_val_if_fail (val, 0);
01640
01641 return _xmmsv_list_insert (it->parent, it->position, val);
01642 }
01643
01644
01645
01646
01647
01648
01649
01650
01651 int
01652 xmmsv_list_iter_remove (xmmsv_list_iter_t *it)
01653 {
01654 x_return_val_if_fail (it, 0);
01655
01656 return _xmmsv_list_remove (it->parent, it->position);
01657 }
01658
01659
01660
01661 struct xmmsv_dict_St {
01662
01663 xmmsv_list_t *flatlist;
01664 x_list_t *iterators;
01665 };
01666
01667 struct xmmsv_dict_iter_St {
01668
01669 xmmsv_list_iter_t *lit;
01670 xmmsv_dict_t *parent;
01671 };
01672
01673 static xmmsv_dict_t *
01674 xmmsv_dict_new (void)
01675 {
01676 xmmsv_dict_t *dict;
01677
01678 dict = x_new0 (xmmsv_dict_t, 1);
01679 if (!dict) {
01680 x_oom ();
01681 return NULL;
01682 }
01683
01684 dict->flatlist = xmmsv_list_new ();
01685
01686 return dict;
01687 }
01688
01689 static void
01690 xmmsv_dict_free (xmmsv_dict_t *dict)
01691 {
01692 xmmsv_dict_iter_t *it;
01693
01694
01695 while (dict->iterators) {
01696 it = (xmmsv_dict_iter_t *) dict->iterators->data;
01697 xmmsv_dict_iter_free (it);
01698 }
01699
01700 xmmsv_list_free (dict->flatlist);
01701
01702 free (dict);
01703 }
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716 int
01717 xmmsv_dict_get (xmmsv_t *dictv, const char *key, xmmsv_t **val)
01718 {
01719 xmmsv_dict_iter_t *it;
01720 int ret = 1;
01721
01722 x_return_val_if_fail (key, 0);
01723 x_return_val_if_fail (dictv, 0);
01724 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), 0);
01725 x_return_val_if_fail (xmmsv_get_dict_iter (dictv, &it), 0);
01726
01727 if (!xmmsv_dict_iter_find (it, key)) {
01728 ret = 0;
01729 }
01730
01731
01732 if (ret && val) {
01733 xmmsv_dict_iter_pair (it, NULL, val);
01734 }
01735
01736 xmmsv_dict_iter_free (it);
01737
01738 return ret;
01739 }
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 int
01752 xmmsv_dict_set (xmmsv_t *dictv, const char *key, xmmsv_t *val)
01753 {
01754 xmmsv_dict_iter_t *it;
01755 int ret;
01756
01757 x_return_val_if_fail (key, 0);
01758 x_return_val_if_fail (val, 0);
01759 x_return_val_if_fail (dictv, 0);
01760 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), 0);
01761 x_return_val_if_fail (xmmsv_get_dict_iter (dictv, &it), 0);
01762
01763
01764 if (xmmsv_dict_iter_find (it, key)) {
01765 ret = xmmsv_dict_iter_set (it, val);
01766
01767
01768 } else {
01769 xmmsv_t *keyval;
01770
01771 keyval = xmmsv_new_string (key);
01772
01773 ret = xmmsv_list_iter_insert (it->lit, keyval);
01774 if (ret) {
01775 xmmsv_list_iter_next (it->lit);
01776 ret = xmmsv_list_iter_insert (it->lit, val);
01777 if (!ret) {
01778
01779
01780
01781
01782 it->lit->position--;
01783 xmmsv_list_iter_remove (it->lit);
01784 }
01785 }
01786 xmmsv_unref (keyval);
01787 }
01788
01789 xmmsv_dict_iter_free (it);
01790
01791 return ret;
01792 }
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802 int
01803 xmmsv_dict_remove (xmmsv_t *dictv, const char *key)
01804 {
01805 xmmsv_dict_iter_t *it;
01806 int ret = 1;
01807
01808 x_return_val_if_fail (key, 0);
01809 x_return_val_if_fail (dictv, 0);
01810 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), 0);
01811 x_return_val_if_fail (xmmsv_get_dict_iter (dictv, &it), 0);
01812
01813 if (!xmmsv_dict_iter_find (it, key)) {
01814 ret = 0;
01815 } else {
01816 ret = xmmsv_list_iter_remove (it->lit) &&
01817 xmmsv_list_iter_remove (it->lit);
01818
01819 }
01820
01821 xmmsv_dict_iter_free (it);
01822
01823 return ret;
01824 }
01825
01826
01827
01828
01829
01830
01831
01832 int
01833 xmmsv_dict_clear (xmmsv_t *dictv)
01834 {
01835 x_return_val_if_fail (dictv, 0);
01836 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), 0);
01837
01838 _xmmsv_list_clear (dictv->value.dict->flatlist);
01839
01840 return 1;
01841 }
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852 int
01853 xmmsv_dict_foreach (xmmsv_t *dictv, xmmsv_dict_foreach_func func,
01854 void *user_data)
01855 {
01856 xmmsv_dict_iter_t *it;
01857 const char *key;
01858 xmmsv_t *v;
01859
01860 x_return_val_if_fail (dictv, 0);
01861 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), 0);
01862 x_return_val_if_fail (xmmsv_get_dict_iter (dictv, &it), 0);
01863
01864 while (xmmsv_dict_iter_valid (it)) {
01865 xmmsv_dict_iter_pair (it, &key, &v);
01866 func (key, v, user_data);
01867 xmmsv_dict_iter_next (it);
01868 }
01869
01870 xmmsv_dict_iter_free (it);
01871
01872 return 1;
01873 }
01874
01875
01876
01877
01878
01879
01880
01881 int
01882 xmmsv_dict_get_size (xmmsv_t *dictv)
01883 {
01884 x_return_val_if_fail (dictv, -1);
01885 x_return_val_if_fail (xmmsv_is_type (dictv, XMMSV_TYPE_DICT), -1);
01886
01887 return dictv->value.dict->flatlist->size / 2;
01888 }
01889
01890 static xmmsv_dict_iter_t *
01891 xmmsv_dict_iter_new (xmmsv_dict_t *d)
01892 {
01893 xmmsv_dict_iter_t *it;
01894
01895 it = x_new0 (xmmsv_dict_iter_t, 1);
01896 if (!it) {
01897 x_oom ();
01898 return NULL;
01899 }
01900
01901 it->lit = xmmsv_list_iter_new (d->flatlist);
01902 it->parent = d;
01903
01904
01905 d->iterators = x_list_prepend (d->iterators, it);
01906
01907 return it;
01908 }
01909
01910 static void
01911 xmmsv_dict_iter_free (xmmsv_dict_iter_t *it)
01912 {
01913
01914
01915
01916 it->parent->iterators = x_list_remove (it->parent->iterators, it);
01917 free (it);
01918 }
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930 void
01931 xmmsv_dict_iter_explicit_destroy (xmmsv_dict_iter_t *it)
01932 {
01933 xmmsv_dict_iter_free (it);
01934 }
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947 int
01948 xmmsv_dict_iter_pair (xmmsv_dict_iter_t *it, const char **key,
01949 xmmsv_t **val)
01950 {
01951 unsigned int orig;
01952 xmmsv_t *v;
01953
01954 if (!xmmsv_dict_iter_valid (it)) {
01955 return 0;
01956 }
01957
01958
01959 orig = it->lit->position;
01960
01961 if (key) {
01962 xmmsv_list_iter_entry (it->lit, &v);
01963 xmmsv_get_string (v, key);
01964 }
01965
01966 if (val) {
01967 xmmsv_list_iter_next (it->lit);
01968 xmmsv_list_iter_entry (it->lit, val);
01969 }
01970
01971 it->lit->position = orig;
01972
01973 return 1;
01974 }
01975
01976
01977
01978
01979
01980
01981
01982 int
01983 xmmsv_dict_iter_valid (xmmsv_dict_iter_t *it)
01984 {
01985 return it && xmmsv_list_iter_valid (it->lit);
01986 }
01987
01988
01989
01990
01991
01992
01993
01994 void
01995 xmmsv_dict_iter_first (xmmsv_dict_iter_t *it)
01996 {
01997 x_return_if_fail (it);
01998
01999 xmmsv_list_iter_first (it->lit);
02000 }
02001
02002
02003
02004
02005
02006
02007
02008 void
02009 xmmsv_dict_iter_next (xmmsv_dict_iter_t *it)
02010 {
02011 x_return_if_fail (it);
02012
02013
02014 xmmsv_list_iter_next (it->lit);
02015 xmmsv_list_iter_next (it->lit);
02016 }
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027 int
02028 xmmsv_dict_iter_find (xmmsv_dict_iter_t *it, const char *key)
02029 {
02030 xmmsv_t *val;
02031 const char *k;
02032 int s, dict_size, cmp, left, right;
02033
02034 x_return_val_if_fail (it, 0);
02035 x_return_val_if_fail (key, 0);
02036
02037
02038 dict_size = it->parent->flatlist->size / 2;
02039
02040
02041
02042
02043 if (!dict_size) {
02044 xmmsv_list_iter_seek (it->lit, 0);
02045
02046 return 0;
02047 }
02048
02049
02050 left = 0;
02051 right = dict_size - 1;
02052
02053 while (left <= right) {
02054 int mid = left + ((right - left) / 2);
02055
02056
02057 xmmsv_list_iter_seek (it->lit, mid * 2);
02058 xmmsv_list_iter_entry (it->lit, &val);
02059
02060
02061 s = xmmsv_get_string (val, &k);
02062 x_return_val_if_fail (s, 0);
02063
02064
02065 cmp = strcmp (k, key);
02066
02067
02068 if (cmp == 0)
02069 return 1;
02070
02071
02072 if (cmp < 0) {
02073 left = mid + 1;
02074 } else {
02075 right = mid - 1;
02076 }
02077 }
02078
02079
02080
02081
02082
02083
02084 if (cmp < 0) {
02085 xmmsv_list_iter_next (it->lit);
02086 xmmsv_list_iter_next (it->lit);
02087 }
02088
02089 return 0;
02090 }
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 int
02101 xmmsv_dict_iter_set (xmmsv_dict_iter_t *it, xmmsv_t *val)
02102 {
02103 unsigned int orig;
02104 int ret;
02105
02106 x_return_val_if_fail (xmmsv_dict_iter_valid (it), 0);
02107
02108
02109 orig = it->lit->position;
02110
02111 xmmsv_list_iter_next (it->lit);
02112 xmmsv_list_iter_remove (it->lit);
02113 ret = xmmsv_list_iter_insert (it->lit, val);
02114
02115
02116 it->lit->position = orig;
02117
02118 return ret;
02119 }
02120
02121
02122
02123
02124
02125
02126
02127 int
02128 xmmsv_dict_iter_remove (xmmsv_dict_iter_t *it)
02129 {
02130 int ret = 0;
02131
02132 ret = xmmsv_list_iter_remove (it->lit) &&
02133 xmmsv_list_iter_remove (it->lit);
02134
02135
02136 return ret;
02137 }
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166 xmmsv_t *
02167 xmmsv_decode_url (const xmmsv_t *inv)
02168 {
02169 int i = 0, j = 0;
02170 const char *ins;
02171 unsigned char *url;
02172 xmmsv_t *ret;
02173
02174 if (!xmmsv_get_string (inv, &ins)) {
02175 return NULL;
02176 }
02177
02178 url = x_malloc (strlen (ins));
02179 if (!url) {
02180 x_oom ();
02181 return NULL;
02182 }
02183
02184 while (ins[i]) {
02185 unsigned char chr = ins[i++];
02186
02187 if (chr == '+') {
02188 chr = ' ';
02189 } else if (chr == '%') {
02190 char ts[3];
02191 char *t;
02192
02193 ts[0] = ins[i++];
02194 if (!ts[0])
02195 goto err;
02196 ts[1] = ins[i++];
02197 if (!ts[1])
02198 goto err;
02199 ts[2] = '\0';
02200
02201 chr = strtoul (ts, &t, 16);
02202
02203 if (t != &ts[2])
02204 goto err;
02205 }
02206
02207 url[j++] = chr;
02208 }
02209
02210 ret = xmmsv_new_bin (url, j);
02211 free (url);
02212
02213 return ret;
02214
02215 err:
02216 free (url);
02217 return NULL;
02218 }
02219
02220 xmmsv_t *
02221 xmmsv_build_dict (const char *firstkey, ...)
02222 {
02223 va_list ap;
02224 const char *key;
02225 xmmsv_t *val, *res;
02226
02227 res = xmmsv_new_dict ();
02228 if (!res)
02229 return NULL;
02230
02231 va_start (ap, firstkey);
02232
02233 key = firstkey;
02234 do {
02235 val = va_arg (ap, xmmsv_t *);
02236
02237 if (!xmmsv_dict_set (res, key, val)) {
02238 xmmsv_unref (res);
02239 res = NULL;
02240 break;
02241 }
02242 xmmsv_unref (val);
02243 key = va_arg (ap, const char *);
02244 } while (key);
02245
02246 va_end (ap);
02247
02248 return res;
02249 }
02250
02251 xmmsv_t *
02252 xmmsv_build_list_va (xmmsv_t *first_entry, va_list ap)
02253 {
02254 xmmsv_t *val, *res;
02255
02256 res = xmmsv_new_list ();
02257 if (!res)
02258 return NULL;
02259
02260 val = first_entry;
02261
02262 while (val) {
02263 if (!xmmsv_list_append (res, val)) {
02264 xmmsv_unref (res);
02265 res = NULL;
02266 break;
02267 }
02268
02269 xmmsv_unref (val);
02270
02271 val = va_arg (ap, xmmsv_t *);
02272 }
02273
02274 return res;
02275 }
02276
02277 xmmsv_t *
02278 xmmsv_build_list (xmmsv_t *first_entry, ...)
02279 {
02280 va_list ap;
02281 xmmsv_t *res;
02282
02283 va_start (ap, first_entry);
02284 res = xmmsv_build_list_va (first_entry, ap);
02285 va_end (ap);
02286
02287 return res;
02288 }
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 int
02304 xmmsv_dict_format (char *target, int len, const char *fmt, xmmsv_t *val)
02305 {
02306 const char *pos;
02307
02308 if (!target) {
02309 return 0;
02310 }
02311
02312 if (!fmt) {
02313 return 0;
02314 }
02315
02316 memset (target, 0, len);
02317
02318 pos = fmt;
02319 while (strlen (target) + 1 < len) {
02320 char *next_key, *key, *end;
02321 int keylen;
02322 xmmsv_dict_iter_t *it;
02323 xmmsv_t *v;
02324
02325 next_key = strstr (pos, "${");
02326 if (!next_key) {
02327 strncat (target, pos, len - strlen (target) - 1);
02328 break;
02329 }
02330
02331 strncat (target, pos, MIN (next_key - pos, len - strlen (target) - 1));
02332 keylen = strcspn (next_key + 2, "}");
02333 key = malloc (keylen + 1);
02334
02335 if (!key) {
02336 fprintf (stderr, "Unable to allocate %u bytes of memory, OOM?", keylen);
02337 break;
02338 }
02339
02340 memset (key, 0, keylen + 1);
02341 strncpy (key, next_key + 2, keylen);
02342
02343 xmmsv_get_dict_iter (val, &it);
02344
02345 if (strcmp (key, "seconds") == 0) {
02346 int duration;
02347
02348 if (xmmsv_dict_iter_find (it, "duration")) {
02349 xmmsv_dict_iter_pair (it, NULL, &v);
02350 xmmsv_get_int (v, &duration);
02351 } else {
02352 duration = 0;
02353 }
02354
02355 if (!duration) {
02356 strncat (target, "00", len - strlen (target) - 1);
02357 } else {
02358 char seconds[10];
02359
02360 duration += 500;
02361 snprintf (seconds, sizeof (seconds), "%02d", (duration/1000)%60);
02362 strncat (target, seconds, len - strlen (target) - 1);
02363 }
02364 } else if (strcmp (key, "minutes") == 0) {
02365 int duration;
02366
02367 if (xmmsv_dict_iter_find (it, "duration")) {
02368 xmmsv_dict_iter_pair (it, NULL, &v);
02369 xmmsv_get_int (v, &duration);
02370 } else {
02371 duration = 0;
02372 }
02373
02374 if (!duration) {
02375 strncat (target, "00", len - strlen (target) - 1);
02376 } else {
02377 char minutes[10];
02378
02379 duration += 500;
02380 snprintf (minutes, sizeof (minutes), "%02d", duration/60000);
02381 strncat (target, minutes, len - strlen (target) - 1);
02382 }
02383 } else {
02384 const char *result = NULL;
02385 char tmp[12];
02386
02387 if (xmmsv_dict_iter_find (it, key)) {
02388 xmmsv_dict_iter_pair (it, NULL, &v);
02389
02390 xmmsv_type_t type = xmmsv_get_type (v);
02391 if (type == XMMSV_TYPE_STRING) {
02392 xmmsv_get_string (v, &result);
02393 } else if (type == XMMSV_TYPE_UINT32) {
02394 uint32_t ui;
02395 xmmsv_get_uint (v, &ui);
02396 snprintf (tmp, 12, "%u", ui);
02397 result = tmp;
02398 } else if (type == XMMSV_TYPE_INT32) {
02399 int32_t i;
02400 xmmsv_get_int (v, &i);
02401 snprintf (tmp, 12, "%d", i);
02402 result = tmp;
02403 }
02404 }
02405
02406 if (result)
02407 strncat (target, result, len - strlen (target) - 1);
02408 }
02409
02410 free (key);
02411 end = strchr (next_key, '}');
02412
02413 if (!end) {
02414 break;
02415 }
02416
02417 pos = end + 1;
02418 }
02419
02420 return strlen (target);
02421 }
02422
02423 static int
02424 _xmmsv_utf8_charlen (unsigned char c)
02425 {
02426 if ((c & 0x80) == 0) {
02427 return 1;
02428 } else if ((c & 0x60) == 0x40) {
02429 return 2;
02430 } else if ((c & 0x70) == 0x60) {
02431 return 3;
02432 } else if ((c & 0x78) == 0x70) {
02433 return 4;
02434 }
02435 return 0;
02436 }
02437
02438
02439
02440
02441
02442
02443 int
02444 xmmsv_utf8_validate (const char *str)
02445 {
02446 int i = 0;
02447
02448 for (;;) {
02449 unsigned char c = str[i++];
02450 int l;
02451 if (!c) {
02452
02453 return 1;
02454 }
02455
02456 l = _xmmsv_utf8_charlen (c);
02457 if (l == 0)
02458 return 0;
02459 while (l-- > 1) {
02460 if ((str[i++] & 0xC0) != 0x80)
02461 return 0;
02462 }
02463 }
02464 }
02465
02466
02467
02468
02469
02470
02471 static int
02472 absolutify_and_validate_pos (int *pos, int size, int allow_append)
02473 {
02474 x_return_val_if_fail (size >= 0, 0);
02475
02476 if (*pos < 0) {
02477 if (-*pos > size)
02478 return 0;
02479 *pos = size + *pos;
02480 }
02481
02482 if (*pos > size)
02483 return 0;
02484
02485 if (!allow_append && *pos == size)
02486 return 0;
02487
02488 return 1;
02489 }
02490
02491 int
02492 xmmsv_dict_has_key (xmmsv_t *dictv, const char *key)
02493 {
02494 return xmmsv_dict_get (dictv, key, NULL);
02495 }
02496
02497
02498 xmmsv_t *
02499 xmmsv_bitbuffer_new_ro (const unsigned char *v, int len)
02500 {
02501 xmmsv_t *val;
02502
02503 val = xmmsv_new (XMMSV_TYPE_BITBUFFER);
02504 val->value.bit.buf = (unsigned char *) v;
02505 val->value.bit.len = len * 8;
02506 val->value.bit.ro = true;
02507 return val;
02508 }
02509
02510 xmmsv_t *
02511 xmmsv_bitbuffer_new (void)
02512 {
02513 xmmsv_t *val;
02514
02515 val = xmmsv_new (XMMSV_TYPE_BITBUFFER);
02516 val->value.bit.buf = NULL;
02517 val->value.bit.len = 0;
02518 val->value.bit.ro = false;
02519 return val;
02520 }
02521
02522
02523 int
02524 xmmsv_bitbuffer_get_bits (xmmsv_t *v, int bits, int *res)
02525 {
02526 int i, t, r;
02527
02528 x_api_error_if (bits < 1, "less than one bit requested", 0);
02529
02530 if (bits == 1) {
02531 int pos = v->value.bit.pos;
02532
02533 if (pos >= v->value.bit.len)
02534 return 0;
02535 r = (v->value.bit.buf[pos / 8] >> (7-(pos % 8)) & 1);
02536 v->value.bit.pos += 1;
02537 *res = r;
02538 return 1;
02539 }
02540
02541 r = 0;
02542 for (i = 0; i < bits; i++) {
02543 t = 0;
02544 if (!xmmsv_bitbuffer_get_bits (v, 1, &t))
02545 return 0;
02546 r = (r << 1) | t;
02547 }
02548 *res = r;
02549 return 1;
02550 }
02551
02552 int
02553 xmmsv_bitbuffer_get_data (xmmsv_t *v, unsigned char *b, int len)
02554 {
02555 while (len) {
02556 int t;
02557 if (!xmmsv_bitbuffer_get_bits (v, 8, &t))
02558 return 0;
02559 *b = t;
02560 b++;
02561 len--;
02562 }
02563 return 1;
02564 }
02565
02566 int
02567 xmmsv_bitbuffer_put_bits (xmmsv_t *v, int bits, int d)
02568 {
02569 unsigned char t;
02570 int pos;
02571 int i;
02572
02573 x_api_error_if (v->value.bit.ro, "write to readonly bitbuffer", 0);
02574 x_api_error_if (bits < 1, "less than one bit requested", 0);
02575
02576 if (bits == 1) {
02577 pos = v->value.bit.pos;
02578
02579 if (pos >= v->value.bit.alloclen) {
02580 int ol, nl;
02581 nl = v->value.bit.alloclen * 2;
02582 ol = v->value.bit.alloclen;
02583 nl = nl < 128 ? 128 : nl;
02584 nl = (nl + 7) & ~7;
02585 v->value.bit.buf = realloc (v->value.bit.buf, nl / 8);
02586 memset (v->value.bit.buf + ol / 8, 0, (nl - ol) / 8);
02587 v->value.bit.alloclen = nl;
02588 }
02589 t = v->value.bit.buf[pos / 8];
02590
02591 t = (t & (~(1<<(7-(pos % 8))))) | (d << (7-(pos % 8)));
02592
02593 v->value.bit.buf[pos / 8] = t;
02594
02595 v->value.bit.pos += 1;
02596 if (v->value.bit.pos > v->value.bit.len)
02597 v->value.bit.len = v->value.bit.pos;
02598 return 1;
02599 }
02600
02601 for (i = 0; i < bits; i++) {
02602 if (!xmmsv_bitbuffer_put_bits (v, 1, !!(d & (1 << (bits-i-1)))))
02603 return 0;
02604 }
02605
02606 return 1;
02607 }
02608
02609 int
02610 xmmsv_bitbuffer_put_bits_at (xmmsv_t *v, int bits, int d, int offset)
02611 {
02612 int prevpos;
02613 prevpos = xmmsv_bitbuffer_pos (v);
02614 if (!xmmsv_bitbuffer_goto (v, offset))
02615 return 0;
02616 if (!xmmsv_bitbuffer_put_bits (v, bits, d))
02617 return 0;
02618 return xmmsv_bitbuffer_goto (v, prevpos);
02619 }
02620
02621 int
02622 xmmsv_bitbuffer_put_data (xmmsv_t *v, const unsigned char *b, int len)
02623 {
02624 while (len) {
02625 int t;
02626 t = *b;
02627 if (!xmmsv_bitbuffer_put_bits (v, 8, t))
02628 return 0;
02629 b++;
02630 len--;
02631 }
02632 return 1;
02633 }
02634
02635 int
02636 xmmsv_bitbuffer_align (xmmsv_t *v)
02637 {
02638 v->value.bit.pos = (v->value.bit.pos + 7) % 8;
02639 return 1;
02640 }
02641
02642 int
02643 xmmsv_bitbuffer_goto (xmmsv_t *v, int pos)
02644 {
02645 x_api_error_if (pos < 0, "negative position", 0);
02646 x_api_error_if (pos > v->value.bit.len, "position after buffer end", 0);
02647
02648 v->value.bit.pos = pos;
02649 return 1;
02650 }
02651
02652 int
02653 xmmsv_bitbuffer_pos (xmmsv_t *v)
02654 {
02655 return v->value.bit.pos;
02656 }
02657
02658 int
02659 xmmsv_bitbuffer_rewind (xmmsv_t *v)
02660 {
02661 return xmmsv_bitbuffer_goto (v, 0);
02662 }
02663
02664 int
02665 xmmsv_bitbuffer_end (xmmsv_t *v)
02666 {
02667 return xmmsv_bitbuffer_goto (v, v->value.bit.len);
02668 }
02669
02670 int
02671 xmmsv_bitbuffer_len (xmmsv_t *v)
02672 {
02673 return v->value.bit.len;
02674 }
02675
02676 const unsigned char *
02677 xmmsv_bitbuffer_buffer (xmmsv_t *v)
02678 {
02679 return v->value.bit.buf;
02680 }
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697