static void test_clone(void) { jd_var dst = JD_INIT, src = JD_INIT, ref = JD_INIT; jd_var json = JD_INIT; jd_set_string(&json, "{\"a\":[1,2,3],\"b\":3.14,\"c\":\"foo\"}"); jd_from_json(&ref, &json); jd_clone(&src, &ref, 1); jd_clone(&dst, &src, 0); /* shallow */ jdt_is(&dst, &src, "clone matches"); jd_assign(jd_lv(&dst, "$.d.0.capsule.source"), &json); jdt_is(&ref, &src, "source unchanged"); jd_assign(jd_lv(&dst, "$.a.3"), &json); jdt_is(jd_rv(&src, "$.a.3"), &json, "deep item changed"); jd_clone(&src, &ref, 1); jd_clone(&dst, &src, 1); /* deep */ jdt_is(&dst, &src, "clone matches"); jd_assign(jd_lv(&dst, "$.d.0.capsule.source"), &json); jdt_is(&ref, &src, "source unchanged"); jd_assign(jd_lv(&dst, "$.a.3"), &json); jdt_is(&ref, &src, "source unchanged again"); jd_release(&dst); jd_release(&src); jd_release(&ref); jd_release(&json); }
jd_var *jd_get_context(jd_var *root, jd_var *path, jd_path_context *ctx, int vivify) { jd_var *ptr = NULL; JD_SCOPE { JD_2VARS(part, elt); if (path->type == ARRAY) jd_clone(part, path, 0); else jd_split(part, path, jd_nsv(".")); if (!jd_shift(part, 1, elt) || jd_compare(elt, jd_nsv("$"))) jd_throw("Bad path"); for (ptr = root; ptr && jd_shift(part, 1, elt);) { if (ptr->type == VOID) { /* empty slot: type depends on key format */ if (is_positive_int(elt)) jd_set_array(ptr, 1); else jd_set_hash(ptr, 1); } if (ptr->type == ARRAY) { size_t ac = jd_count(ptr); jd_int ix = jd_get_int(elt); if (ix == ac && vivify) ptr = jd_push(ptr, 1); else if (ix < ac) ptr = jd_get_idx(ptr, ix); else { ptr = NULL; } } else if (ptr->type == HASH) { ptr = jd_get_key(ptr, elt, vivify); } else { jd_throw("Unexpected element in structure"); } } } return ptr; }
jd_var *jd__closure_clone(jd_var *out, jd_closure *jdc, int deep) { jd_set_closure(out, jdc->f); if (deep) jd_clone(jd_context(out), &jdc->ctx, 1); else jd_assign(jd_context(out), &jdc->ctx); return out; }
void dy_queue_enqueue(dy_queue *q, jd_var *msg) { pthread_mutex_lock(&q->mutex); jd_clone(jd_push(&q->queue, 1), msg, 1); pthread_cond_signal(&q->cond); pthread_mutex_unlock(&q->mutex); }