summaryrefslogtreecommitdiffstats
path: root/src/out-limd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/out-limd.c')
-rw-r--r--src/out-limd.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/out-limd.c b/src/out-limd.c
index 7d861f8..e281644 100644
--- a/src/out-limd.c
+++ b/src/out-limd.c
@@ -40,6 +40,7 @@
40#include "strbuf.h" 40#include "strbuf.h"
41#include "time64.h" 41#include "time64.h"
42#include "base64.h" 42#include "base64.h"
43#include "hashtable.h"
43 44
44#define MAC_EPOCH 978307200 45#define MAC_EPOCH 978307200
45 46
@@ -278,19 +279,30 @@ static int num_digits_u(uint64_t i)
278 return n; 279 return n;
279} 280}
280 281
281static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, uint32_t indent) 282static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, uint32_t indent, hashtable_t *visited)
282{ 283{
283 plist_data_t data; 284 plist_data_t data;
284 if (!node) { 285 if (!node) {
285 return PLIST_ERR_INVALID_ARG; 286 return PLIST_ERR_INVALID_ARG;
286 } 287 }
288
289 if (hash_table_lookup(visited, node)) {
290#if DEBUG
291 fprintf(stderr, "libplist: ERROR: circular reference detected\n");
292#endif
293 return PLIST_ERR_CIRCULAR_REF;
294 }
295
296 // mark as visited
297 hash_table_insert(visited, node, (void*)1);
298
287 data = plist_get_data(node); 299 data = plist_get_data(node);
288 if (node->children) { 300 if (node->children) {
289 node_t ch; 301 node_t ch;
290 unsigned int n_children = node_n_children(node); 302 unsigned int n_children = node_n_children(node);
291 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { 303 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
292 plist_err_t res = node_estimate_size(ch, size, depth + 1, indent); 304 plist_err_t res = _node_estimate_size(ch, size, depth + 1, indent, visited);
293 if (res < 0) { 305 if (res != PLIST_ERR_SUCCESS) {
294 return res; 306 return res;
295 } 307 }
296 } 308 }
@@ -359,6 +371,15 @@ static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t dept
359 return PLIST_ERR_SUCCESS; 371 return PLIST_ERR_SUCCESS;
360} 372}
361 373
374static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, uint32_t indent)
375{
376 hashtable_t *visited = hash_table_new(plist_node_ptr_hash, plist_node_ptr_compare, NULL);
377 if (!visited) return PLIST_ERR_NO_MEM;
378 plist_err_t err = _node_estimate_size(node, size, depth, indent, visited);
379 hash_table_destroy(visited);
380 return err;
381}
382
362static plist_err_t _plist_write_to_strbuf(plist_t plist, strbuf_t *outbuf, plist_write_options_t options) 383static plist_err_t _plist_write_to_strbuf(plist_t plist, strbuf_t *outbuf, plist_write_options_t options)
363{ 384{
364 uint8_t indent = 0; 385 uint8_t indent = 0;