summaryrefslogtreecommitdiffstats
path: root/jv.c
diff options
context:
space:
mode:
authorStephen Roantree <stroantree@gmail.com>2012-10-24 11:42:25 -0700
committerStephen Roantree <stroantree@gmail.com>2012-10-24 13:50:26 -0700
commit5e25c2a259d2337d38b730d5dc22e7db67ea88cb (patch)
treebf0d88fdad29f2fa9ea25a3ae5de73c8ea7c2297 /jv.c
parent033d9b2fd55b1fef0f17ce91d864c55e07f3ee5d (diff)
Implemented contains operator
Diffstat (limited to 'jv.c')
-rw-r--r--jv.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/jv.c b/jv.c
index 2d91366b..8515e7f4 100644
--- a/jv.c
+++ b/jv.c
@@ -250,6 +250,27 @@ static int jvp_array_equal(jv_complex* a, jv_complex* b) {
return 1;
}
+static int jvp_array_contains(jv_complex* a, jv_complex* b) {
+ int r = 1;
+ for (int bi = 0; bi < jvp_array_length(b); bi++) {
+ int ri = 0;
+ jv* bval = jvp_array_read(b, bi);
+ for (int ai = 0; ai < jvp_array_length(a); ai++) {
+ jv aval = jv_copy(*jvp_array_read(a, ai));
+ jv bval_copy = jv_copy(*bval);
+ if (jv_contains(aval, bval_copy)) {
+ ri = 1;
+ break;
+ }
+ }
+ if (!ri) {
+ r = 0;
+ break;
+ }
+ }
+ return r;
+}
+
static jv_complex jvp_array_slice(jv_complex* a, int start, int end) {
// FIXME: maybe slice should reallocate if the slice is small enough
assert(start <= end);
@@ -863,6 +884,27 @@ jv jv_object_merge(jv a, jv b) {
return a;
}
+int jv_object_contains(jv a, jv b) {
+ assert(jv_get_kind(a) == JV_KIND_OBJECT);
+ assert(jv_get_kind(b) == JV_KIND_OBJECT);
+ int r = 1;
+
+ for (int i=0; i<jvp_object_size(&b.val.complex); i++) {
+ struct object_slot* slotb = jvp_object_get_slot(&b.val.complex, i);
+ if (!slotb->string) continue;
+ jv* slota = jvp_object_read(&a.val.complex, slotb->string);
+ if (!(slota && jv_get_kind(slotb->value) == jv_get_kind(*slota)
+ && jv_contains(jv_copy(*slota), jv_copy(slotb->value)))) {
+ r = 0;
+ break;
+ }
+ }
+
+ jv_free(a);
+ jv_free(b);
+ return r;
+}
+
/*
* Object iteration (internal helpers)
*/
@@ -977,3 +1019,21 @@ int jv_equal(jv a, jv b) {
jv_free(b);
return r;
}
+
+int jv_contains(jv a, jv b) {
+ int r = 1;
+ if (jv_get_kind(a) != jv_get_kind(b)) {
+ r = 0;
+ } else if (jv_get_kind(a) == JV_KIND_OBJECT) {
+ r = jv_object_contains(jv_copy(a), jv_copy(b));
+ } else if (jv_get_kind(a) == JV_KIND_ARRAY) {
+ r = jvp_array_contains(&a.val.complex, &b.val.complex);
+ } else if (jv_get_kind(a) == JV_KIND_STRING) {
+ r = strstr(jv_string_value(a), jv_string_value(b)) != 0;
+ } else {
+ r = jv_equal(jv_copy(a), jv_copy(b));
+ }
+ jv_free(a);
+ jv_free(b);
+ return r;
+} \ No newline at end of file