From 465a4ec565a106e0e4cc1d64214fb2d6d791c8dc Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sat, 29 Dec 2012 16:13:06 +0000 Subject: Improvements to del(foo). del(foo,bar) is now very different from del(foo),del(bar). See #37. --- jv_aux.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 37 deletions(-) (limited to 'jv_aux.c') diff --git a/jv_aux.c b/jv_aux.c index 83695f96..f0e15b50 100644 --- a/jv_aux.c +++ b/jv_aux.c @@ -60,31 +60,63 @@ jv jv_set(jv t, jv k, jv v) { return t; } -jv jv_del(jv t, jv k) { - if (jv_get_kind(t) == JV_KIND_NULL) { - jv_free(k); - } else if (jv_get_kind(t) == JV_KIND_ARRAY && - jv_get_kind(k) == JV_KIND_NUMBER) { - int idx = (int)jv_number_value(k); - jv_free(k); - int len = jv_array_length(jv_copy(t)); - if (idx >= 0 && idx < len) { - for (int i = idx+1; i < len; i++) { - t = jv_array_set(t, i-1, jv_array_get(jv_copy(t), i)); +// assumes keys is a sorted array +jv jv_dels(jv t, jv keys) { + assert(jv_get_kind(keys) == JV_KIND_ARRAY); + assert(jv_is_valid(t)); + + if (jv_get_kind(t) == JV_KIND_NULL || jv_array_length(jv_copy(keys)) == 0) { + // no change + } else if (jv_get_kind(t) == JV_KIND_ARRAY) { + jv new_array = jv_array(); + int kidx = 0; + for (int i=0; i start); + int delkey = jv_array_length(jv_array_get(jv_copy(paths), i)) == start + 1; + jv key = jv_array_get(jv_array_get(jv_copy(paths), i), start); + while (j < jv_array_length(jv_copy(paths)) && + jv_equal(jv_copy(key), jv_array_get(jv_array_get(jv_copy(paths), j), start))) + j++; + // if i <= entry < j, then entry starts with key + if (delkey) { + // deleting this entire key, we don't care about any more specific deletions + delkeys = jv_array_append(delkeys, key); + } else { + // deleting certain sub-parts of this key + jv subobject = jv_get(jv_copy(object), jv_copy(key)); + if (!jv_is_valid(subobject)) { + jv_free(key); + jv_free(object); + object = subobject; + break; + } else if (jv_get_kind(subobject) == JV_KIND_NULL) { + jv_free(key); + jv_free(subobject); + } else { + jv newsubobject = delpaths_sorted(subobject, jv_array_slice(jv_copy(paths), i, j), start+1); + if (!jv_is_valid(newsubobject)) { + jv_free(key); + jv_free(object); + object = newsubobject; + break; + } + object = jv_set(object, key, newsubobject); + } + if (!jv_is_valid(object)) break; + } + i = j; } - if (!jv_is_valid(root)) { - jv_free(path); - return root; + jv_free(paths); + if (jv_is_valid(object)) + object = jv_dels(object, delkeys); + else + jv_free(delkeys); + return object; +} + +jv jv_delpaths(jv object, jv paths) { + paths = jv_sort(paths, jv_copy(paths)); + for (int i=0; i