summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/README.md11
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/attr_container.c986
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/attr_container.h596
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/shared_utils.h155
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h101
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.cmake15
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.h13
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/restful_utils.c493
8 files changed, 2370 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/README.md b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/README.md
new file mode 100644
index 000000000..b166e0b3a
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/README.md
@@ -0,0 +1,11 @@
+ Notes:
+=======
+This folder is for the source files shared by both WASM APP and native runtime
+
+- The c files in this directory are compiled into both the WASM APP and runtime.
+- The header files for distributing to SDK are placed in the "bi-inc" folder.
+
+
+
+
+
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/attr_container.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/attr_container.c
new file mode 100644
index 000000000..e1e9f4e35
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/attr_container.c
@@ -0,0 +1,986 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "bi-inc/attr_container.h"
+
+typedef union jvalue {
+ bool z;
+ int8_t i8;
+ uint8_t u8;
+ int16_t i16;
+ uint16_t u16;
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
+ float f;
+ double d;
+} jvalue;
+
+static inline int16_t
+get_int16(const char *buf)
+{
+ int16_t ret;
+ bh_memcpy_s(&ret, sizeof(int16_t), buf, sizeof(int16_t));
+ return ret;
+}
+
+static inline uint16_t
+get_uint16(const char *buf)
+{
+ uint16_t ret;
+ bh_memcpy_s(&ret, sizeof(uint16_t), buf, sizeof(uint16_t));
+ return ret;
+}
+
+static inline int32_t
+get_int32(const char *buf)
+{
+ int32_t ret;
+ bh_memcpy_s(&ret, sizeof(int32_t), buf, sizeof(int32_t));
+ return ret;
+}
+
+static inline uint32_t
+get_uint32(const char *buf)
+{
+ uint32_t ret;
+ bh_memcpy_s(&ret, sizeof(uint32_t), buf, sizeof(uint32_t));
+ return ret;
+}
+
+static inline int64_t
+get_int64(const char *buf)
+{
+ int64_t ret;
+ bh_memcpy_s(&ret, sizeof(int64_t), buf, sizeof(int64_t));
+ return ret;
+}
+
+static inline uint64_t
+get_uint64(const char *buf)
+{
+ uint64_t ret;
+ bh_memcpy_s(&ret, sizeof(uint64_t), buf, sizeof(uint64_t));
+ return ret;
+}
+
+static inline void
+set_int16(char *buf, int16_t v)
+{
+ bh_memcpy_s(buf, sizeof(int16_t), &v, sizeof(int16_t));
+}
+
+static inline void
+set_uint16(char *buf, uint16_t v)
+{
+ bh_memcpy_s(buf, sizeof(uint16_t), &v, sizeof(uint16_t));
+}
+
+static inline void
+set_int32(char *buf, int32_t v)
+{
+ bh_memcpy_s(buf, sizeof(int32_t), &v, sizeof(int32_t));
+}
+
+static inline void
+set_uint32(char *buf, uint32_t v)
+{
+ bh_memcpy_s(buf, sizeof(uint32_t), &v, sizeof(uint32_t));
+}
+
+static inline void
+set_int64(char *buf, int64_t v)
+{
+ bh_memcpy_s(buf, sizeof(int64_t), &v, sizeof(int64_t));
+}
+
+static inline void
+set_uint64(char *buf, uint64_t v)
+{
+ bh_memcpy_s(buf, sizeof(uint64_t), &v, sizeof(uint64_t));
+}
+
+char *
+attr_container_get_attr_begin(const attr_container_t *attr_cont,
+ uint32_t *p_total_length, uint16_t *p_attr_num)
+{
+ char *p = (char *)attr_cont->buf;
+ uint16_t str_len, attr_num;
+ uint32_t total_length;
+
+ /* skip total length */
+ total_length = get_uint32(p);
+ p += sizeof(uint32_t);
+ if (!total_length)
+ return NULL;
+
+ /* tag length */
+ str_len = get_uint16(p);
+ p += sizeof(uint16_t);
+ if (!str_len)
+ return NULL;
+
+ /* tag content */
+ p += str_len;
+ if ((uint32_t)(p - attr_cont->buf) >= total_length)
+ return NULL;
+
+ /* attribute num */
+ attr_num = get_uint16(p);
+ p += sizeof(uint16_t);
+ if ((uint32_t)(p - attr_cont->buf) >= total_length)
+ return NULL;
+
+ if (p_total_length)
+ *p_total_length = total_length;
+
+ if (p_attr_num)
+ *p_attr_num = attr_num;
+
+ /* first attribute */
+ return p;
+}
+
+static char *
+attr_container_get_attr_next(const char *curr_attr)
+{
+ char *p = (char *)curr_attr;
+ uint8_t type;
+
+ /* key length and key */
+ p += sizeof(uint16_t) + get_uint16(p);
+ type = *p++;
+
+ /* Byte type to Boolean type */
+ if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN) {
+ p += 1 << (type & 3);
+ return p;
+ }
+ /* String type */
+ else if (type == ATTR_TYPE_STRING) {
+ p += sizeof(uint16_t) + get_uint16(p);
+ return p;
+ }
+ /* ByteArray type */
+ else if (type == ATTR_TYPE_BYTEARRAY) {
+ p += sizeof(uint32_t) + get_uint32(p);
+ return p;
+ }
+
+ return NULL;
+}
+
+static const char *
+attr_container_find_attr(const attr_container_t *attr_cont, const char *key)
+{
+ uint32_t total_length;
+ uint16_t str_len, attr_num, i;
+ const char *p = attr_cont->buf;
+
+ if (!key)
+ return NULL;
+
+ if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
+ &attr_num)))
+ return NULL;
+
+ for (i = 0; i < attr_num; i++) {
+ /* key length */
+ if (!(str_len = get_uint16(p)))
+ return NULL;
+
+ if (str_len == strlen(key) + 1
+ && memcmp(p + sizeof(uint16_t), key, str_len) == 0) {
+ if ((uint32_t)(p + sizeof(uint16_t) + str_len - attr_cont->buf)
+ >= total_length)
+ return NULL;
+ return p;
+ }
+
+ if (!(p = attr_container_get_attr_next(p)))
+ return NULL;
+ }
+
+ return NULL;
+}
+
+char *
+attr_container_get_attr_end(const attr_container_t *attr_cont)
+{
+ uint32_t total_length;
+ uint16_t attr_num, i;
+ char *p;
+
+ if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
+ &attr_num)))
+ return NULL;
+
+ for (i = 0; i < attr_num; i++)
+ if (!(p = attr_container_get_attr_next(p)))
+ return NULL;
+
+ return p;
+}
+
+static char *
+attr_container_get_msg_end(attr_container_t *attr_cont)
+{
+ char *p = attr_cont->buf;
+ return p + get_uint32(p);
+}
+
+uint16_t
+attr_container_get_attr_num(const attr_container_t *attr_cont)
+{
+ uint16_t str_len;
+ /* skip total length */
+ const char *p = attr_cont->buf + sizeof(uint32_t);
+
+ str_len = get_uint16(p);
+ /* skip tag length and tag */
+ p += sizeof(uint16_t) + str_len;
+
+ /* attribute num */
+ return get_uint16(p);
+}
+
+static void
+attr_container_inc_attr_num(attr_container_t *attr_cont)
+{
+ uint16_t str_len, attr_num;
+ /* skip total length */
+ char *p = attr_cont->buf + sizeof(uint32_t);
+
+ str_len = get_uint16(p);
+ /* skip tag length and tag */
+ p += sizeof(uint16_t) + str_len;
+
+ /* attribute num */
+ attr_num = get_uint16(p) + 1;
+ set_uint16(p, attr_num);
+}
+
+attr_container_t *
+attr_container_create(const char *tag)
+{
+ attr_container_t *attr_cont;
+ int length, tag_length;
+ char *p;
+
+ tag_length = tag ? strlen(tag) + 1 : 1;
+ length = offsetof(attr_container_t, buf) +
+ /* total length + tag length + tag + reserved 100 bytes */
+ sizeof(uint32_t) + sizeof(uint16_t) + tag_length + 100;
+
+ if (!(attr_cont = attr_container_malloc(length))) {
+ attr_container_printf(
+ "Create attr_container failed: allocate memory failed.\r\n");
+ return NULL;
+ }
+
+ memset(attr_cont, 0, length);
+ p = attr_cont->buf;
+
+ /* total length */
+ set_uint32(p, length - offsetof(attr_container_t, buf));
+ p += 4;
+
+ /* tag length, tag */
+ set_uint16(p, tag_length);
+ p += 2;
+ if (tag)
+ bh_memcpy_s(p, tag_length, tag, tag_length);
+
+ return attr_cont;
+}
+
+void
+attr_container_destroy(const attr_container_t *attr_cont)
+{
+ if (attr_cont)
+ attr_container_free((char *)attr_cont);
+}
+
+static bool
+check_set_attr(attr_container_t **p_attr_cont, const char *key)
+{
+ uint32_t flags;
+
+ if (!p_attr_cont || !*p_attr_cont || !key || strlen(key) == 0) {
+ attr_container_printf(
+ "Set attribute failed: invalid input arguments.\r\n");
+ return false;
+ }
+
+ flags = get_uint32((char *)*p_attr_cont);
+ if (flags & ATTR_CONT_READONLY_SHIFT) {
+ attr_container_printf(
+ "Set attribute failed: attribute container is readonly.\r\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+attr_container_set_attr(attr_container_t **p_attr_cont, const char *key,
+ int type, const void *value, int value_length)
+{
+ attr_container_t *attr_cont, *attr_cont1;
+ uint16_t str_len;
+ uint32_t total_length, attr_len;
+ char *p, *p1, *attr_end, *msg_end, *attr_buf;
+
+ if (!check_set_attr(p_attr_cont, key)) {
+ return false;
+ }
+
+ attr_cont = *p_attr_cont;
+ p = attr_cont->buf;
+ total_length = get_uint32(p);
+
+ if (!(attr_end = attr_container_get_attr_end(attr_cont))) {
+ attr_container_printf("Set attr failed: get attr end failed.\r\n");
+ return false;
+ }
+
+ msg_end = attr_container_get_msg_end(attr_cont);
+
+ /* key len + key + '\0' + type */
+ attr_len = sizeof(uint16_t) + strlen(key) + 1 + 1;
+ if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN)
+ attr_len += 1 << (type & 3);
+ else if (type == ATTR_TYPE_STRING)
+ attr_len += sizeof(uint16_t) + value_length;
+ else if (type == ATTR_TYPE_BYTEARRAY)
+ attr_len += sizeof(uint32_t) + value_length;
+
+ if (!(p = attr_buf = attr_container_malloc(attr_len))) {
+ attr_container_printf("Set attr failed: allocate memory failed.\r\n");
+ return false;
+ }
+
+ /* Set the attr buf */
+ str_len = (uint16_t)(strlen(key) + 1);
+ set_uint16(p, str_len);
+ p += sizeof(uint16_t);
+ bh_memcpy_s(p, str_len, key, str_len);
+ p += str_len;
+
+ *p++ = type;
+ if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN)
+ bh_memcpy_s(p, 1 << (type & 3), value, 1 << (type & 3));
+ else if (type == ATTR_TYPE_STRING) {
+ set_uint16(p, value_length);
+ p += sizeof(uint16_t);
+ bh_memcpy_s(p, value_length, value, value_length);
+ }
+ else if (type == ATTR_TYPE_BYTEARRAY) {
+ set_uint32(p, value_length);
+ p += sizeof(uint32_t);
+ bh_memcpy_s(p, value_length, value, value_length);
+ }
+
+ if ((p = (char *)attr_container_find_attr(attr_cont, key))) {
+ /* key found */
+ p1 = attr_container_get_attr_next(p);
+
+ if (p1 - p == attr_len) {
+ bh_memcpy_s(p, attr_len, attr_buf, attr_len);
+ attr_container_free(attr_buf);
+ return true;
+ }
+
+ if ((uint32_t)(p1 - p + msg_end - attr_end) >= attr_len) {
+ memmove(p, p1, attr_end - p1);
+ bh_memcpy_s(p + (attr_end - p1), attr_len, attr_buf, attr_len);
+ attr_container_free(attr_buf);
+ return true;
+ }
+
+ total_length += attr_len + 100;
+ if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
+ + total_length))) {
+ attr_container_printf(
+ "Set attr failed: allocate memory failed.\r\n");
+ attr_container_free(attr_buf);
+ return false;
+ }
+
+ bh_memcpy_s(attr_cont1, p - (char *)attr_cont, attr_cont,
+ p - (char *)attr_cont);
+ bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont),
+ attr_end - p1, p1, attr_end - p1);
+ bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont)
+ + (unsigned)(attr_end - p1),
+ attr_len, attr_buf, attr_len);
+ p = attr_cont1->buf;
+ set_uint32(p, total_length);
+ *p_attr_cont = attr_cont1;
+ /* Free original buffer */
+ attr_container_free(attr_cont);
+ attr_container_free(attr_buf);
+ return true;
+ }
+ else {
+ /* key not found */
+ if ((uint32_t)(msg_end - attr_end) >= attr_len) {
+ bh_memcpy_s(attr_end, msg_end - attr_end, attr_buf, attr_len);
+ attr_container_inc_attr_num(attr_cont);
+ attr_container_free(attr_buf);
+ return true;
+ }
+
+ total_length += attr_len + 100;
+ if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
+ + total_length))) {
+ attr_container_printf(
+ "Set attr failed: allocate memory failed.\r\n");
+ attr_container_free(attr_buf);
+ return false;
+ }
+
+ bh_memcpy_s(attr_cont1, attr_end - (char *)attr_cont, attr_cont,
+ attr_end - (char *)attr_cont);
+ bh_memcpy_s((char *)attr_cont1
+ + (unsigned)(attr_end - (char *)attr_cont),
+ attr_len, attr_buf, attr_len);
+ attr_container_inc_attr_num(attr_cont1);
+ p = attr_cont1->buf;
+ set_uint32(p, total_length);
+ *p_attr_cont = attr_cont1;
+ /* Free original buffer */
+ attr_container_free(attr_cont);
+ attr_container_free(attr_buf);
+ return true;
+ }
+
+ return false;
+}
+
+bool
+attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
+ short value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_SHORT, &value,
+ 2);
+}
+
+bool
+attr_container_set_int16(attr_container_t **p_attr_cont, const char *key,
+ int16_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT16, &value,
+ 2);
+}
+
+bool
+attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
+ int value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT, &value, 4);
+}
+
+bool
+attr_container_set_int32(attr_container_t **p_attr_cont, const char *key,
+ int32_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT32, &value,
+ 4);
+}
+
+bool
+attr_container_set_uint32(attr_container_t **p_attr_cont, const char *key,
+ uint32_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT32, &value,
+ 4);
+}
+
+bool
+attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
+ int64_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT64, &value,
+ 8);
+}
+
+bool
+attr_container_set_uint64(attr_container_t **p_attr_cont, const char *key,
+ uint64_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT64, &value,
+ 8);
+}
+
+bool
+attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
+ int8_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTE, &value, 1);
+}
+
+bool
+attr_container_set_int8(attr_container_t **p_attr_cont, const char *key,
+ int8_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT8, &value, 1);
+}
+
+bool
+attr_container_set_uint8(attr_container_t **p_attr_cont, const char *key,
+ uint8_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT8, &value,
+ 1);
+}
+
+bool
+attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
+ uint16_t value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT16, &value,
+ 2);
+}
+
+bool
+attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
+ float value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_FLOAT, &value,
+ 4);
+}
+
+bool
+attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
+ double value)
+{
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_DOUBLE, &value,
+ 8);
+}
+
+bool
+attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
+ bool value)
+{
+ int8_t value1 = value ? 1 : 0;
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BOOLEAN, &value1,
+ 1);
+}
+
+bool
+attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
+ const char *value)
+{
+ if (!value) {
+ attr_container_printf("Set attr failed: invald input arguments.\r\n");
+ return false;
+ }
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_STRING, value,
+ strlen(value) + 1);
+}
+
+bool
+attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
+ const int8_t *value, unsigned length)
+{
+ if (!value) {
+ attr_container_printf("Set attr failed: invald input arguments.\r\n");
+ return false;
+ }
+ return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTEARRAY, value,
+ length);
+}
+
+static const char *
+attr_container_get_attr(const attr_container_t *attr_cont, const char *key)
+{
+ const char *attr_addr;
+
+ if (!attr_cont || !key) {
+ attr_container_printf(
+ "Get attribute failed: invalid input arguments.\r\n");
+ return NULL;
+ }
+
+ if (!(attr_addr = attr_container_find_attr(attr_cont, key))) {
+ attr_container_printf("Get attribute failed: lookup key failed.\r\n");
+ return NULL;
+ }
+
+ /* key len + key + '\0' */
+ return attr_addr + 2 + strlen(key) + 1;
+}
+
+#define TEMPLATE_ATTR_BUF_TO_VALUE(attr, key, var_name) \
+ do { \
+ jvalue val; \
+ const char *addr = attr_container_get_attr(attr, key); \
+ uint8_t type; \
+ if (!addr) \
+ return 0; \
+ val.i64 = 0; \
+ type = *(uint8_t *)addr++; \
+ switch (type) { \
+ case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */ \
+ case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */ \
+ case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */ \
+ case ATTR_TYPE_INT64: \
+ case ATTR_TYPE_UINT8: \
+ case ATTR_TYPE_UINT16: \
+ case ATTR_TYPE_UINT32: \
+ case ATTR_TYPE_UINT64: \
+ case ATTR_TYPE_FLOAT: \
+ case ATTR_TYPE_DOUBLE: \
+ case ATTR_TYPE_BOOLEAN: \
+ bh_memcpy_s(&val, sizeof(val.var_name), addr, \
+ 1 << (type & 3)); \
+ break; \
+ case ATTR_TYPE_STRING: \
+ { \
+ unsigned len = get_uint16(addr); \
+ addr += 2; \
+ if (len > sizeof(val.var_name)) \
+ len = sizeof(val.var_name); \
+ bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
+ break; \
+ } \
+ case ATTR_TYPE_BYTEARRAY: \
+ { \
+ unsigned len = get_uint32(addr); \
+ addr += 4; \
+ if (len > sizeof(val.var_name)) \
+ len = sizeof(val.var_name); \
+ bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
+ break; \
+ } \
+ default: \
+ bh_assert(0); \
+ break; \
+ } \
+ return val.var_name; \
+ } while (0)
+
+short
+attr_container_get_as_short(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i16);
+}
+
+int16_t
+attr_container_get_as_int16(const attr_container_t *attr_cont, const char *key)
+{
+ return (int16_t)attr_container_get_as_short(attr_cont, key);
+}
+
+int
+attr_container_get_as_int(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i32);
+}
+
+int32_t
+attr_container_get_as_int32(const attr_container_t *attr_cont, const char *key)
+{
+ return (int32_t)attr_container_get_as_int(attr_cont, key);
+}
+
+uint32_t
+attr_container_get_as_uint32(const attr_container_t *attr_cont, const char *key)
+{
+ return (uint32_t)attr_container_get_as_int(attr_cont, key);
+}
+
+int64_t
+attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i64);
+}
+
+uint64_t
+attr_container_get_as_uint64(const attr_container_t *attr_cont, const char *key)
+{
+ return (uint64_t)attr_container_get_as_int64(attr_cont, key);
+}
+
+int8_t
+attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i8);
+}
+
+int8_t
+attr_container_get_as_int8(const attr_container_t *attr_cont, const char *key)
+{
+ return attr_container_get_as_byte(attr_cont, key);
+}
+
+uint8_t
+attr_container_get_as_uint8(const attr_container_t *attr_cont, const char *key)
+{
+ return (uint8_t)attr_container_get_as_byte(attr_cont, key);
+}
+
+uint16_t
+attr_container_get_as_uint16(const attr_container_t *attr_cont, const char *key)
+{
+ return (uint16_t)attr_container_get_as_short(attr_cont, key);
+}
+
+float
+attr_container_get_as_float(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, f);
+}
+
+double
+attr_container_get_as_double(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, d);
+}
+
+bool
+attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key)
+{
+ TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, z);
+}
+
+const int8_t *
+attr_container_get_as_bytearray(const attr_container_t *attr_cont,
+ const char *key, unsigned *array_length)
+{
+ const char *addr = attr_container_get_attr(attr_cont, key);
+ uint8_t type;
+ uint32_t length;
+
+ if (!addr)
+ return NULL;
+
+ if (!array_length) {
+ attr_container_printf("Get attribute failed: invalid input arguments.");
+ return NULL;
+ }
+
+ type = *(uint8_t *)addr++;
+ switch (type) {
+ case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */
+ case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */
+ case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */
+ case ATTR_TYPE_INT64:
+ case ATTR_TYPE_UINT8:
+ case ATTR_TYPE_UINT16:
+ case ATTR_TYPE_UINT32:
+ case ATTR_TYPE_UINT64:
+ case ATTR_TYPE_FLOAT:
+ case ATTR_TYPE_DOUBLE:
+ case ATTR_TYPE_BOOLEAN:
+ length = 1 << (type & 3);
+ break;
+ case ATTR_TYPE_STRING:
+ length = get_uint16(addr);
+ addr += 2;
+ break;
+ case ATTR_TYPE_BYTEARRAY:
+ length = get_uint32(addr);
+ addr += 4;
+ break;
+ default:
+ return NULL;
+ }
+
+ *array_length = length;
+ return (const int8_t *)addr;
+}
+
+char *
+attr_container_get_as_string(const attr_container_t *attr_cont, const char *key)
+{
+ unsigned array_length;
+ return (char *)attr_container_get_as_bytearray(attr_cont, key,
+ &array_length);
+}
+
+const char *
+attr_container_get_tag(const attr_container_t *attr_cont)
+{
+ return attr_cont ? attr_cont->buf + sizeof(uint32_t) + sizeof(uint16_t)
+ : NULL;
+}
+
+bool
+attr_container_contain_key(const attr_container_t *attr_cont, const char *key)
+{
+ if (!attr_cont || !key || !strlen(key)) {
+ attr_container_printf(
+ "Check contain key failed: invalid input arguments.\r\n");
+ return false;
+ }
+ return attr_container_find_attr(attr_cont, key) ? true : false;
+}
+
+unsigned int
+attr_container_get_serialize_length(const attr_container_t *attr_cont)
+{
+ const char *p;
+
+ if (!attr_cont) {
+ attr_container_printf("Get container serialize length failed: invalid "
+ "input arguments.\r\n");
+ return 0;
+ }
+
+ p = attr_cont->buf;
+ return sizeof(uint16_t) + get_uint32(p);
+}
+
+bool
+attr_container_serialize(char *buf, const attr_container_t *attr_cont)
+{
+ const char *p;
+ uint16_t flags;
+ uint32_t length;
+
+ if (!buf || !attr_cont) {
+ attr_container_printf(
+ "Container serialize failed: invalid input arguments.\r\n");
+ return false;
+ }
+
+ p = attr_cont->buf;
+ length = sizeof(uint16_t) + get_uint32(p);
+ bh_memcpy_s(buf, length, attr_cont, length);
+ /* Set readonly */
+ flags = get_uint16((const char *)attr_cont);
+ set_uint16(buf, flags | (1 << ATTR_CONT_READONLY_SHIFT));
+
+ return true;
+}
+
+bool
+attr_container_is_constant(const attr_container_t *attr_cont)
+{
+ uint16_t flags;
+
+ if (!attr_cont) {
+ attr_container_printf(
+ "Container check const: invalid input arguments.\r\n");
+ return false;
+ }
+
+ flags = get_uint16((const char *)attr_cont);
+ return (flags & (1 << ATTR_CONT_READONLY_SHIFT)) ? true : false;
+}
+
+void
+attr_container_dump(const attr_container_t *attr_cont)
+{
+ uint32_t total_length;
+ uint16_t attr_num, i, type;
+ const char *p, *tag, *key;
+ jvalue value;
+
+ if (!attr_cont)
+ return;
+
+ tag = attr_container_get_tag(attr_cont);
+ if (!tag)
+ return;
+
+ attr_container_printf("Attribute container dump:\n");
+ attr_container_printf("Tag: %s\n", tag);
+
+ p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num);
+ if (!p)
+ return;
+
+ attr_container_printf("Attribute list:\n");
+ for (i = 0; i < attr_num; i++) {
+ key = p + 2;
+ /* Skip key len and key */
+ p += 2 + get_uint16(p);
+ type = *p++;
+ attr_container_printf(" key: %s", key);
+
+ switch (type) {
+ case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */
+ bh_memcpy_s(&value.i8, 1, p, 1);
+ attr_container_printf(", type: byte, value: 0x%x\n",
+ value.i8 & 0xFF);
+ p++;
+ break;
+ case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */
+ bh_memcpy_s(&value.i16, sizeof(int16_t), p, sizeof(int16_t));
+ attr_container_printf(", type: short, value: 0x%x\n",
+ value.i16 & 0xFFFF);
+ p += 2;
+ break;
+ case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */
+ bh_memcpy_s(&value.i32, sizeof(int32_t), p, sizeof(int32_t));
+ attr_container_printf(", type: int, value: 0x%x\n", value.i32);
+ p += 4;
+ break;
+ case ATTR_TYPE_INT64:
+ bh_memcpy_s(&value.i64, sizeof(int64_t), p, sizeof(int64_t));
+ attr_container_printf(", type: int64, value: 0x%llx\n",
+ (long long unsigned int)(value.i64));
+ p += 8;
+ break;
+ case ATTR_TYPE_UINT8:
+ bh_memcpy_s(&value.u8, 1, p, 1);
+ attr_container_printf(", type: uint8, value: 0x%x\n", value.u8);
+ p++;
+ break;
+ case ATTR_TYPE_UINT16:
+ bh_memcpy_s(&value.u16, sizeof(uint16_t), p, sizeof(uint16_t));
+ attr_container_printf(", type: uint16, value: 0x%x\n",
+ value.u16);
+ p += 2;
+ break;
+ case ATTR_TYPE_UINT32:
+ bh_memcpy_s(&value.u32, sizeof(uint32_t), p, sizeof(uint32_t));
+ attr_container_printf(", type: uint32, value: 0x%x\n",
+ value.u32);
+ p += 4;
+ break;
+ case ATTR_TYPE_UINT64:
+ bh_memcpy_s(&value.u64, sizeof(uint64_t), p, sizeof(uint64_t));
+ attr_container_printf(", type: int64, value: 0x%llx\n",
+ (long long unsigned int)(value.u64));
+ p += 8;
+ break;
+ case ATTR_TYPE_FLOAT:
+ bh_memcpy_s(&value.f, sizeof(float), p, sizeof(float));
+ attr_container_printf(", type: float, value: %f\n", value.f);
+ p += 4;
+ break;
+ case ATTR_TYPE_DOUBLE:
+ bh_memcpy_s(&value.d, sizeof(double), p, sizeof(double));
+ attr_container_printf(", type: double, value: %f\n", value.d);
+ p += 8;
+ break;
+ case ATTR_TYPE_BOOLEAN:
+ bh_memcpy_s(&value.z, 1, p, 1);
+ attr_container_printf(", type: bool, value: 0x%x\n", value.z);
+ p++;
+ break;
+ case ATTR_TYPE_STRING:
+ attr_container_printf(", type: string, value: %s\n",
+ p + sizeof(uint16_t));
+ p += sizeof(uint16_t) + get_uint16(p);
+ break;
+ case ATTR_TYPE_BYTEARRAY:
+ attr_container_printf(", type: byte array, length: %d\n",
+ get_uint32(p));
+ p += sizeof(uint32_t) + get_uint32(p);
+ break;
+ default:
+ bh_assert(0);
+ break;
+ }
+ }
+
+ attr_container_printf("\n");
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/attr_container.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/attr_container.h
new file mode 100644
index 000000000..f5d8759b8
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/attr_container.h
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _ATTR_CONTAINER_H_
+#define _ATTR_CONTAINER_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "bh_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Attribute type */
+enum {
+ ATTR_TYPE_BEGIN = 0,
+ ATTR_TYPE_BYTE = ATTR_TYPE_BEGIN,
+ ATTR_TYPE_INT8 = ATTR_TYPE_BYTE,
+ ATTR_TYPE_SHORT,
+ ATTR_TYPE_INT16 = ATTR_TYPE_SHORT,
+ ATTR_TYPE_INT,
+ ATTR_TYPE_INT32 = ATTR_TYPE_INT,
+ ATTR_TYPE_INT64,
+ ATTR_TYPE_UINT8,
+ ATTR_TYPE_UINT16,
+ ATTR_TYPE_UINT32,
+ ATTR_TYPE_UINT64,
+ /**
+ * Why ATTR_TYPE_FLOAT = 10?
+ * We determine the number of bytes that should be copied through 1<<(type &
+ * 3). ATTR_TYPE_BYTE = 0, so the number of bytes is 1 << 0 = 1.
+ * ATTR_TYPE_UINT64 = 7, so the number of bytes is 1 << 3 = 8.
+ * Since the float type takes up 4 bytes, ATTR_TYPE_FLOAT should be 10.
+ * Calculation: (1 << (10&3)) = (1 << 2) = 4
+ */
+ ATTR_TYPE_FLOAT = 10,
+ ATTR_TYPE_DOUBLE,
+ ATTR_TYPE_BOOLEAN,
+ ATTR_TYPE_STRING,
+ ATTR_TYPE_BYTEARRAY,
+ ATTR_TYPE_END = ATTR_TYPE_BYTEARRAY
+};
+
+#define ATTR_CONT_READONLY_SHIFT 2
+
+typedef struct attr_container {
+ /* container flag:
+ * bit0, bit1 denote the implemenation algorithm, 00: buffer, 01: link list
+ * bit2 denotes the readonly flag: 1 is readonly and attr cannot be set
+ */
+ char flags[2];
+ /**
+ * Buffer format
+ * for buffer implementation:
+ * buf length (4 bytes)
+ * tag length (2 bytes)
+ * tag
+ * attr num (2bytes)
+ * attr[0..n-1]:
+ * attr key length (2 bytes)
+ * attr type (1byte)
+ * attr value (length depends on attr type)
+ */
+ char buf[1];
+} attr_container_t;
+
+/**
+ * Create attribute container
+ *
+ * @param tag tag of current attribute container
+ *
+ * @return the created attribute container, NULL if failed
+ */
+attr_container_t *
+attr_container_create(const char *tag);
+
+/**
+ * Destroy attribute container
+ *
+ * @param attr_cont the attribute container to destroy
+ */
+void
+attr_container_destroy(const attr_container_t *attr_cont);
+
+/**
+ * Set short attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
+ short value);
+
+/**
+ * Set int16 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_int16(attr_container_t **p_attr_cont, const char *key,
+ int16_t value);
+
+/**
+ * Set int attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
+ int value);
+
+/**
+ * Set int32 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_int32(attr_container_t **p_attr_cont, const char *key,
+ int32_t value);
+
+/**
+ * Set uint32 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_uint32(attr_container_t **p_attr_cont, const char *key,
+ uint32_t value);
+
+/**
+ * Set int64 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
+ int64_t value);
+
+/**
+ * Set uint64 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_uint64(attr_container_t **p_attr_cont, const char *key,
+ uint64_t value);
+
+/**
+ * Set byte attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
+ int8_t value);
+
+/**
+ * Set int8 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_int8(attr_container_t **p_attr_cont, const char *key,
+ int8_t value);
+
+/**
+ * Set uint8 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_uint8(attr_container_t **p_attr_cont, const char *key,
+ uint8_t value);
+
+/**
+ * Set uint16 attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
+ uint16_t value);
+
+/**
+ * Set float attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
+ float value);
+
+/**
+ * Set double attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
+ double value);
+
+/**
+ * Set bool attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
+ bool value);
+
+/**
+ * Set string attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the attribute value
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
+ const char *value);
+
+/**
+ * Set bytearray attribute in attribute container
+ *
+ * @param p_attr_cont pointer to attribute container to set attribute, and
+ * return the new attribute container if it is re-created
+ * @param key the attribute key
+ * @param value the bytearray buffer
+ * @param length the bytearray length
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
+ const int8_t *value, unsigned length);
+
+/**
+ * Get tag of current attribute container
+ *
+ * @param attr_cont the attribute container
+ *
+ * @return tag of current attribute container
+ */
+const char *
+attr_container_get_tag(const attr_container_t *attr_cont);
+
+/**
+ * Get attribute number of current attribute container
+ *
+ * @param attr_cont the attribute container
+ *
+ * @return attribute number of current attribute container
+ */
+uint16_t
+attr_container_get_attr_num(const attr_container_t *attr_cont);
+
+/**
+ * Whether the attribute container contains an attribute key.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return true if key is contained in message, false otherwise
+ */
+bool
+attr_container_contain_key(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as short value,
+ * return 0 if attribute isn't found in message.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the short value of the attribute, 0 if key isn't found
+ */
+short
+attr_container_get_as_short(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as int16 value,
+ * return 0 if attribute isn't found in message.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the short value of the attribute, 0 if key isn't found
+ */
+int16_t
+attr_container_get_as_int16(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as int value,
+ * return 0 if attribute isn't found in message.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the int value of the attribute, 0 if key isn't found
+ */
+int
+attr_container_get_as_int(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as int32 value,
+ * return 0 if attribute isn't found in message.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the int value of the attribute, 0 if key isn't found
+ */
+int32_t
+attr_container_get_as_int32(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as uint32 value,
+ * return 0 if attribute isn't found in message.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the unsigned int value of the attribute, 0 if key isn't found
+ */
+uint32_t
+attr_container_get_as_uint32(const attr_container_t *attr_cont,
+ const char *key);
+
+/**
+ * Get attribute from attribute container and return it as int64 value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the long value of the attribute, 0 if key isn't found
+ */
+int64_t
+attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as uint64 value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the unsigned long value of the attribute, 0 if key isn't found
+ */
+uint64_t
+attr_container_get_as_uint64(const attr_container_t *attr_cont,
+ const char *key);
+
+/**
+ * Get attribute from attribute container and return it as byte value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the byte value of the attribute, 0 if key isn't found
+ */
+int8_t
+attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as int8 value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the byte value of the attribute, 0 if key isn't found
+ */
+int8_t
+attr_container_get_as_int8(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as uint8 value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the uint8 value of the attribute, 0 if key isn't found
+ */
+uint8_t
+attr_container_get_as_uint8(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as uint16 value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the char value of the attribute, 0 if key isn't found
+ */
+uint16_t
+attr_container_get_as_uint16(const attr_container_t *attr_cont,
+ const char *key);
+
+/**
+ * Get attribute from attribute container and return it as float value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the float value of the attribute, 0 if key isn't found
+ */
+float
+attr_container_get_as_float(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as double value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the double value of the attribute, 0 if key isn't found
+ */
+double
+attr_container_get_as_double(const attr_container_t *attr_cont,
+ const char *key);
+
+/**
+ * Get attribute from attribute container and return it as bool value,
+ * return false if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the bool value of the attribute, 0 if key isn't found
+ */
+bool
+attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key);
+
+/**
+ * Get attribute from attribute container and return it as string value,
+ * return NULL if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the string value of the attribute, NULL if key isn't found
+ */
+char *
+attr_container_get_as_string(const attr_container_t *attr_cont,
+ const char *key);
+
+/**
+ * Get attribute from attribute container and return it as bytearray value,
+ * return 0 if attribute isn't found in attribute container.
+ *
+ * @param attr_cont the attribute container
+ * @param key the attribute key
+ *
+ * @return the bytearray value of the attribute, NULL if key isn't found
+ */
+const int8_t *
+attr_container_get_as_bytearray(const attr_container_t *attr_cont,
+ const char *key, unsigned *array_length);
+
+/**
+ * Get the buffer size of attribute container
+ *
+ * @param attr_cont the attribute container
+ *
+ * @return the buffer size of attribute container
+ */
+unsigned
+attr_container_get_serialize_length(const attr_container_t *attr_cont);
+
+/**
+ * Serialize attribute container to a buffer
+ *
+ * @param buf the buffer to receive the serialized data
+ * @param attr_cont the attribute container to be serialized
+ *
+ * @return true if success, false otherwise
+ */
+bool
+attr_container_serialize(char *buf, const attr_container_t *attr_cont);
+
+/**
+ * Whether the attribute container is const, or set attribute isn't supported
+ *
+ * @param attr_cont the attribute container
+ *
+ * @return true if const, false otherwise
+ */
+bool
+attr_container_is_constant(const attr_container_t *attr_cont);
+
+void
+attr_container_dump(const attr_container_t *attr_cont);
+
+#ifndef attr_container_malloc
+#define attr_container_malloc WA_MALLOC
+#endif
+
+#ifndef attr_container_free
+#define attr_container_free WA_FREE
+#endif
+
+#ifndef attr_container_printf
+#define attr_container_printf printf
+#endif
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* end of _ATTR_CONTAINER_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/shared_utils.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/shared_utils.h
new file mode 100644
index 000000000..8155ea1f7
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/shared_utils.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _SHARED_UTILS_H_
+#define _SHARED_UTILS_H_
+
+#include "bh_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FMT_ATTR_CONTAINER 99
+#define FMT_APP_RAW_BINARY 98
+
+/* the request structure */
+typedef struct request {
+ // message id
+ uint32 mid;
+
+ // url of the request
+ char *url;
+
+ // action of the request, can be PUT/GET/POST/DELETE
+ int action;
+
+ // payload format, currently only support attr_container_t type
+ int fmt;
+
+ // payload of the request, currently only support attr_container_t type
+ void *payload;
+
+ // length in bytes of the payload
+ int payload_len;
+
+ // sender of the request
+ unsigned long sender;
+} request_t;
+
+/* the response structure */
+typedef struct response {
+ // message id
+ uint32 mid;
+
+ // status of the response
+ int status;
+
+ // payload format
+ int fmt;
+
+ // payload of the response,
+ void *payload;
+
+ // length in bytes of the payload
+ int payload_len;
+
+ // receiver of the response
+ unsigned long reciever;
+} response_t;
+
+int
+check_url_start(const char *url, int url_len, const char *leading_str);
+
+bool
+match_url(char *pattern, char *matched);
+
+char *
+find_key_value(char *buffer, int buffer_len, char *key, char *value,
+ int value_len, char delimiter);
+
+request_t *
+clone_request(request_t *request);
+
+void
+request_cleaner(request_t *request);
+
+response_t *
+clone_response(response_t *response);
+
+void
+response_cleaner(response_t *response);
+
+/**
+ * @brief Set fields of response.
+ *
+ * @param response pointer of the response to be set
+ * @param status status of response
+ * @param fmt format of the response payload
+ * @param payload payload of the response
+ * @param payload_len length in bytes of the response payload
+ *
+ * @return pointer to the response
+ *
+ * @warning the response pointer MUST NOT be NULL
+ */
+response_t *
+set_response(response_t *response, int status, int fmt, const char *payload,
+ int payload_len);
+
+/**
+ * @brief Make a response for a request.
+ *
+ * @param request pointer of the request
+ * @param response pointer of the response to be made
+ *
+ * @return pointer to the response
+ *
+ * @warning the request and response pointers MUST NOT be NULL
+ */
+response_t *
+make_response_for_request(request_t *request, response_t *response);
+
+/**
+ * @brief Initialize a request.
+ *
+ * @param request pointer of the request to be initialized
+ * @param url url of the request
+ * @param action action of the request
+ * @param fmt format of the request payload
+ * @param payload payload of the request
+ * @param payload_len length in bytes of the request payload
+ *
+ * @return pointer to the request
+ *
+ * @warning the request pointer MUST NOT be NULL
+ */
+request_t *
+init_request(request_t *request, char *url, int action, int fmt, void *payload,
+ int payload_len);
+
+char *
+pack_request(request_t *request, int *size);
+
+request_t *
+unpack_request(char *packet, int size, request_t *request);
+
+char *
+pack_response(response_t *response, int *size);
+
+response_t *
+unpack_response(char *packet, int size, response_t *response);
+
+void
+free_req_resp_packet(char *packet);
+
+char *
+wa_strdup(const char *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of _SHARED_UTILS_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h
new file mode 100644
index 000000000..86d864e41
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H
+#define WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H
+
+#include "bh_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+/* Object native function IDs */
+enum {
+ OBJ_FUNC_ID_DEL,
+ OBJ_FUNC_ID_DEL_ASYNC,
+ OBJ_FUNC_ID_CLEAN,
+ OBJ_FUNC_ID_SET_EVT_CB,
+ OBJ_FUNC_ID_ALIGN,
+
+ /* Number of functions */
+ _OBJ_FUNC_ID_NUM,
+};
+
+/* Button native function IDs */
+enum {
+ BTN_FUNC_ID_CREATE,
+ BTN_FUNC_ID_SET_TOGGLE,
+ BTN_FUNC_ID_SET_STATE,
+ BTN_FUNC_ID_TOGGLE,
+ BTN_FUNC_ID_SET_INK_IN_TIME,
+ BTN_FUNC_ID_SET_INK_WAIT_TIME,
+ BTN_FUNC_ID_SET_INK_OUT_TIME,
+ BTN_FUNC_ID_GET_STATE,
+ BTN_FUNC_ID_GET_TOGGLE,
+ BTN_FUNC_ID_GET_INK_IN_TIME,
+ BTN_FUNC_ID_GET_INK_WAIT_TIME,
+ BTN_FUNC_ID_GET_INK_OUT_TIME,
+ /* Number of functions */
+ _BTN_FUNC_ID_NUM,
+};
+
+/* Check box native function IDs */
+enum {
+ CB_FUNC_ID_CREATE,
+ CB_FUNC_ID_SET_TEXT,
+ CB_FUNC_ID_SET_STATIC_TEXT,
+ CB_FUNC_ID_GET_TEXT,
+ CB_FUNC_ID_GET_TEXT_LENGTH,
+
+ /* Number of functions */
+ _CB_FUNC_ID_NUM,
+};
+
+/* List native function IDs */
+enum {
+ LIST_FUNC_ID_CREATE,
+ LIST_FUNC_ID_ADD_BTN,
+
+ /* Number of functions */
+ _LIST_FUNC_ID_NUM,
+};
+
+/* Label native function IDs */
+enum {
+ LABEL_FUNC_ID_CREATE,
+ LABEL_FUNC_ID_SET_TEXT,
+ LABEL_FUNC_ID_SET_ARRAY_TEXT,
+ LABEL_FUNC_ID_SET_STATIC_TEXT,
+ LABEL_FUNC_ID_SET_LONG_MODE,
+ LABEL_FUNC_ID_SET_ALIGN,
+ LABEL_FUNC_ID_SET_RECOLOR,
+ LABEL_FUNC_ID_SET_BODY_DRAW,
+ LABEL_FUNC_ID_SET_ANIM_SPEED,
+ LABEL_FUNC_ID_SET_TEXT_SEL_START,
+ LABEL_FUNC_ID_SET_TEXT_SEL_END,
+ LABEL_FUNC_ID_GET_TEXT,
+ LABEL_FUNC_ID_GET_TEXT_LENGTH,
+ LABEL_FUNC_ID_GET_LONG_MODE,
+ LABEL_FUNC_ID_GET_ALIGN,
+ LABEL_FUNC_ID_GET_RECOLOR,
+ LABEL_FUNC_ID_GET_BODY_DRAW,
+ LABEL_FUNC_ID_GET_ANIM_SPEED,
+ LABEL_FUNC_ID_GET_LETTER_POS,
+ LABEL_FUNC_ID_GET_TEXT_SEL_START,
+ LABEL_FUNC_ID_GET_TEXT_SEL_END,
+ LABEL_FUNC_ID_INS_TEXT,
+ LABEL_FUNC_ID_CUT_TEXT,
+ /* Number of functions */
+ _LABEL_FUNC_ID_NUM,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.cmake b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.cmake
new file mode 100644
index 000000000..48ebe0a33
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.cmake
@@ -0,0 +1,15 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+set (NATIVE_INTERFACE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+include_directories(${NATIVE_INTERFACE_DIR})
+
+
+file (GLOB_RECURSE source_all ${NATIVE_INTERFACE_DIR}/*.c)
+
+set (NATIVE_INTERFACE_SOURCE ${source_all})
+
+set (WASM_APP_BI_INC_DIR "${NATIVE_INTERFACE_DIR}/bi-inc")
+LIST (APPEND RUNTIME_LIB_HEADER_LIST "${NATIVE_INTERFACE_DIR}/native_interface.h")
+
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.h
new file mode 100644
index 000000000..ce9f24780
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/native_interface.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _NATIVE_INTERFACE_H_
+#define _NATIVE_INTERFACE_H_
+
+/* Note: the bh_plaform.h is the only head file separately
+ implemented by both [app] and [native] worlds */
+#include "bh_platform.h"
+
+#endif /* end of _NATIVE_INTERFACE_H */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/restful_utils.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/restful_utils.c
new file mode 100644
index 000000000..03e86a699
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-framework/app-native-shared/restful_utils.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "bi-inc/shared_utils.h"
+
+/* Serialization of request and response message
+ *
+ * Choices:
+ * We considered a few options:
+ * 1. coap
+ * 2. flatbuffer
+ * 3. cbor
+ * 4. attr-containers of our own
+ * 5. customized serialization for request/response
+ *
+ * Now we choose the #5 mainly because we need to quickly get the URL for
+ * dispatching and sometimes we want to change the URL in the original packet.
+ * the request format: fixed part: version: (1 byte), code (1 byte), fmt(2
+ * byte), mid (4 bytes), sender_id(4 bytes), url_len(2 bytes),
+ * payload_len(4bytes) dynamic part: url (bytes in url_len), payload
+ *
+ * response format:
+ * fixed part: (1 byte), code (1 byte), fmt(2 byte), mid (4 bytes), sender_id(4
+ * bytes), payload_len(4bytes) dynamic part: payload
+ */
+#define REQUES_PACKET_VER 1
+#define REQUEST_PACKET_FIX_PART_LEN 18
+#define REQUEST_PACKET_URL_OFFSET REQUEST_PACKET_FIX_PART_LEN
+#define REQUEST_PACKET_URL_LEN \
+ *((uint16 *)((char *)buffer + 12)) /* to ensure little endian */
+#define REQUEST_PACKET_PAYLOAD_LEN \
+ *((uint32 *)((char *)buffer + 14)) /* to ensure little endian */
+#define REQUEST_PACKET_URL(buffer) ((char *)buffer + REQUEST_PACKET_URL_OFFSET)
+#define REQUEST_PACKET_PAYLOAD(buffer) \
+ ((char *)buffer + REQUEST_PACKET_URL_OFFSET \
+ + REQUEST_PACKET_URL_LEN(buffer))
+
+#define RESPONSE_PACKET_FIX_PART_LEN 16
+
+char *
+pack_request(request_t *request, int *size)
+{
+ int url_len = strlen(request->url) + 1;
+ int len = REQUEST_PACKET_FIX_PART_LEN + url_len + request->payload_len;
+ uint16 u16;
+ uint32 u32;
+ char *packet;
+
+ if ((packet = (char *)WA_MALLOC(len)) == NULL)
+ return NULL;
+
+ /* TODO: ensure little endian for words and dwords */
+ *packet = REQUES_PACKET_VER;
+ *((uint8 *)(packet + 1)) = request->action;
+
+ u16 = htons(request->fmt);
+ memcpy(packet + 2, &u16, 2);
+
+ u32 = htonl(request->mid);
+ memcpy(packet + 4, &u32, 4);
+
+ u32 = htonl(request->sender);
+ memcpy(packet + 8, &u32, 4);
+
+ u16 = htons(url_len);
+ memcpy(packet + 12, &u16, 2);
+
+ u32 = htonl(request->payload_len);
+ memcpy(packet + 14, &u32, 4);
+
+ strcpy(packet + REQUEST_PACKET_URL_OFFSET, request->url);
+ memcpy(packet + REQUEST_PACKET_URL_OFFSET + url_len, request->payload,
+ request->payload_len);
+
+ *size = len;
+ return packet;
+}
+
+void
+free_req_resp_packet(char *packet)
+{
+ WA_FREE(packet);
+}
+
+request_t *
+unpack_request(char *packet, int size, request_t *request)
+{
+ uint16 url_len, u16;
+ uint32 payload_len, u32;
+
+ if (*packet != REQUES_PACKET_VER) {
+ return NULL;
+ }
+ if (size < REQUEST_PACKET_FIX_PART_LEN) {
+ return NULL;
+ }
+
+ memcpy(&u16, packet + 12, 2);
+ url_len = ntohs(u16);
+
+ memcpy(&u32, packet + 14, 4);
+ payload_len = ntohl(u32);
+
+ if (size != (REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
+ return NULL;
+ }
+
+ if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
+ return NULL;
+ }
+
+ request->action = *((uint8 *)(packet + 1));
+
+ memcpy(&u16, packet + 2, 2);
+ request->fmt = ntohs(u16);
+
+ memcpy(&u32, packet + 4, 4);
+ request->mid = ntohl(u32);
+
+ memcpy(&u32, packet + 8, 4);
+ request->sender = ntohl(u32);
+
+ request->payload_len = payload_len;
+ request->url = REQUEST_PACKET_URL(packet);
+
+ if (payload_len > 0)
+ request->payload = packet + REQUEST_PACKET_URL_OFFSET + url_len;
+ else
+ request->payload = NULL;
+
+ return request;
+}
+
+char *
+pack_response(response_t *response, int *size)
+{
+ int len = RESPONSE_PACKET_FIX_PART_LEN + response->payload_len;
+ uint16 u16;
+ uint32 u32;
+ char *packet;
+
+ if ((packet = (char *)WA_MALLOC(len)) == NULL)
+ return NULL;
+
+ /* TODO: ensure little endian for words and dwords */
+ *packet = REQUES_PACKET_VER;
+ *((uint8 *)(packet + 1)) = response->status;
+
+ u16 = htons(response->fmt);
+ memcpy(packet + 2, &u16, 2);
+
+ u32 = htonl(response->mid);
+ memcpy(packet + 4, &u32, 4);
+
+ u32 = htonl(response->reciever);
+ memcpy(packet + 8, &u32, 4);
+
+ u32 = htonl(response->payload_len);
+ memcpy(packet + 12, &u32, 4);
+
+ memcpy(packet + RESPONSE_PACKET_FIX_PART_LEN, response->payload,
+ response->payload_len);
+
+ *size = len;
+ return packet;
+}
+
+response_t *
+unpack_response(char *packet, int size, response_t *response)
+{
+ uint16 u16;
+ uint32 payload_len, u32;
+
+ if (*packet != REQUES_PACKET_VER)
+ return NULL;
+
+ if (size < RESPONSE_PACKET_FIX_PART_LEN)
+ return NULL;
+
+ memcpy(&u32, packet + 12, 4);
+ payload_len = ntohl(u32);
+ if (size != (RESPONSE_PACKET_FIX_PART_LEN + payload_len))
+ return NULL;
+
+ response->status = *((uint8 *)(packet + 1));
+
+ memcpy(&u16, packet + 2, 2);
+ response->fmt = ntohs(u16);
+
+ memcpy(&u32, packet + 4, 4);
+ response->mid = ntohl(u32);
+
+ memcpy(&u32, packet + 8, 4);
+ response->reciever = ntohl(u32);
+
+ response->payload_len = payload_len;
+ if (payload_len > 0)
+ response->payload = packet + RESPONSE_PACKET_FIX_PART_LEN;
+ else
+ response->payload = NULL;
+
+ return response;
+}
+
+request_t *
+clone_request(request_t *request)
+{
+ /* deep clone */
+ request_t *req = (request_t *)WA_MALLOC(sizeof(request_t));
+ if (req == NULL)
+ return NULL;
+
+ memset(req, 0, sizeof(*req));
+ req->action = request->action;
+ req->fmt = request->fmt;
+ req->url = wa_strdup(request->url);
+ req->sender = request->sender;
+ req->mid = request->mid;
+
+ if (req->url == NULL)
+ goto fail;
+
+ req->payload_len = request->payload_len;
+
+ if (request->payload_len) {
+ req->payload = (char *)WA_MALLOC(request->payload_len);
+ if (!req->payload)
+ goto fail;
+ memcpy(req->payload, request->payload, request->payload_len);
+ }
+ else {
+ /* when payload_len is 0, the payload may be used for
+ carrying some handle or integer */
+ req->payload = request->payload;
+ }
+
+ return req;
+
+fail:
+ request_cleaner(req);
+ return NULL;
+}
+
+void
+request_cleaner(request_t *request)
+{
+ if (request->url != NULL)
+ WA_FREE(request->url);
+ if (request->payload != NULL && request->payload_len > 0)
+ WA_FREE(request->payload);
+
+ WA_FREE(request);
+}
+
+void
+response_cleaner(response_t *response)
+{
+ if (response->payload != NULL && response->payload_len > 0)
+ WA_FREE(response->payload);
+
+ WA_FREE(response);
+}
+
+response_t *
+clone_response(response_t *response)
+{
+ response_t *clone = (response_t *)WA_MALLOC(sizeof(response_t));
+
+ if (clone == NULL)
+ return NULL;
+
+ memset(clone, 0, sizeof(*clone));
+ clone->fmt = response->fmt;
+ clone->mid = response->mid;
+ clone->status = response->status;
+ clone->reciever = response->reciever;
+ clone->payload_len = response->payload_len;
+ if (clone->payload_len) {
+ clone->payload = (char *)WA_MALLOC(response->payload_len);
+ if (!clone->payload)
+ goto fail;
+ memcpy(clone->payload, response->payload, response->payload_len);
+ }
+ else {
+ /* when payload_len is 0, the payload may be used for
+ carrying some handle or integer */
+ clone->payload = response->payload;
+ }
+ return clone;
+
+fail:
+ response_cleaner(clone);
+ return NULL;
+}
+
+response_t *
+set_response(response_t *response, int status, int fmt, const char *payload,
+ int payload_len)
+{
+ response->payload = (void *)payload;
+ response->payload_len = payload_len;
+ response->status = status;
+ response->fmt = fmt;
+ return response;
+}
+
+response_t *
+make_response_for_request(request_t *request, response_t *response)
+{
+ response->mid = request->mid;
+ response->reciever = request->sender;
+
+ return response;
+}
+
+static unsigned int mid = 0;
+
+request_t *
+init_request(request_t *request, char *url, int action, int fmt, void *payload,
+ int payload_len)
+{
+ request->url = url;
+ request->action = action;
+ request->fmt = fmt;
+ request->payload = payload;
+ request->payload_len = payload_len;
+ request->mid = ++mid;
+
+ return request;
+}
+
+/*
+ check if the "url" is starting with "leading_str"
+ return: 0 - not match; >0 - the offset of matched url, include any "/" at the
+ end notes:
+ 1. it ensures the leading_str "/abc" can pass "/abc/cde" and "/abc/, but fail
+ "/ab" and "/abcd". leading_str "/abc/" can pass "/abc"
+ 2. it omit the '/' at the first char
+ 3. it ensure the leading_str "/abc" can pass "/abc?cde
+ */
+
+int
+check_url_start(const char *url, int url_len, const char *leading_str)
+{
+ int offset = 0;
+ if (*leading_str == '/')
+ leading_str++;
+ if (url_len > 0 && *url == '/') {
+ url_len--;
+ url++;
+ offset++;
+ }
+
+ int len = strlen(leading_str);
+ if (len == 0)
+ return 0;
+
+ /* ensure leading_str not end with "/" */
+ if (leading_str[len - 1] == '/') {
+ len--;
+ if (len == 0)
+ return 0;
+ }
+
+ /* equal length */
+ if (url_len == len) {
+ if (memcmp(url, leading_str, url_len) == 0) {
+ return (offset + len);
+ }
+ else {
+ return 0;
+ }
+ }
+
+ if (url_len < len)
+ return 0;
+ else if (memcmp(url, leading_str, len) != 0)
+ return 0;
+ else if (url[len] != '/' && url[len] != '?')
+ return 0;
+ else
+ return (offset + len + 1);
+}
+
+// * @pattern:
+// * sample 1: /abcd, match /abcd only
+// * sample 2: /abcd/ match match "/abcd" and "/abcd/*"
+// * sample 3: /abcd*, match any url started with "/abcd"
+// * sample 4: /abcd/*, exclude "/abcd"
+
+bool
+match_url(char *pattern, char *matched)
+{
+ if (*pattern == '/')
+ pattern++;
+ if (*matched == '/')
+ matched++;
+
+ int matched_len = strlen(matched);
+ if (matched_len == 0)
+ return false;
+
+ if (matched[matched_len - 1] == '/') {
+ matched_len--;
+ if (matched_len == 0)
+ return false;
+ }
+
+ int len = strlen(pattern);
+ if (len == 0)
+ return false;
+
+ if (pattern[len - 1] == '/') {
+ len--;
+ if (strncmp(pattern, matched, len) != 0)
+ return false;
+
+ if (len == matched_len)
+ return true;
+
+ if (matched_len > len && matched[len] == '/')
+ return true;
+
+ return false;
+ }
+ else if (pattern[len - 1] == '*') {
+ if (pattern[len - 2] == '/') {
+ if (strncmp(pattern, matched, len - 1) == 0)
+ return true;
+ else
+ return false;
+ }
+ else {
+ return (strncmp(pattern, matched, len - 1) == 0);
+ }
+ }
+ else {
+ return (strcmp(pattern, matched) == 0);
+ }
+}
+
+/*
+ * get the value of the key from following format buffer:
+ * key1=value1;key2=value2;key3=value3
+ */
+char *
+find_key_value(char *buffer, int buffer_len, char *key, char *value,
+ int value_len, char delimiter)
+{
+ char *p = buffer;
+ int remaining = buffer_len;
+ int key_len = strlen(key);
+
+ while (*p != 0 && remaining > 0) {
+ while (*p == ' ' || *p == delimiter) {
+ p++;
+ remaining--;
+ }
+
+ if (remaining <= key_len)
+ return NULL;
+
+ /* find the key */
+ if (0 == strncmp(p, key, key_len) && p[key_len] == '=') {
+ p += (key_len + 1);
+ remaining -= (key_len + 1);
+ char *v = value;
+ memset(value, 0, value_len);
+ value_len--; /* ensure last char is 0 */
+ while (*p != delimiter && remaining > 0 && value_len > 0) {
+ *v++ = *p++;
+ remaining--;
+ value_len--;
+ }
+ return value;
+ }
+
+ /* goto next key */
+ while (*p != delimiter && remaining > 0) {
+ p++;
+ remaining--;
+ }
+ }
+
+ return NULL;
+}