diff options
| -rw-r--r-- | src/plist.c | 131 |
1 files changed, 74 insertions, 57 deletions
diff --git a/src/plist.c b/src/plist.c index 17b8419..9a488bb 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -698,50 +698,62 @@ static void _plist_array_post_insert(plist_t node, plist_t item, long n) | |||
| 698 | 698 | ||
| 699 | void plist_array_set_item(plist_t node, plist_t item, uint32_t n) | 699 | void plist_array_set_item(plist_t node, plist_t item, uint32_t n) |
| 700 | { | 700 | { |
| 701 | if (!item) { | 701 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { |
| 702 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); | ||
| 702 | return; | 703 | return; |
| 703 | } | 704 | } |
| 704 | if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) | 705 | node_t it = (node_t)item; |
| 706 | if (it->parent != NULL) { | ||
| 707 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); | ||
| 708 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); | ||
| 709 | return; | ||
| 710 | } | ||
| 711 | plist_t old_item = plist_array_get_item(node, n); | ||
| 712 | if (old_item) | ||
| 705 | { | 713 | { |
| 706 | plist_t old_item = plist_array_get_item(node, n); | 714 | int idx = plist_free_node((node_t)old_item); |
| 707 | if (old_item) | 715 | assert(idx >= 0); |
| 708 | { | 716 | if (idx < 0) { |
| 709 | int idx = plist_free_node((node_t)old_item); | 717 | return; |
| 710 | assert(idx >= 0); | 718 | } |
| 711 | if (idx < 0) { | 719 | node_insert((node_t)node, idx, (node_t)item); |
| 712 | return; | 720 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| 713 | } | 721 | if (pa) { |
| 714 | node_insert((node_t)node, idx, (node_t)item); | 722 | ptr_array_set(pa, item, idx); |
| 715 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; | ||
| 716 | if (pa) { | ||
| 717 | ptr_array_set(pa, item, idx); | ||
| 718 | } | ||
| 719 | } | 723 | } |
| 720 | } | 724 | } |
| 721 | } | 725 | } |
| 722 | 726 | ||
| 723 | void plist_array_append_item(plist_t node, plist_t item) | 727 | void plist_array_append_item(plist_t node, plist_t item) |
| 724 | { | 728 | { |
| 725 | if (!item) { | 729 | if (!PLIST_IS_ARRAY(node) || !item) { |
| 730 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p)\n", __func__, node, item); | ||
| 726 | return; | 731 | return; |
| 727 | } | 732 | } |
| 728 | if (node && PLIST_ARRAY == plist_get_node_type(node)) | 733 | node_t it = (node_t)item; |
| 729 | { | 734 | if (it->parent != NULL) { |
| 730 | node_attach((node_t)node, (node_t)item); | 735 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); |
| 731 | _plist_array_post_insert(node, item, -1); | 736 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); |
| 737 | return; | ||
| 732 | } | 738 | } |
| 739 | node_attach((node_t)node, (node_t)item); | ||
| 740 | _plist_array_post_insert(node, item, -1); | ||
| 733 | } | 741 | } |
| 734 | 742 | ||
| 735 | void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) | 743 | void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) |
| 736 | { | 744 | { |
| 737 | if (!item) { | 745 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { |
| 746 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); | ||
| 738 | return; | 747 | return; |
| 739 | } | 748 | } |
| 740 | if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) | 749 | node_t it = (node_t)item; |
| 741 | { | 750 | if (it->parent != NULL) { |
| 742 | node_insert((node_t)node, n, (node_t)item); | 751 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); |
| 743 | _plist_array_post_insert(node, item, (long)n); | 752 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); |
| 753 | return; | ||
| 744 | } | 754 | } |
| 755 | node_insert((node_t)node, n, (node_t)item); | ||
| 756 | _plist_array_post_insert(node, item, (long)n); | ||
| 745 | } | 757 | } |
| 746 | 758 | ||
| 747 | void plist_array_remove_item(plist_t node, uint32_t n) | 759 | void plist_array_remove_item(plist_t node, uint32_t n) |
| @@ -905,44 +917,49 @@ plist_t plist_dict_get_item(plist_t node, const char* key) | |||
| 905 | 917 | ||
| 906 | void plist_dict_set_item(plist_t node, const char* key, plist_t item) | 918 | void plist_dict_set_item(plist_t node, const char* key, plist_t item) |
| 907 | { | 919 | { |
| 908 | if (!item) { | 920 | if (!PLIST_IS_DICT(node) || !key || !item) { |
| 921 | PLIST_ERR("invalid argument passed to %s (node=%p, key=%p, item=%p)\n", __func__, node, key, item); | ||
| 909 | return; | 922 | return; |
| 910 | } | 923 | } |
| 911 | if (node && PLIST_DICT == plist_get_node_type(node)) { | 924 | node_t it = (node_t)item; |
| 912 | plist_t old_item = plist_dict_get_item(node, key); | 925 | if (it->parent != NULL) { |
| 913 | plist_t key_node = NULL; | 926 | assert(it->parent == NULL && "item already has a parent"); |
| 927 | PLIST_ERR("%s: item already has a parent\n", __func__); | ||
| 928 | return; | ||
| 929 | } | ||
| 930 | plist_t old_item = plist_dict_get_item(node, key); | ||
| 931 | plist_t key_node = NULL; | ||
| 914 | if (old_item) { | 932 | if (old_item) { |
| 915 | int idx = plist_free_node((node_t)old_item); | 933 | int idx = plist_free_node((node_t)old_item); |
| 916 | assert(idx >= 0); | 934 | assert(idx >= 0); |
| 917 | if (idx < 0) { | 935 | if (idx < 0) { |
| 918 | return; | 936 | return; |
| 919 | } | ||
| 920 | node_insert((node_t)node, idx, (node_t)item); | ||
| 921 | key_node = node_prev_sibling((node_t)item); | ||
| 922 | } else { | ||
| 923 | key_node = plist_new_key(key); | ||
| 924 | node_attach((node_t)node, (node_t)key_node); | ||
| 925 | node_attach((node_t)node, (node_t)item); | ||
| 926 | } | 937 | } |
| 938 | node_insert((node_t)node, idx, (node_t)item); | ||
| 939 | key_node = node_prev_sibling((node_t)item); | ||
| 940 | } else { | ||
| 941 | key_node = plist_new_key(key); | ||
| 942 | node_attach((node_t)node, (node_t)key_node); | ||
| 943 | node_attach((node_t)node, (node_t)item); | ||
| 944 | } | ||
| 927 | 945 | ||
| 928 | hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; | 946 | hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| 929 | if (ht) { | 947 | if (ht) { |
| 930 | /* store pointer to item in hash table */ | 948 | /* store pointer to item in hash table */ |
| 931 | hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item); | 949 | hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item); |
| 932 | } else { | 950 | } else { |
| 933 | if (((node_t)node)->count > 500) { | 951 | if (((node_t)node)->count > 500) { |
| 934 | /* make new hash table */ | 952 | /* make new hash table */ |
| 935 | ht = hash_table_new(dict_key_hash, dict_key_compare, NULL); | 953 | ht = hash_table_new(dict_key_hash, dict_key_compare, NULL); |
| 936 | /* calculate the hashes for all entries we have so far */ | 954 | /* calculate the hashes for all entries we have so far */ |
| 937 | plist_t current = NULL; | 955 | plist_t current = NULL; |
| 938 | for (current = (plist_t)node_first_child((node_t)node); | 956 | for (current = (plist_t)node_first_child((node_t)node); |
| 939 | ht && current; | 957 | ht && current; |
| 940 | current = (plist_t)node_next_sibling(node_next_sibling((node_t)current))) | 958 | current = (plist_t)node_next_sibling(node_next_sibling((node_t)current))) |
| 941 | { | 959 | { |
| 942 | hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current)); | 960 | hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current)); |
| 943 | } | ||
| 944 | ((plist_data_t)((node_t)node)->data)->hashtable = ht; | ||
| 945 | } | 961 | } |
| 962 | ((plist_data_t)((node_t)node)->data)->hashtable = ht; | ||
| 946 | } | 963 | } |
| 947 | } | 964 | } |
| 948 | } | 965 | } |
