diff options
| -rw-r--r-- | include/plist/plist.h | 13 | ||||
| -rw-r--r-- | src/plist.c | 109 |
2 files changed, 81 insertions, 41 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index 8ed9063..b46b9a9 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h | |||
| @@ -400,6 +400,12 @@ extern "C" | |||
| 400 | */ | 400 | */ |
| 401 | PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); | 401 | PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); |
| 402 | 402 | ||
| 403 | /** | ||
| 404 | * Free #PLIST_ARRAY iterator. | ||
| 405 | * | ||
| 406 | * @param iter Iterator to free. | ||
| 407 | */ | ||
| 408 | PLIST_API void plist_array_free_iter(plist_array_iter iter); | ||
| 403 | 409 | ||
| 404 | /******************************************** | 410 | /******************************************** |
| 405 | * * | 411 | * * |
| @@ -438,6 +444,13 @@ extern "C" | |||
| 438 | PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); | 444 | PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); |
| 439 | 445 | ||
| 440 | /** | 446 | /** |
| 447 | * Free #PLIST_DICT iterator. | ||
| 448 | * | ||
| 449 | * @param iter Iterator to free. | ||
| 450 | */ | ||
| 451 | PLIST_API void plist_dict_free_iter(plist_dict_iter iter); | ||
| 452 | |||
| 453 | /** | ||
| 441 | * Get key associated key to an item. Item must be member of a dictionary. | 454 | * Get key associated key to an item. Item must be member of a dictionary. |
| 442 | * | 455 | * |
| 443 | * @param node the item | 456 | * @param node the item |
diff --git a/src/plist.c b/src/plist.c index 22ef4d7..82161f1 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -1092,32 +1092,41 @@ void plist_array_item_remove(plist_t node) | |||
| 1092 | } | 1092 | } |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | typedef struct { | ||
| 1096 | node_t cur; | ||
| 1097 | } plist_array_iter_private; | ||
| 1098 | |||
| 1095 | void plist_array_new_iter(plist_t node, plist_array_iter *iter) | 1099 | void plist_array_new_iter(plist_t node, plist_array_iter *iter) |
| 1096 | { | 1100 | { |
| 1097 | if (iter) | 1101 | if (!iter) return; |
| 1098 | { | 1102 | *iter = NULL; |
| 1099 | *iter = malloc(sizeof(node_t)); | 1103 | if (!PLIST_IS_ARRAY(node)) return; |
| 1100 | *((node_t*)(*iter)) = node_first_child((node_t)node); | 1104 | |
| 1101 | } | 1105 | plist_array_iter_private* it = (plist_array_iter_private*)malloc(sizeof(*it)); |
| 1106 | if (!it) return; | ||
| 1107 | it->cur = node_first_child((node_t)node); | ||
| 1108 | *iter = (plist_array_iter)it; | ||
| 1102 | } | 1109 | } |
| 1103 | 1110 | ||
| 1104 | void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item) | 1111 | void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item) |
| 1105 | { | 1112 | { |
| 1106 | node_t* iter_node = (node_t*)iter; | 1113 | if (item) *item = NULL; |
| 1114 | if (!iter) return; | ||
| 1115 | if (!PLIST_IS_ARRAY(node)) return; | ||
| 1107 | 1116 | ||
| 1108 | if (item) | 1117 | plist_array_iter_private* it = (plist_array_iter_private*)iter; |
| 1109 | { | 1118 | node_t cur = it->cur; |
| 1110 | *item = NULL; | 1119 | if (!cur) return; |
| 1111 | } | ||
| 1112 | 1120 | ||
| 1113 | if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node) | 1121 | if (item) { |
| 1114 | { | 1122 | *item = (plist_t)cur; |
| 1115 | if (item) | ||
| 1116 | { | ||
| 1117 | *item = (plist_t)(*iter_node); | ||
| 1118 | } | ||
| 1119 | *iter_node = node_next_sibling(*iter_node); | ||
| 1120 | } | 1123 | } |
| 1124 | it->cur = node_next_sibling(cur); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | void plist_array_free_iter(plist_array_iter iter) | ||
| 1128 | { | ||
| 1129 | free(iter); | ||
| 1121 | } | 1130 | } |
| 1122 | 1131 | ||
| 1123 | uint32_t plist_dict_get_size(plist_t node) | 1132 | uint32_t plist_dict_get_size(plist_t node) |
| @@ -1130,41 +1139,59 @@ uint32_t plist_dict_get_size(plist_t node) | |||
| 1130 | return ret; | 1139 | return ret; |
| 1131 | } | 1140 | } |
| 1132 | 1141 | ||
| 1142 | typedef struct { | ||
| 1143 | node_t cur; | ||
| 1144 | } plist_dict_iter_private; | ||
| 1145 | |||
| 1133 | void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) | 1146 | void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) |
| 1134 | { | 1147 | { |
| 1135 | if (iter) | 1148 | if (!iter) return; |
| 1136 | { | 1149 | *iter = NULL; |
| 1137 | *iter = malloc(sizeof(node_t)); | 1150 | if (!PLIST_IS_DICT(node)) return; |
| 1138 | *((node_t*)(*iter)) = node_first_child((node_t)node); | 1151 | |
| 1139 | } | 1152 | plist_dict_iter_private* it = (plist_dict_iter_private*)malloc(sizeof(*it)); |
| 1153 | if (!it) return; | ||
| 1154 | it->cur = node_first_child((node_t)node); | ||
| 1155 | *iter = (plist_dict_iter)it; | ||
| 1140 | } | 1156 | } |
| 1141 | 1157 | ||
| 1142 | void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) | 1158 | void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) |
| 1143 | { | 1159 | { |
| 1144 | node_t* iter_node = (node_t*)iter; | 1160 | if (key) *key = NULL; |
| 1161 | if (val) *val = NULL; | ||
| 1162 | if (!iter) return; | ||
| 1163 | if (!PLIST_IS_DICT(node)) return; | ||
| 1145 | 1164 | ||
| 1146 | if (key) | 1165 | plist_dict_iter_private* it = (plist_dict_iter_private*)iter; |
| 1147 | { | 1166 | |
| 1148 | *key = NULL; | 1167 | node_t k = it->cur; |
| 1168 | if (!k) return; | ||
| 1169 | |||
| 1170 | if (!PLIST_IS_KEY((plist_t)k)) { | ||
| 1171 | // malformed dict, terminate iteration | ||
| 1172 | it->cur = NULL; | ||
| 1173 | return; | ||
| 1149 | } | 1174 | } |
| 1150 | if (val) | 1175 | |
| 1151 | { | 1176 | node_t v = node_next_sibling(k); |
| 1152 | *val = NULL; | 1177 | if (!v) { |
| 1178 | // key without value, terminate iteration | ||
| 1179 | it->cur = NULL; | ||
| 1180 | return; | ||
| 1153 | } | 1181 | } |
| 1154 | 1182 | ||
| 1155 | if (node && PLIST_DICT == plist_get_node_type(node) && *iter_node) | 1183 | if (key) { |
| 1156 | { | 1184 | plist_get_key_val((plist_t)k, key); |
| 1157 | if (key) | ||
| 1158 | { | ||
| 1159 | plist_get_key_val((plist_t)(*iter_node), key); | ||
| 1160 | } | ||
| 1161 | *iter_node = node_next_sibling(*iter_node); | ||
| 1162 | if (val) | ||
| 1163 | { | ||
| 1164 | *val = (plist_t)(*iter_node); | ||
| 1165 | } | ||
| 1166 | *iter_node = node_next_sibling(*iter_node); | ||
| 1167 | } | 1185 | } |
| 1186 | if (val) { | ||
| 1187 | *val = (plist_t)v; | ||
| 1188 | } | ||
| 1189 | it->cur = node_next_sibling(v); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | void plist_dict_free_iter(plist_dict_iter iter) | ||
| 1193 | { | ||
| 1194 | free(iter); | ||
| 1168 | } | 1195 | } |
| 1169 | 1196 | ||
| 1170 | void plist_dict_get_item_key(plist_t node, char **key) | 1197 | void plist_dict_get_item_key(plist_t node, char **key) |
