//## Json Json.getJson(String key); static KMETHOD Json_getJson(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturn((kJson *)KLIB Knull(kctx, O_ct(sfp[0].asObject)))); const char *key = S_text(sfp[1].asString); json_t* ret = json_object_get(obj, key); CHECK_JSON(ret, KReturn((kJson *)KLIB Knull(kctx, O_ct(sfp[0].asObject)))); ret = json_incref(ret); struct _kJson *json = (struct _kJson *)KLIB new_kObjectDontUseThis(kctx, KGetReturnType(sfp), 0); json->obj = ret; KReturn(json); }
//## void Json.setJson(String key, Json value); static KMETHOD Json_setJson(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnDefaultObjectValue()); const char *key = S_text(sfp[1].asString); json_t* val = ((struct _kJson *)sfp[2].asObject)->obj; CHECK_JSON(val, KReturnDefaultObjectValue()); int ret = json_object_set(obj, key, val); if(ret < 0) { DBG_P("[WARNING] Json set cannnot set target object"); KReturnDefaultObjectValue(); } KReturnVoid(); }
str JSONjson2integer(lng *ret, json *js) { JSON *jt; char *rest; *ret = lng_nil; jt = JSONparse(*js, FALSE); CHECK_JSON(jt); switch (jt->elm[0].kind) { case JSON_NUMBER: *ret = strtol(jt->elm[0].value, &rest, 0); if (rest && (size_t) (rest - jt->elm[0].value) !=jt->elm[0].valuelen) *ret = lng_nil; break; case JSON_ARRAY: if (jt->free == 2) { *ret = strtol(jt->elm[1].value, &rest, 0); if (rest && (size_t) (rest - jt->elm[1].value) !=jt->elm[1].valuelen) *ret = lng_nil; } break; case JSON_OBJECT: if (jt->free == 3) { *ret = strtol(jt->elm[2].value, &rest, 0); if (rest && (size_t) (rest - jt->elm[2].value) !=jt->elm[2].valuelen) *ret = lng_nil; } } JSONfree(jt); return MAL_SUCCEED; }
str JSONvalueTable(bat *ret, json *js) { BAT *bn; char *r; int i; JSON *jt; jt = JSONparse(*js, FALSE); // already validated CHECK_JSON(jt); bn = BATnew(TYPE_void, TYPE_json, 64, TRANSIENT); if (bn == NULL) throw(MAL, "json.values", MAL_MALLOC_FAIL); BATseqbase(bn, 0); bn->hsorted = 1; bn->hrevsorted = 0; bn->H->nonil = 1; bn->tsorted = 1; bn->trevsorted = 0; bn->T->nonil = 1; for (i = jt->elm[0].next; i; i = jt->elm[i].next) { if (jt->elm[i].kind == JSON_ELEMENT) r = JSONgetValue(jt, jt->elm[i].child); else r = JSONgetValue(jt, i); BUNappend(bn, r, FALSE); GDKfree(r); } BBPkeepref(*ret = bn->batCacheid); return MAL_SUCCEED; }
str JSONkeyArray(json *ret, json *js) { char *result = NULL; str r; int i; JSON *jt; jt = JSONparse(*js, FALSE); // already validated CHECK_JSON(jt); if (jt->elm[0].kind == JSON_OBJECT) for (i = jt->elm[0].next; i; i = jt->elm[i].next) { r = GDKzalloc(jt->elm[i].valuelen + 3); if (jt->elm[i].valuelen) strncpy(r, jt->elm[i].value - 1, jt->elm[i].valuelen + 2); result = JSONglue(result, r, ','); } else throw(MAL, "json.keyarray", "Object expected"); r = (char *) GDKstrdup("["); result = JSONglue(r, result, 0); r = (char *) GDKstrdup("]"); *ret = JSONglue(result, r, 0); return MAL_SUCCEED; }
//## String Json.dump(); static KMETHOD Json_dump(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnDefaultObjectValue()); char* data = json_dumps(obj, JSON_ENSURE_ASCII); if(data == NULL) { KReturn(KNULL(String)); } KReturn(KLIB new_kString(kctx, data, strlen(data), 0)); }
//## void Json.setArray(String key, Json[] a); static KMETHOD Json_setArray(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnDefaultObjectValue()); const char *key = S_text(sfp[1].asString); kArrayVar* a = (kArrayVar *)sfp[2].asArray; json_t *ja = (json_t *)a->ObjectItems; json_object_set(obj, key, ja); KReturnVoid(); }
str JSONstr2json(json *ret, str *j) { JSON *jt = JSONparse(*j, FALSE); CHECK_JSON(jt); if (jt) JSONfree(jt); *ret = GDKstrdup(*j); return MAL_SUCCEED; }
str JSONdump(void *ret, json *val) { JSON *jt = JSONparse(*val, FALSE); CHECK_JSON(jt); (void) ret; JSONdumpInternal(jt, 0); JSONfree(jt); return MAL_SUCCEED; }
str JSONlength(int *ret, json *j) { int i, cnt = 0; JSON *jt = JSONparse(*j, FALSE); CHECK_JSON(jt); for (i = jt->elm[0].next; i; i = jt->elm[i].next) cnt++; *ret = cnt; return MAL_SUCCEED; }
//## @Static Json Json.parse(String str); static KMETHOD Json_parse(KonohaContext *kctx, KonohaStack *sfp) { const char *buf = S_text(sfp[1].asString); json_t* obj; json_error_t err; obj = json_loads(buf, 0, &err); struct _kJson *ret = (struct _kJson *)KLIB new_kObjectDontUseThis(kctx, KGetReturnType(sfp), 0); CHECK_JSON(obj, KReturn((kJson *)KLIB Knull(kctx, O_ct(ret)))); obj = json_incref(obj); ret->obj = obj; KReturn(ret); }
//## int Json.getInt(String key); static KMETHOD Json_getInt(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnUnboxValue(0)); const char *key = S_text(sfp[1].asString); json_t* ret = json_object_get(obj, key); if(!json_is_integer(ret)) { KReturnUnboxValue(0); } json_int_t val = json_integer_value(ret); KReturnUnboxValue((kint_t)val); }
//## Boolean Json.getBool(String key); static KMETHOD Json_getBool(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnUnboxValue(false)); const char *key = S_text(sfp[1].asString); json_t* json = json_object_get(obj, key); kbool_t ret = false; if(json_is_true(json)) { ret = true; } KReturnUnboxValue(ret); }
//## float Json.getFloat(String key); static KMETHOD Json_getFloat(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnFloatValue(0.0)); const char *key = S_text(sfp[1].asString); json_t* ret = json_object_get(obj, key); if(!json_is_real(ret)) { KReturnFloatValue(0.0); } ret = json_incref(ret); double val = json_real_value(ret); KReturnFloatValue(val); }
//## String[] Json.getKeys(); static KMETHOD Json_getKeys(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; kArray *a = (kArray *)KLIB new_kObjectDontUseThis(kctx, CT_StringArray0, 0); CHECK_JSON(obj, KReturn(KNULL(Array))); const char* key; void* iter = json_object_iter(obj); while(iter) { key = json_object_iter_key(iter); iter = json_object_iter_next(obj, iter); KLIB kArray_add(kctx, a, KLIB new_kString(kctx, key, strlen(key), StringPolicy_POOL|StringPolicy_ASCII)); } KReturn(a); }
//## String Json.getString(String key); static KMETHOD Json_getString(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturn(KNULL(String))); const char *key = S_text(sfp[1].asString); json_t* ret = json_object_get(obj, key); if(!json_is_string(ret)) { KReturn(KNULL(String)); } ret = json_incref(ret); const char* str = json_string_value(ret); if(str == NULL) { KReturn(KNULL(String)); } KReturn(KLIB new_kString(kctx, str, strlen(str), 0)); }
static str JSONfilterInternal(json *ret, json *js, str *expr, str other) { pattern terms[MAXTERMS]; int tidx = 0; JSON *jt; str j = *js, msg = MAL_SUCCEED, s; json result = 0; size_t l; (void) other; if (strNil(j)) { *ret = GDKstrdup(j); return MAL_SUCCEED; } memset((char *) terms, 0, MAXTERMS * sizeof(pattern)); msg = JSONcompile(*expr, terms); if (msg) return msg; jt = JSONparse(j, FALSE); CHECK_JSON(jt); result = s = JSONmatch(jt, 0, terms, tidx); // process all other PATH expression for (tidx++; tidx < MAXTERMS && terms[tidx].token; tidx++) if (terms[tidx].token == END_STEP && tidx + 1 < MAXTERMS && terms[tidx + 1].token) { s = JSONmatch(jt, 0, terms, ++tidx); result = JSONglue(result, s, ','); } if (result) { l = strlen(result); if (result[l - 1] == ',') result[l - 1] = 0; } else l = 3; s = GDKzalloc(l + 3); snprintf(s, l + 3, "[%s]", (result ? result : "")); GDKfree(result); for (l = 0; terms[l].token; l++) if (terms[l].name) GDKfree(terms[l].name); JSONfree(jt); *ret = s; return msg; }
//## void Json.setString(String key, String value); static KMETHOD Json_setString(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturnDefaultObjectValue()); const char *key = S_text(sfp[1].asString); const char *stringValue = S_text(sfp[2].asString); json_t* val = json_string(stringValue); if(!json_is_string(val)) { DBG_P("[ERROR]: Value is not Json object."); //KLIB KonohaRuntime_raise(kctx, 1, sfp, pline, msg); KReturnDefaultObjectValue(); } int ret = json_object_set(obj, key, val); if(ret < 0) { DBG_P("[WARNING] Json set cannnot set target object"); KReturnDefaultObjectValue(); } KReturnVoid(); }
str JSONjson2textSeparator(str *ret, json *js, str *sep) { JSON *jt; size_t l; str s; jt = JSONparse(*js, FALSE); CHECK_JSON(jt); l = strlen(*js) + 1; s = GDKmalloc(l); JSONplaintext(s, &l, jt, 0, **sep); l = strlen(s); if (l) s[l - 1] = 0; *ret = s; JSONfree(jt); return MAL_SUCCEED; }
//## Array Json.getArray(); static KMETHOD Json_getArray(KonohaContext *kctx, KonohaStack *sfp) { json_t* obj = ((struct _kJson *)sfp[0].asObject)->obj; CHECK_JSON(obj, KReturn(KNULL(Array))); const char *key = S_text(sfp[1].asString); json_t* ja; if(key == NULL) { ja = ((struct _kJson *)sfp[0].asObject)->obj; ja = json_incref(ja); } else { ja = json_object_get(obj, key); ja = json_incref(ja); } if(!json_is_array(ja)) { KReturn(KNULL(Array)); } kArrayVar* a = (kArrayVar *)KLIB new_kObjectDontUseThis(kctx, CT_Array, 0); a->ObjectItems= (kObject**)ja; KReturn(a); }
str JSONvalueArray(json *ret, json *js) { char *result = NULL; str r; int i; JSON *jt; jt = JSONparse(*js, FALSE); // already validated CHECK_JSON(jt); if (jt->elm[0].kind == JSON_OBJECT) for (i = jt->elm[0].next; i; i = jt->elm[i].next) { r = JSONgetValue(jt, jt->elm[i].child); result = JSONglue(result, r, ','); } else throw(MAL, "json.valuearray", "Object expected"); r = (char *) GDKstrdup("["); result = JSONglue(r, result, 0); r = (char *) GDKstrdup("]"); *ret = JSONglue(result, r, 0); return MAL_SUCCEED; }
static str JSONunfoldInternal(bat *od, bat *key, bat *val, json *js) { BAT *bo = NULL, *bk, *bv; oid o = 0; str msg = MAL_SUCCEED; JSON *jt = JSONparse(*js, FALSE); CHECK_JSON(jt); bk = BATnew(TYPE_void, TYPE_str, 64, TRANSIENT); if (bk == NULL) { JSONfree(jt); throw(MAL, "json.unfold", MAL_MALLOC_FAIL); } BATseqbase(bk, 0); bk->hsorted = 1; bk->hrevsorted = 0; bk->H->nonil = 1; bk->tsorted = 1; bk->trevsorted = 0; bk->T->nonil = 1; if (od) { bo = BATnew(TYPE_void, TYPE_oid, 64, TRANSIENT); if (bo == NULL) { BBPunfix(bk->batCacheid); JSONfree(jt); throw(MAL, "json.unfold", MAL_MALLOC_FAIL); } BATseqbase(bo, 0); bo->hsorted = 1; bo->hrevsorted = 0; bo->H->nonil = 1; bo->tsorted = 1; bo->trevsorted = 0; bo->T->nonil = 1; } bv = BATnew(TYPE_void, TYPE_json, 64, TRANSIENT); if (bv == NULL) { JSONfree(jt); if (od) BBPunfix(bo->batCacheid); BBPunfix(bk->batCacheid); throw(MAL, "json.unfold", MAL_MALLOC_FAIL); } BATseqbase(bv, 0); bv->hsorted = 1; bv->hrevsorted = 0; bv->H->nonil = 1; bv->tsorted = 1; bv->trevsorted = 0; bv->T->nonil = 1; if (jt->elm[0].kind == JSON_ARRAY || jt->elm[0].kind == JSON_OBJECT) JSONunfoldContainer(jt, 0, (od ? bo : 0), bk, bv, &o); else msg = createException(MAL, "json.unfold", "JSON object or array expected"); JSONfree(jt); BBPkeepref(*key = bk->batCacheid); BBPkeepref(*val = bv->batCacheid); if (od) BBPkeepref(*od = bo->batCacheid); return msg; }