summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h')
-rw-r--r--Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h b/Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h
new file mode 100644
index 00000000000..55e2d98ecd1
--- /dev/null
+++ b/Build/source/texk/web2c/mfluadir/otfcc/lib/support/json/json-funcs.h
@@ -0,0 +1,203 @@
+#ifndef CARYLL_SUPPORT_JSON_FUNCS_H
+#define CARYLL_SUPPORT_JSON_FUNCS_H
+
+#include <stdint.h>
+#include <math.h>
+
+#include "dep/json-builder.h"
+#include "dep/json.h"
+#include "dep/sds.h"
+
+#include "caryll/ownership.h"
+#include "otfcc/primitives.h"
+#include "otfcc/vf/vq.h"
+#include "otfcc/table/fvar.h"
+
+#ifndef INLINE
+#ifdef _MSC_VER
+#define INLINE __forceinline /* use __forceinline (VC++ specific) */
+#else
+#define INLINE inline /* use standard inline */
+#endif
+#endif
+
+static INLINE json_value *preserialize(MOVE json_value *x);
+
+static INLINE json_value *json_obj_get(const json_value *obj, const char *key) {
+ if (!obj || obj->type != json_object) return NULL;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ if (strcmp(ck, key) == 0) return obj->u.object.values[_k].value;
+ }
+ return NULL;
+}
+static INLINE json_value *json_obj_get_type(const json_value *obj, const char *key,
+ const json_type type) {
+ json_value *v = json_obj_get(obj, key);
+ if (v && v->type == type) return v;
+ return NULL;
+}
+static INLINE sds json_obj_getsds(const json_value *obj, const char *key) {
+ json_value *v = json_obj_get_type(obj, key, json_string);
+ if (!v)
+ return NULL;
+ else
+ return sdsnewlen(v->u.string.ptr, v->u.string.length);
+}
+static INLINE char *json_obj_getstr_share(const json_value *obj, const char *key) {
+ json_value *v = json_obj_get_type(obj, key, json_string);
+ if (!v)
+ return NULL;
+ else
+ return v->u.string.ptr;
+}
+
+static INLINE json_value *json_object_push_tag(json_value *a, uint32_t tag, json_value *b) {
+ char tags[4] = {(tag & 0xff000000) >> 24, (tag & 0xff0000) >> 16, (tag & 0xff00) >> 8,
+ (tag & 0xff)};
+ return json_object_push_length(a, 4, tags, b);
+}
+
+// Coordinates, VV and VQ
+static INLINE double json_numof(const json_value *cv) {
+ if (cv && cv->type == json_integer) return cv->u.integer;
+ if (cv && cv->type == json_double) return cv->u.dbl;
+ return 0;
+}
+static INLINE json_value *json_new_position(pos_t z) {
+ if (round(z) == z) {
+ return json_integer_new(z);
+ } else {
+ return json_double_new(z);
+ }
+}
+json_value *json_new_VQRegion_Explicit(const vq_Region *rs, const table_fvar *fvar);
+json_value *json_new_VQRegion(const vq_Region *rs, const table_fvar *fvar);
+json_value *json_new_VQ(const VQ z, const table_fvar *fvar);
+json_value *json_new_VV(const VV x, const table_fvar *fvar);
+json_value *json_new_VVp(const VV *x, const table_fvar *fvar);
+VQ json_vqOf(const json_value *cv, const table_fvar *fvar);
+
+static INLINE double json_obj_getnum(const json_value *obj, const char *key) {
+ if (!obj || obj->type != json_object) return 0.0;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_integer) return cv->u.integer;
+ if (cv && cv->type == json_double) return cv->u.dbl;
+ }
+ }
+ return 0.0;
+}
+static INLINE int32_t json_obj_getint(const json_value *obj, const char *key) {
+ if (!obj || obj->type != json_object) return 0;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_integer) return (int32_t)cv->u.integer;
+ if (cv && cv->type == json_double) return cv->u.dbl;
+ }
+ }
+ return 0;
+}
+static INLINE double json_obj_getnum_fallback(const json_value *obj, const char *key,
+ double fallback) {
+ if (!obj || obj->type != json_object) return fallback;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_integer) return cv->u.integer;
+ if (cv && cv->type == json_double) return cv->u.dbl;
+ }
+ }
+ return fallback;
+}
+static INLINE int32_t json_obj_getint_fallback(const json_value *obj, const char *key,
+ int32_t fallback) {
+ if (!obj || obj->type != json_object) return fallback;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_integer) return (int32_t)cv->u.integer;
+ if (cv && cv->type == json_double) return cv->u.dbl;
+ }
+ }
+ return fallback;
+}
+static INLINE bool json_boolof(const json_value *cv) {
+ if (cv && cv->type == json_boolean) return cv->u.boolean;
+ return false;
+}
+static INLINE bool json_obj_getbool(const json_value *obj, const char *key) {
+ if (!obj || obj->type != json_object) return false;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_boolean) return cv->u.boolean;
+ }
+ }
+ return false;
+}
+static INLINE bool json_obj_getbool_fallback(const json_value *obj, const char *key,
+ bool fallback) {
+ if (!obj || obj->type != json_object) return fallback;
+ for (uint32_t _k = 0; _k < obj->u.object.length; _k++) {
+ char *ck = obj->u.object.values[_k].name;
+ json_value *cv = obj->u.object.values[_k].value;
+ if (strcmp(ck, key) == 0) {
+ if (cv && cv->type == json_boolean) return cv->u.boolean;
+ }
+ }
+ return fallback;
+}
+
+static INLINE json_value *json_from_sds(const sds str) {
+ return json_string_new_length((uint32_t)sdslen(str), str);
+}
+
+// flags reader and writer
+static INLINE json_value *otfcc_dump_flags(int flags, const char *labels[]) {
+ json_value *v = json_object_new(0);
+ for (uint16_t j = 0; labels[j]; j++)
+ if (flags & (1 << j)) { json_object_push(v, labels[j], json_boolean_new(true)); }
+ return v;
+}
+static INLINE uint32_t otfcc_parse_flags(const json_value *v, const char *labels[]) {
+ if (!v) return 0;
+ if (v->type == json_integer) {
+ return (uint32_t)v->u.integer;
+ } else if (v->type == json_double) {
+ return (uint32_t)v->u.dbl;
+ } else if (v->type == json_object) {
+ uint32_t flags = 0;
+ for (uint16_t j = 0; labels[j]; j++) {
+ if (json_obj_getbool(v, labels[j])) { flags |= (1 << j); }
+ }
+ return flags;
+ } else {
+ return 0;
+ }
+}
+
+static INLINE json_value *preserialize(MOVE json_value *x) {
+#ifdef CARYLL_USE_PRE_SERIALIZED
+ json_serialize_opts opts = {.mode = json_serialize_mode_packed};
+ size_t preserialize_len = json_measure_ex(x, opts);
+ char *buf = (char *)malloc(preserialize_len);
+ json_serialize_ex(buf, x, opts);
+ json_builder_free(x);
+
+ json_value *xx = json_string_new_nocopy((uint32_t)(preserialize_len - 1), buf);
+ xx->type = json_pre_serialized;
+ return xx;
+#else
+ return x;
+#endif
+}
+
+#endif