diff options
Diffstat (limited to 'src/plist.c')
| -rw-r--r-- | src/plist.c | 174 |
1 files changed, 94 insertions, 80 deletions
diff --git a/src/plist.c b/src/plist.c index 2ad1b0a..7def2b6 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -953,8 +953,7 @@ plist_t plist_copy(plist_t node) | |||
| 953 | uint32_t plist_array_get_size(plist_t node) | 953 | uint32_t plist_array_get_size(plist_t node) |
| 954 | { | 954 | { |
| 955 | uint32_t ret = 0; | 955 | uint32_t ret = 0; |
| 956 | if (node && PLIST_ARRAY == plist_get_node_type(node)) | 956 | if (PLIST_IS_ARRAY(node)) { |
| 957 | { | ||
| 958 | ret = node_n_children((node_t)node); | 957 | ret = node_n_children((node_t)node); |
| 959 | } | 958 | } |
| 960 | return ret; | 959 | return ret; |
| @@ -963,8 +962,7 @@ uint32_t plist_array_get_size(plist_t node) | |||
| 963 | plist_t plist_array_get_item(plist_t node, uint32_t n) | 962 | plist_t plist_array_get_item(plist_t node, uint32_t n) |
| 964 | { | 963 | { |
| 965 | plist_t ret = NULL; | 964 | plist_t ret = NULL; |
| 966 | if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) | 965 | if (PLIST_IS_ARRAY(node) && n < INT_MAX) { |
| 967 | { | ||
| 968 | ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; | 966 | ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| 969 | if (pa) { | 967 | if (pa) { |
| 970 | ret = (plist_t)ptr_array_index(pa, n); | 968 | ret = (plist_t)ptr_array_index(pa, n); |
| @@ -977,10 +975,9 @@ plist_t plist_array_get_item(plist_t node, uint32_t n) | |||
| 977 | 975 | ||
| 978 | uint32_t plist_array_get_item_index(plist_t node) | 976 | uint32_t plist_array_get_item_index(plist_t node) |
| 979 | { | 977 | { |
| 980 | plist_t father = plist_get_parent(node); | 978 | plist_t parent = plist_get_parent(node); |
| 981 | if (PLIST_ARRAY == plist_get_node_type(father)) | 979 | if (PLIST_IS_ARRAY(parent)) { |
| 982 | { | 980 | return node_child_position((node_t)parent, (node_t)node); |
| 983 | return node_child_position((node_t)father, (node_t)node); | ||
| 984 | } | 981 | } |
| 985 | return UINT_MAX; | 982 | return UINT_MAX; |
| 986 | } | 983 | } |
| @@ -1039,25 +1036,25 @@ static void _plist_array_post_set(plist_t node, plist_t item, long n) | |||
| 1039 | } | 1036 | } |
| 1040 | } | 1037 | } |
| 1041 | 1038 | ||
| 1042 | void plist_array_set_item(plist_t node, plist_t item, uint32_t n) | 1039 | plist_err_t plist_array_set_item(plist_t node, plist_t item, uint32_t n) |
| 1043 | { | 1040 | { |
| 1044 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { | 1041 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { |
| 1045 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); | 1042 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); |
| 1046 | return; | 1043 | return PLIST_ERR_INVALID_ARG; |
| 1047 | } | 1044 | } |
| 1048 | node_t it = (node_t)item; | 1045 | node_t it = (node_t)item; |
| 1049 | if (it->parent != NULL) { | 1046 | if (it->parent != NULL) { |
| 1050 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); | 1047 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); |
| 1051 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); | 1048 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); |
| 1052 | return; | 1049 | return PLIST_ERR_INVALID_ARG; |
| 1053 | } | 1050 | } |
| 1054 | plist_t old_item = plist_array_get_item(node, n); | 1051 | plist_t old_item = plist_array_get_item(node, n); |
| 1055 | if (!old_item) return; | 1052 | if (!old_item) return PLIST_ERR_INVALID_ARG; |
| 1056 | 1053 | ||
| 1057 | int idx = node_detach((node_t)node, (node_t)old_item); | 1054 | int idx = node_detach((node_t)node, (node_t)old_item); |
| 1058 | if (idx < 0) { | 1055 | if (idx < 0) { |
| 1059 | PLIST_ERR("%s: Failed to detach old item (err=%d)\n", __func__, idx); | 1056 | PLIST_ERR("%s: Failed to detach old item (err=%d)\n", __func__, idx); |
| 1060 | return; | 1057 | return PLIST_ERR_UNKNOWN; |
| 1061 | } | 1058 | } |
| 1062 | 1059 | ||
| 1063 | int r = node_insert((node_t)node, (unsigned)idx, (node_t)item); | 1060 | int r = node_insert((node_t)node, (unsigned)idx, (node_t)item); |
| @@ -1066,87 +1063,99 @@ void plist_array_set_item(plist_t node, plist_t item, uint32_t n) | |||
| 1066 | if (rb == NODE_ERR_SUCCESS) { | 1063 | if (rb == NODE_ERR_SUCCESS) { |
| 1067 | _plist_array_post_set(node, old_item, idx); // restore cache correctly | 1064 | _plist_array_post_set(node, old_item, idx); // restore cache correctly |
| 1068 | PLIST_ERR("%s: failed to insert replacement (idx=%d err=%d); rollback succeeded\n", __func__, idx, r); | 1065 | PLIST_ERR("%s: failed to insert replacement (idx=%d err=%d); rollback succeeded\n", __func__, idx, r); |
| 1066 | return (r == NODE_ERR_NO_MEM) ? PLIST_ERR_NO_MEM : PLIST_ERR_UNKNOWN; | ||
| 1069 | } else { | 1067 | } else { |
| 1070 | PLIST_ERR("%s: insert failed (err=%d) and rollback failed (err=%d); array now missing element at idx=%d\n", __func__, r, rb, idx); | 1068 | PLIST_ERR("%s: insert failed (err=%d) and rollback failed (err=%d); array now missing element at idx=%d\n", __func__, r, rb, idx); |
| 1069 | return PLIST_ERR_UNKNOWN; | ||
| 1071 | } | 1070 | } |
| 1072 | return; | ||
| 1073 | } | 1071 | } |
| 1074 | 1072 | ||
| 1075 | _plist_array_post_set(node, item, idx); // update cache | 1073 | _plist_array_post_set(node, item, idx); // update cache |
| 1076 | plist_free_node((node_t)old_item); | 1074 | plist_free_node((node_t)old_item); |
| 1075 | |||
| 1076 | return PLIST_ERR_SUCCESS; | ||
| 1077 | } | 1077 | } |
| 1078 | 1078 | ||
| 1079 | void plist_array_append_item(plist_t node, plist_t item) | 1079 | plist_err_t plist_array_append_item(plist_t node, plist_t item) |
| 1080 | { | 1080 | { |
| 1081 | if (!PLIST_IS_ARRAY(node) || !item) { | 1081 | if (!PLIST_IS_ARRAY(node) || !item) { |
| 1082 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p)\n", __func__, node, item); | 1082 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p)\n", __func__, node, item); |
| 1083 | return; | 1083 | return PLIST_ERR_INVALID_ARG; |
| 1084 | } | 1084 | } |
| 1085 | node_t it = (node_t)item; | 1085 | node_t it = (node_t)item; |
| 1086 | if (it->parent != NULL) { | 1086 | if (it->parent != NULL) { |
| 1087 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); | 1087 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); |
| 1088 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); | 1088 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); |
| 1089 | return; | 1089 | return PLIST_ERR_INVALID_ARG; |
| 1090 | } | 1090 | } |
| 1091 | 1091 | ||
| 1092 | int r = node_attach((node_t)node, (node_t)item); | 1092 | int r = node_attach((node_t)node, (node_t)item); |
| 1093 | if (r != NODE_ERR_SUCCESS) { | 1093 | if (r != NODE_ERR_SUCCESS) { |
| 1094 | PLIST_ERR("%s: failed to append item (err=%d)\n", __func__, r); | 1094 | PLIST_ERR("%s: failed to append item (err=%d)\n", __func__, r); |
| 1095 | return; | 1095 | return PLIST_ERR_UNKNOWN; |
| 1096 | } | 1096 | } |
| 1097 | _plist_array_post_insert(node, item, -1); | 1097 | _plist_array_post_insert(node, item, -1); |
| 1098 | |||
| 1099 | return PLIST_ERR_SUCCESS; | ||
| 1098 | } | 1100 | } |
| 1099 | 1101 | ||
| 1100 | void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) | 1102 | plist_err_t plist_array_insert_item(plist_t node, plist_t item, uint32_t n) |
| 1101 | { | 1103 | { |
| 1102 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { | 1104 | if (!PLIST_IS_ARRAY(node) || !item || n >= INT_MAX) { |
| 1103 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); | 1105 | PLIST_ERR("invalid argument passed to %s (node=%p, item=%p, n=%u)\n", __func__, node, item, n); |
| 1104 | return; | 1106 | return PLIST_ERR_INVALID_ARG; |
| 1105 | } | 1107 | } |
| 1106 | node_t it = (node_t)item; | 1108 | node_t it = (node_t)item; |
| 1107 | if (it->parent != NULL) { | 1109 | if (it->parent != NULL) { |
| 1108 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); | 1110 | assert(it->parent == NULL && "item already has a parent; use plist_copy() or detach first"); |
| 1109 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); | 1111 | PLIST_ERR("%s: item already has a parent; use plist_copy() or detach first\n", __func__); |
| 1110 | return; | 1112 | return PLIST_ERR_INVALID_ARG; |
| 1111 | } | 1113 | } |
| 1112 | 1114 | ||
| 1113 | int r = node_insert((node_t)node, n, (node_t)item); | 1115 | int r = node_insert((node_t)node, n, (node_t)item); |
| 1114 | if (r != NODE_ERR_SUCCESS) { | 1116 | if (r != NODE_ERR_SUCCESS) { |
| 1115 | PLIST_ERR("%s: Failed to insert item at index %u (err=%d)\n", __func__, n, r); | 1117 | PLIST_ERR("%s: Failed to insert item at index %u (err=%d)\n", __func__, n, r); |
| 1116 | return; | 1118 | return PLIST_ERR_UNKNOWN; |
| 1117 | } | 1119 | } |
| 1118 | _plist_array_post_insert(node, item, (long)n); | 1120 | _plist_array_post_insert(node, item, (long)n); |
| 1121 | |||
| 1122 | return PLIST_ERR_SUCCESS; | ||
| 1119 | } | 1123 | } |
| 1120 | 1124 | ||
| 1121 | void plist_array_remove_item(plist_t node, uint32_t n) | 1125 | plist_err_t plist_array_remove_item(plist_t node, uint32_t n) |
| 1122 | { | 1126 | { |
| 1123 | if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX) | 1127 | if (!PLIST_IS_ARRAY(node) || n >= INT_MAX || n > plist_array_get_size(node)) { |
| 1124 | { | 1128 | PLIST_ERR("invalid argument passed to %s (node=%p, n=%u)\n", __func__, node, n); |
| 1125 | plist_t old_item = plist_array_get_item(node, n); | 1129 | return PLIST_ERR_INVALID_ARG; |
| 1126 | if (old_item) | 1130 | } |
| 1127 | { | 1131 | |
| 1128 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; | 1132 | plist_t old_item = plist_array_get_item(node, n); |
| 1129 | if (pa) { | 1133 | if (!old_item) { |
| 1130 | ptr_array_remove(pa, n); | 1134 | PLIST_ERR("item not found at index %u\n", n); |
| 1131 | } | 1135 | return PLIST_ERR_INVALID_ARG; |
| 1132 | plist_free(old_item); | 1136 | } |
| 1133 | } | 1137 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| 1138 | if (pa) { | ||
| 1139 | ptr_array_remove(pa, n); | ||
| 1134 | } | 1140 | } |
| 1141 | plist_free(old_item); | ||
| 1142 | |||
| 1143 | return PLIST_ERR_SUCCESS; | ||
| 1135 | } | 1144 | } |
| 1136 | 1145 | ||
| 1137 | void plist_array_item_remove(plist_t node) | 1146 | plist_err_t plist_array_item_remove(plist_t item) |
| 1138 | { | 1147 | { |
| 1139 | plist_t father = plist_get_parent(node); | 1148 | plist_t parent = plist_get_parent(item); |
| 1140 | if (PLIST_ARRAY == plist_get_node_type(father)) | 1149 | if (PLIST_IS_ARRAY(parent)) { |
| 1141 | { | 1150 | int n = node_child_position((node_t)parent, (node_t)item); |
| 1142 | int n = node_child_position((node_t)father, (node_t)node); | 1151 | if (n < 0) return PLIST_ERR_INVALID_ARG; |
| 1143 | if (n < 0) return; | 1152 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)parent)->data)->hashtable; |
| 1144 | ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)father)->data)->hashtable; | ||
| 1145 | if (pa) { | 1153 | if (pa) { |
| 1146 | ptr_array_remove(pa, n); | 1154 | ptr_array_remove(pa, n); |
| 1147 | } | 1155 | } |
| 1148 | plist_free(node); | 1156 | plist_free(item); |
| 1149 | } | 1157 | } |
| 1158 | return PLIST_ERR_SUCCESS; | ||
| 1150 | } | 1159 | } |
| 1151 | 1160 | ||
| 1152 | typedef struct { | 1161 | typedef struct { |
| @@ -1189,8 +1198,7 @@ void plist_array_free_iter(plist_array_iter iter) | |||
| 1189 | uint32_t plist_dict_get_size(plist_t node) | 1198 | uint32_t plist_dict_get_size(plist_t node) |
| 1190 | { | 1199 | { |
| 1191 | uint32_t ret = 0; | 1200 | uint32_t ret = 0; |
| 1192 | if (node && PLIST_DICT == plist_get_node_type(node)) | 1201 | if (PLIST_IS_DICT(node)) { |
| 1193 | { | ||
| 1194 | ret = node_n_children((node_t)node) / 2; | 1202 | ret = node_n_children((node_t)node) / 2; |
| 1195 | } | 1203 | } |
| 1196 | return ret; | 1204 | return ret; |
| @@ -1253,9 +1261,8 @@ void plist_dict_free_iter(plist_dict_iter iter) | |||
| 1253 | 1261 | ||
| 1254 | void plist_dict_get_item_key(plist_t node, char **key) | 1262 | void plist_dict_get_item_key(plist_t node, char **key) |
| 1255 | { | 1263 | { |
| 1256 | plist_t father = plist_get_parent(node); | 1264 | plist_t parent = plist_get_parent(node); |
| 1257 | if (PLIST_DICT == plist_get_node_type(father)) | 1265 | if (PLIST_IS_DICT(parent)) { |
| 1258 | { | ||
| 1259 | plist_get_key_val( (plist_t) node_prev_sibling((node_t)node), key); | 1266 | plist_get_key_val( (plist_t) node_prev_sibling((node_t)node), key); |
| 1260 | } | 1267 | } |
| 1261 | } | 1268 | } |
| @@ -1263,9 +1270,8 @@ void plist_dict_get_item_key(plist_t node, char **key) | |||
| 1263 | plist_t plist_dict_item_get_key(plist_t node) | 1270 | plist_t plist_dict_item_get_key(plist_t node) |
| 1264 | { | 1271 | { |
| 1265 | plist_t ret = NULL; | 1272 | plist_t ret = NULL; |
| 1266 | plist_t father = plist_get_parent(node); | 1273 | plist_t parent = plist_get_parent(node); |
| 1267 | if (PLIST_DICT == plist_get_node_type(father)) | 1274 | if (PLIST_IS_DICT(parent)) { |
| 1268 | { | ||
| 1269 | ret = (plist_t)node_prev_sibling((node_t)node); | 1275 | ret = (plist_t)node_prev_sibling((node_t)node); |
| 1270 | } | 1276 | } |
| 1271 | return ret; | 1277 | return ret; |
| @@ -1311,17 +1317,17 @@ plist_t plist_dict_get_item(plist_t node, const char* key) | |||
| 1311 | return ret; | 1317 | return ret; |
| 1312 | } | 1318 | } |
| 1313 | 1319 | ||
| 1314 | void plist_dict_set_item(plist_t node, const char* key, plist_t item) | 1320 | plist_err_t plist_dict_set_item(plist_t node, const char* key, plist_t item) |
| 1315 | { | 1321 | { |
| 1316 | if (!PLIST_IS_DICT(node) || !key || !item) { | 1322 | if (!PLIST_IS_DICT(node) || !key || !item) { |
| 1317 | PLIST_ERR("invalid argument passed to %s (node=%p, key=%p, item=%p)\n", __func__, node, key, item); | 1323 | PLIST_ERR("invalid argument passed to %s (node=%p, key=%p, item=%p)\n", __func__, node, key, item); |
| 1318 | return; | 1324 | return PLIST_ERR_INVALID_ARG; |
| 1319 | } | 1325 | } |
| 1320 | node_t it = (node_t)item; | 1326 | node_t it = (node_t)item; |
| 1321 | if (it->parent != NULL) { | 1327 | if (it->parent != NULL) { |
| 1322 | assert(it->parent == NULL && "item already has a parent"); | 1328 | assert(it->parent == NULL && "item already has a parent"); |
| 1323 | PLIST_ERR("%s: item already has a parent\n", __func__); | 1329 | PLIST_ERR("%s: item already has a parent\n", __func__); |
| 1324 | return; | 1330 | return PLIST_ERR_INVALID_ARG; |
| 1325 | } | 1331 | } |
| 1326 | 1332 | ||
| 1327 | hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; | 1333 | hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| @@ -1335,18 +1341,18 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1335 | node_t old_key = node_prev_sibling(old_val); | 1341 | node_t old_key = node_prev_sibling(old_val); |
| 1336 | if (!old_key) { | 1342 | if (!old_key) { |
| 1337 | PLIST_ERR("%s: corrupt dict (value without key)\n", __func__); | 1343 | PLIST_ERR("%s: corrupt dict (value without key)\n", __func__); |
| 1338 | return; | 1344 | return PLIST_ERR_UNKNOWN; |
| 1339 | } | 1345 | } |
| 1340 | if (!PLIST_IS_KEY((plist_t)old_key)) { | 1346 | if (!PLIST_IS_KEY((plist_t)old_key)) { |
| 1341 | PLIST_ERR("%s: corrupt dict ('key' node is not PLIST_KEY\n", __func__); | 1347 | PLIST_ERR("%s: corrupt dict ('key' node is not PLIST_KEY\n", __func__); |
| 1342 | return; | 1348 | return PLIST_ERR_UNKNOWN; |
| 1343 | } | 1349 | } |
| 1344 | 1350 | ||
| 1345 | // detach old value (do NOT free yet) | 1351 | // detach old value (do NOT free yet) |
| 1346 | int idx = node_detach((node_t)node, old_val); | 1352 | int idx = node_detach((node_t)node, old_val); |
| 1347 | if (idx < 0) { | 1353 | if (idx < 0) { |
| 1348 | PLIST_ERR("%s: failed to detach old value (err=%d)\n", __func__, idx); | 1354 | PLIST_ERR("%s: failed to detach old value (err=%d)\n", __func__, idx); |
| 1349 | return; | 1355 | return PLIST_ERR_UNKNOWN; |
| 1350 | } | 1356 | } |
| 1351 | 1357 | ||
| 1352 | // insert new value at same position | 1358 | // insert new value at same position |
| @@ -1358,7 +1364,7 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1358 | hash_table_insert(ht, ((node_t)old_key)->data, old_item); | 1364 | hash_table_insert(ht, ((node_t)old_key)->data, old_item); |
| 1359 | } | 1365 | } |
| 1360 | PLIST_ERR("%s: failed to replace dict value (err=%d)\n", __func__, r); | 1366 | PLIST_ERR("%s: failed to replace dict value (err=%d)\n", __func__, r); |
| 1361 | return; | 1367 | return PLIST_ERR_UNKNOWN; |
| 1362 | } | 1368 | } |
| 1363 | key_node = old_key; | 1369 | key_node = old_key; |
| 1364 | 1370 | ||
| @@ -1372,13 +1378,13 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1372 | } else { | 1378 | } else { |
| 1373 | // --- INSERT NEW KEY/VALUE PAIR --- | 1379 | // --- INSERT NEW KEY/VALUE PAIR --- |
| 1374 | key_node = plist_new_key(key); | 1380 | key_node = plist_new_key(key); |
| 1375 | if (!key_node) return; | 1381 | if (!key_node) return PLIST_ERR_NO_MEM; |
| 1376 | 1382 | ||
| 1377 | int r = node_attach((node_t)node, (node_t)key_node); | 1383 | int r = node_attach((node_t)node, (node_t)key_node); |
| 1378 | if (r != NODE_ERR_SUCCESS) { | 1384 | if (r != NODE_ERR_SUCCESS) { |
| 1379 | plist_free_node((node_t)key_node); | 1385 | plist_free_node((node_t)key_node); |
| 1380 | PLIST_ERR("%s: failed to attach dict key (err=%d)\n", __func__, r); | 1386 | PLIST_ERR("%s: failed to attach dict key (err=%d)\n", __func__, r); |
| 1381 | return; | 1387 | return PLIST_ERR_UNKNOWN; |
| 1382 | } | 1388 | } |
| 1383 | r = node_attach((node_t)node, (node_t)item); | 1389 | r = node_attach((node_t)node, (node_t)item); |
| 1384 | if (r != NODE_ERR_SUCCESS) { | 1390 | if (r != NODE_ERR_SUCCESS) { |
| @@ -1386,7 +1392,7 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1386 | node_detach((node_t)node, (node_t)key_node); | 1392 | node_detach((node_t)node, (node_t)key_node); |
| 1387 | plist_free_node((node_t)key_node); | 1393 | plist_free_node((node_t)key_node); |
| 1388 | PLIST_ERR("%s: failed to attach dict value (err=%d)\n", __func__, r); | 1394 | PLIST_ERR("%s: failed to attach dict value (err=%d)\n", __func__, r); |
| 1389 | return; | 1395 | return PLIST_ERR_UNKNOWN; |
| 1390 | } | 1396 | } |
| 1391 | 1397 | ||
| 1392 | if (ht) { | 1398 | if (ht) { |
| @@ -1406,37 +1412,44 @@ void plist_dict_set_item(plist_t node, const char* key, plist_t item) | |||
| 1406 | ((plist_data_t)((node_t)node)->data)->hashtable = ht; | 1412 | ((plist_data_t)((node_t)node)->data)->hashtable = ht; |
| 1407 | } | 1413 | } |
| 1408 | } | 1414 | } |
| 1415 | return PLIST_ERR_SUCCESS; | ||
| 1409 | } | 1416 | } |
| 1410 | 1417 | ||
| 1411 | void plist_dict_remove_item(plist_t node, const char* key) | 1418 | plist_err_t plist_dict_remove_item(plist_t node, const char* key) |
| 1412 | { | 1419 | { |
| 1413 | if (node && PLIST_DICT == plist_get_node_type(node)) | 1420 | if (!PLIST_IS_DICT(node) || !key) { |
| 1414 | { | 1421 | PLIST_ERR("invalid argument passed to %s (node=%p, key=%p)\n", __func__, node, key); |
| 1415 | plist_t old_item = plist_dict_get_item(node, key); | 1422 | return PLIST_ERR_INVALID_ARG; |
| 1416 | if (old_item) | 1423 | } |
| 1417 | { | 1424 | |
| 1418 | plist_t key_node = node_prev_sibling((node_t)old_item); | 1425 | plist_t old_item = plist_dict_get_item(node, key); |
| 1419 | hashtable_t* ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; | 1426 | if (!old_item) { |
| 1420 | if (ht) { | 1427 | PLIST_ERR("item not found for key '%s'\n", key); |
| 1421 | hash_table_remove(ht, ((node_t)key_node)->data); | 1428 | return PLIST_ERR_INVALID_ARG; |
| 1422 | } | 1429 | } |
| 1423 | plist_free(key_node); | 1430 | |
| 1424 | plist_free(old_item); | 1431 | plist_t key_node = node_prev_sibling((node_t)old_item); |
| 1425 | } | 1432 | hashtable_t* ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable; |
| 1433 | if (ht) { | ||
| 1434 | hash_table_remove(ht, ((node_t)key_node)->data); | ||
| 1426 | } | 1435 | } |
| 1436 | plist_free(key_node); | ||
| 1437 | plist_free(old_item); | ||
| 1438 | |||
| 1439 | return PLIST_ERR_SUCCESS; | ||
| 1427 | } | 1440 | } |
| 1428 | 1441 | ||
| 1429 | void plist_dict_merge(plist_t *target, plist_t source) | 1442 | plist_err_t plist_dict_merge(plist_t *target, plist_t source) |
| 1430 | { | 1443 | { |
| 1431 | if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT)) | 1444 | if (!target || !PLIST_IS_DICT(*target) || !PLIST_IS_DICT(source)) |
| 1432 | return; | 1445 | return PLIST_ERR_INVALID_ARG; |
| 1433 | 1446 | ||
| 1434 | char* key = NULL; | 1447 | char* key = NULL; |
| 1435 | plist_dict_iter it = NULL; | 1448 | plist_dict_iter it = NULL; |
| 1436 | plist_t subnode = NULL; | 1449 | plist_t subnode = NULL; |
| 1437 | plist_dict_new_iter(source, &it); | 1450 | plist_dict_new_iter(source, &it); |
| 1438 | if (!it) | 1451 | if (!it) |
| 1439 | return; | 1452 | return PLIST_ERR_NO_MEM; |
| 1440 | 1453 | ||
| 1441 | do { | 1454 | do { |
| 1442 | plist_dict_next_item(source, it, &key, &subnode); | 1455 | plist_dict_next_item(source, it, &key, &subnode); |
| @@ -1448,6 +1461,7 @@ void plist_dict_merge(plist_t *target, plist_t source) | |||
| 1448 | key = NULL; | 1461 | key = NULL; |
| 1449 | } while (1); | 1462 | } while (1); |
| 1450 | free(it); | 1463 | free(it); |
| 1464 | return PLIST_ERR_SUCCESS; | ||
| 1451 | } | 1465 | } |
| 1452 | 1466 | ||
| 1453 | uint8_t plist_dict_get_bool(plist_t dict, const char *key) | 1467 | uint8_t plist_dict_get_bool(plist_t dict, const char *key) |
| @@ -2010,8 +2024,8 @@ static plist_err_t plist_set_element_val(plist_t node, plist_type type, const vo | |||
| 2010 | 2024 | ||
| 2011 | void plist_set_key_val(plist_t node, const char *val) | 2025 | void plist_set_key_val(plist_t node, const char *val) |
| 2012 | { | 2026 | { |
| 2013 | plist_t father = plist_get_parent(node); | 2027 | plist_t parent = plist_get_parent(node); |
| 2014 | plist_t item = plist_dict_get_item(father, val); | 2028 | plist_t item = plist_dict_get_item(parent, val); |
| 2015 | if (item) { | 2029 | if (item) { |
| 2016 | return; | 2030 | return; |
| 2017 | } | 2031 | } |
