Enable AoT and wamr-sdk, and change arguments of call wasm API (#157)
* Implement memory profiler, optimize memory usage, modify code indent * Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default * Add a new extension library: connection * Fix bug of reading magic number and version in big endian platform * Re-org platform APIs: move most platform APIs from iwasm to shared-lib * Enhance wasm loader to fix some security issues * Fix issue about illegal load of EXC_RETURN into PC on stm32 board * Updates that let a restricted version of the interpreter run in SGX * Enable native/app address validation and conversion for wasm app * Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused * Refine binary size and fix several minor issues Optimize interpreter LOAD/STORE opcodes to decrease the binary size Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper Add macros of global heap size, stack size, heap size for Zephyr main.c Clear compile warning of wasm_application.c * Add more strict security checks for libc wrapper API's * Use one libc wrapper copy for sgx and other platforms; remove bh_printf macro for other platform header files * Enhance security of libc strcpy/sprintf wrapper function * Fix issue of call native for x86_64/arm/mips, add module inst parameter for native wrapper functions * Remove get_module_inst() and fix issue of call native * Refine wgl lib: remove module_inst parameter from widget functions; move function index check to runtime instantiate * Refine interpreter call native process, refine memory boudary check * Fix issues of invokeNative function of arm/mips/general version * Add a switch to build simple sample without gui support * Add BUILD_TARGET setting in makefile to replace cpu compiler flags in source code * Re-org shared lib header files, remove unused info; fix compile issues of vxworks * Add build target general * Remove unused files * Update license header * test push * Restore file * Sync up with internal/feature * Sync up with internal/feature * Rename build_wamr_app to build_wasm_app * Fix small issues of README * Enhance malformed wasm file checking Fix issue of print hex int and implement utf8 string check Fix wasi file read/write right issue Fix minor issue of build wasm app doc * Sync up with internal/feature * Sync up with internal/feature: fix interpreter arm issue, fix read leb issue * Sync up with internal/feature * Fix bug of config.h and rename wasi config.h to ssp_config.h * Sync up with internal/feature * Import wamr aot * update document * update document * Update document, disable WASI in 32bit * update document * remove files * update document * Update document * update document * update document * update samples * Sync up with internal repo
This commit is contained in:
11
core/app-framework/app-native-shared/README.md
Normal file
11
core/app-framework/app-native-shared/README.md
Normal file
@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
830
core/app-framework/app-native-shared/attr_container.c
Normal file
830
core/app-framework/app-native-shared/attr_container.c
Normal file
@ -0,0 +1,830 @@
|
||||
/*
|
||||
* 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 b;
|
||||
uint16_t c;
|
||||
int16_t s;
|
||||
int32_t i;
|
||||
int64_t j;
|
||||
float f;
|
||||
double d;
|
||||
} jvalue;
|
||||
|
||||
#define bh_memcpy_s(dest, dlen, src, slen) do { \
|
||||
int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen); \
|
||||
(void)_ret; \
|
||||
} while (0)
|
||||
|
||||
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)
|
||||
{
|
||||
return get_int16(buf);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return get_int32(buf);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return get_int64(buf);
|
||||
}
|
||||
|
||||
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 (p - attr_cont->buf >= total_length)
|
||||
return NULL;
|
||||
|
||||
/* attribute num */
|
||||
attr_num = get_uint16(p);
|
||||
p += sizeof(uint16_t);
|
||||
if (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++;
|
||||
|
||||
/* Short type to Boolean type */
|
||||
if (type >= ATTR_TYPE_SHORT && 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 (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_SHORT && 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 = 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_SHORT && 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 (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 (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_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_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_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_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 false;
|
||||
}
|
||||
|
||||
/* 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.j = 0; \
|
||||
type = *(uint8_t*)addr++; \
|
||||
switch (type) { \
|
||||
case ATTR_TYPE_SHORT: \
|
||||
case ATTR_TYPE_INT: \
|
||||
case ATTR_TYPE_INT64: \
|
||||
case ATTR_TYPE_BYTE: \
|
||||
case ATTR_TYPE_UINT16: \
|
||||
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; \
|
||||
} \
|
||||
} \
|
||||
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, s);
|
||||
}
|
||||
|
||||
int attr_container_get_as_int(const attr_container_t *attr_cont,
|
||||
const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i);
|
||||
}
|
||||
|
||||
int64_t attr_container_get_as_int64(const attr_container_t *attr_cont,
|
||||
const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, j);
|
||||
}
|
||||
|
||||
int8_t attr_container_get_as_byte(const attr_container_t *attr_cont,
|
||||
const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, b);
|
||||
}
|
||||
|
||||
uint16_t attr_container_get_as_uint16(const attr_container_t *attr_cont,
|
||||
const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, s);
|
||||
}
|
||||
|
||||
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_SHORT:
|
||||
case ATTR_TYPE_INT:
|
||||
case ATTR_TYPE_INT64:
|
||||
case ATTR_TYPE_BYTE:
|
||||
case ATTR_TYPE_UINT16:
|
||||
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_SHORT:
|
||||
bh_memcpy_s(&value.s, sizeof(int16_t), p, sizeof(int16_t));
|
||||
attr_container_printf(", type: short, value: 0x%x\n",
|
||||
value.s & 0xFFFF);
|
||||
p += 2;
|
||||
break;
|
||||
case ATTR_TYPE_INT:
|
||||
bh_memcpy_s(&value.i, sizeof(int32_t), p, sizeof(int32_t));
|
||||
attr_container_printf(", type: int, value: 0x%x\n", value.i);
|
||||
p += 4;
|
||||
break;
|
||||
case ATTR_TYPE_INT64:
|
||||
bh_memcpy_s(&value.j, sizeof(uint64_t), p, sizeof(uint64_t));
|
||||
attr_container_printf(", type: int64, value: 0x%llx\n", (long long unsigned int)(value.j));
|
||||
p += 8;
|
||||
break;
|
||||
case ATTR_TYPE_BYTE:
|
||||
bh_memcpy_s(&value.b, 1, p, 1);
|
||||
attr_container_printf(", type: byte, value: 0x%x\n",
|
||||
value.b & 0xFF);
|
||||
p++;
|
||||
break;
|
||||
case ATTR_TYPE_UINT16:
|
||||
bh_memcpy_s(&value.c, sizeof(uint16_t), p, sizeof(uint16_t));
|
||||
attr_container_printf(", type: uint16, value: 0x%x\n", value.c);
|
||||
p += 2;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
attr_container_printf("\n");
|
||||
}
|
||||
|
||||
425
core/app-framework/app-native-shared/bi-inc/attr_container.h
Normal file
425
core/app-framework/app-native-shared/bi-inc/attr_container.h
Normal file
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* 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 <inttypes.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 = 1,
|
||||
ATTR_TYPE_SHORT = ATTR_TYPE_BEGIN,
|
||||
ATTR_TYPE_INT,
|
||||
ATTR_TYPE_INT64,
|
||||
ATTR_TYPE_BYTE,
|
||||
ATTR_TYPE_UINT16,
|
||||
ATTR_TYPE_FLOAT,
|
||||
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 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 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 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 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 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 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 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 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_ */
|
||||
|
||||
154
core/app-framework/app-native-shared/bi-inc/shared_utils.h
Normal file
154
core/app-framework/app-native-shared/bi-inc/shared_utils.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _SHARED_UTILS_H_ */
|
||||
335
core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h
Normal file
335
core/app-framework/app-native-shared/bi-inc/wgl_shared_utils.h
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#include "lv_conf.h"
|
||||
|
||||
typedef lv_coord_t wgl_coord_t; /* lv_coord_t is defined in lv_conf.h */
|
||||
typedef void * wgl_font_user_data_t;
|
||||
|
||||
/**
|
||||
* Represents a point on the screen.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
} wgl_point_t;
|
||||
|
||||
/** Represents an area of the screen. */
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t x1;
|
||||
lv_coord_t y1;
|
||||
lv_coord_t x2;
|
||||
lv_coord_t y2;
|
||||
} wgl_area_t;
|
||||
|
||||
|
||||
/** Describes the properties of a glyph. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */
|
||||
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||
int8_t ofs_y; /**< y offset of the bounding box*/
|
||||
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
||||
}wgl_font_glyph_dsc_t;
|
||||
|
||||
/*Describe the properties of a font*/
|
||||
typedef struct _wgl_font_struct
|
||||
{
|
||||
/** Get a glyph's descriptor from a font*/
|
||||
bool (*get_glyph_dsc)(const struct _wgl_font_struct *, wgl_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/** Get a glyph's bitmap from a font*/
|
||||
const uint8_t * (*get_glyph_bitmap)(const struct _wgl_font_struct *, uint32_t);
|
||||
|
||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||
uint8_t line_height; /**< The real line height where any text fits*/
|
||||
uint8_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
void * dsc; /**< Store implementation specific data here*/
|
||||
#if LV_USE_USER_DATA
|
||||
wgl_font_user_data_t user_data; /**< Custom user data for font. */
|
||||
#endif
|
||||
} wgl_font_t;
|
||||
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_SIZE 8
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
#define LV_COLOR_SIZE 8
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#define LV_COLOR_SIZE 16
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_SIZE 32
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t blue : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t red : 1;
|
||||
uint8_t full : 1;
|
||||
} wgl_color1_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t blue : 2;
|
||||
uint8_t green : 3;
|
||||
uint8_t red : 3;
|
||||
} ch;
|
||||
uint8_t full;
|
||||
} wgl_color8_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
uint16_t blue : 5;
|
||||
uint16_t green : 6;
|
||||
uint16_t red : 5;
|
||||
#else
|
||||
uint16_t green_h : 3;
|
||||
uint16_t red : 5;
|
||||
uint16_t blue : 5;
|
||||
uint16_t green_l : 3;
|
||||
#endif
|
||||
} ch;
|
||||
uint16_t full;
|
||||
} wgl_color16_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t alpha;
|
||||
} ch;
|
||||
uint32_t full;
|
||||
} wgl_color32_t;
|
||||
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
typedef uint8_t wgl_color_int_t;
|
||||
typedef wgl_color1_t wgl_color_t;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
typedef uint8_t wgl_color_int_t;
|
||||
typedef wgl_color8_t wgl_color_t;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
typedef uint16_t wgl_color_int_t;
|
||||
typedef wgl_color16_t wgl_color_t;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
typedef uint32_t wgl_color_int_t;
|
||||
typedef wgl_color32_t wgl_color_t;
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
||||
#endif
|
||||
|
||||
typedef uint8_t wgl_opa_t;
|
||||
|
||||
|
||||
|
||||
/*Border types (Use 'OR'ed values)*/
|
||||
enum {
|
||||
WGL_BORDER_NONE = 0x00,
|
||||
WGL_BORDER_BOTTOM = 0x01,
|
||||
WGL_BORDER_TOP = 0x02,
|
||||
WGL_BORDER_LEFT = 0x04,
|
||||
WGL_BORDER_RIGHT = 0x08,
|
||||
WGL_BORDER_FULL = 0x0F,
|
||||
WGL_BORDER_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
|
||||
};
|
||||
typedef uint8_t wgl_border_part_t;
|
||||
|
||||
/*Shadow types*/
|
||||
enum {
|
||||
WGL_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */
|
||||
WGL_SHADOW_FULL, /**< Draw shadow on all sides */
|
||||
};
|
||||
typedef uint8_t wgl_shadow_type_t;
|
||||
|
||||
/**
|
||||
* Objects in LittlevGL can be assigned a style - which holds information about
|
||||
* how the object should be drawn.
|
||||
*
|
||||
* This allows for easy customization without having to modify the object's design
|
||||
* function.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t glass : 1; /**< 1: Do not inherit this style*/
|
||||
|
||||
/** Object background. */
|
||||
struct
|
||||
{
|
||||
wgl_color_t main_color; /**< Object's main background color. */
|
||||
wgl_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */
|
||||
wgl_coord_t radius; /**< Object's corner radius. You can use #WGL_RADIUS_CIRCLE if you want to draw a circle. */
|
||||
wgl_opa_t opa; /**< Object's opacity (0-255). */
|
||||
|
||||
struct
|
||||
{
|
||||
wgl_color_t color; /**< Border color */
|
||||
wgl_coord_t width; /**< Border width */
|
||||
wgl_border_part_t part; /**< Which borders to draw */
|
||||
wgl_opa_t opa; /**< Border opacity. */
|
||||
} border;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
wgl_color_t color;
|
||||
wgl_coord_t width;
|
||||
wgl_shadow_type_t type; /**< Which parts of the shadow to draw */
|
||||
} shadow;
|
||||
|
||||
struct
|
||||
{
|
||||
wgl_coord_t top;
|
||||
wgl_coord_t bottom;
|
||||
wgl_coord_t left;
|
||||
wgl_coord_t right;
|
||||
wgl_coord_t inner;
|
||||
} padding;
|
||||
} body;
|
||||
|
||||
/** Style for text drawn by this object. */
|
||||
struct
|
||||
{
|
||||
wgl_color_t color; /**< Text color */
|
||||
wgl_color_t sel_color; /**< Text selection background color. */
|
||||
const wgl_font_t * font;
|
||||
wgl_coord_t letter_space; /**< Space between letters */
|
||||
wgl_coord_t line_space; /**< Space between lines (vertical) */
|
||||
wgl_opa_t opa; /**< Text opacity */
|
||||
} text;
|
||||
|
||||
/**< Style of images. */
|
||||
struct
|
||||
{
|
||||
wgl_color_t color; /**< Color to recolor the image with */
|
||||
wgl_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */
|
||||
wgl_opa_t opa; /**< Opacity of whole image */
|
||||
} image;
|
||||
|
||||
/**< Style of lines (not borders). */
|
||||
struct
|
||||
{
|
||||
wgl_color_t color;
|
||||
wgl_coord_t width;
|
||||
wgl_opa_t opa;
|
||||
uint8_t rounded : 1; /**< 1: rounded line endings*/
|
||||
} line;
|
||||
} wgl_style_t;
|
||||
|
||||
|
||||
|
||||
/* 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 */
|
||||
15
core/app-framework/app-native-shared/native_interface.cmake
Normal file
15
core/app-framework/app-native-shared/native_interface.cmake
Normal file
@ -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")
|
||||
|
||||
133
core/app-framework/app-native-shared/native_interface.h
Normal file
133
core/app-framework/app-native-shared/native_interface.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#define get_module_inst(exec_env) \
|
||||
wasm_runtime_get_module_inst(exec_env)
|
||||
|
||||
#define validate_app_addr(offset, size) \
|
||||
wasm_runtime_validate_app_addr(module_inst, offset, size)
|
||||
|
||||
#define validate_app_str_addr(offset) \
|
||||
wasm_runtime_validate_app_str_addr(module_inst, offset)
|
||||
|
||||
#define addr_app_to_native(offset) \
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset)
|
||||
|
||||
#define addr_native_to_app(ptr) \
|
||||
wasm_runtime_addr_native_to_app(module_inst, ptr)
|
||||
|
||||
#define module_malloc(size) \
|
||||
wasm_runtime_module_malloc(module_inst, size)
|
||||
|
||||
#define module_free(offset) \
|
||||
wasm_runtime_module_free(module_inst, offset)
|
||||
|
||||
/*char *wa_strdup(const char *);*/
|
||||
|
||||
/*
|
||||
* request/response interfaces
|
||||
*/
|
||||
|
||||
bool
|
||||
wasm_response_send(wasm_exec_env_t exec_env,
|
||||
int32 buffer_offset, int size);
|
||||
void
|
||||
wasm_register_resource(wasm_exec_env_t exec_env,
|
||||
int32 url_offset);
|
||||
void
|
||||
wasm_post_request(wasm_exec_env_t exec_env,
|
||||
int32 buffer_offset, int size);
|
||||
void
|
||||
wasm_sub_event(wasm_exec_env_t exec_env,
|
||||
int32 url_offset);
|
||||
|
||||
/*
|
||||
* sensor interfaces
|
||||
*/
|
||||
|
||||
bool
|
||||
wasm_sensor_config(wasm_exec_env_t exec_env,
|
||||
uint32 sensor, int interval, int bit_cfg, int delay);
|
||||
uint32
|
||||
wasm_sensor_open(wasm_exec_env_t exec_env,
|
||||
int32 name_offset, int instance);
|
||||
bool
|
||||
wasm_sensor_config_with_attr_container(wasm_exec_env_t exec_env,
|
||||
uint32 sensor,
|
||||
int32 buffer_offset, int len);
|
||||
bool
|
||||
wasm_sensor_close(wasm_exec_env_t exec_env,
|
||||
uint32 sensor);
|
||||
|
||||
/*
|
||||
* timer interfaces
|
||||
*/
|
||||
|
||||
typedef unsigned int timer_id_t;
|
||||
|
||||
timer_id_t
|
||||
wasm_create_timer(wasm_exec_env_t exec_env,
|
||||
int interval, bool is_period, bool auto_start);
|
||||
void
|
||||
wasm_timer_destroy(wasm_exec_env_t exec_env, timer_id_t timer_id);
|
||||
void
|
||||
wasm_timer_cancel(wasm_exec_env_t exec_env, timer_id_t timer_id);
|
||||
void
|
||||
wasm_timer_restart(wasm_exec_env_t exec_env,
|
||||
timer_id_t timer_id, int interval);
|
||||
uint32
|
||||
wasm_get_sys_tick_ms(wasm_exec_env_t exec_env);
|
||||
|
||||
/*
|
||||
* connection interfaces
|
||||
*/
|
||||
|
||||
uint32
|
||||
wasm_open_connection(wasm_exec_env_t exec_env,
|
||||
int32 name_offset, int32 args_offset, uint32 len);
|
||||
void
|
||||
wasm_close_connection(wasm_exec_env_t exec_env,
|
||||
uint32 handle);
|
||||
int
|
||||
wasm_send_on_connection(wasm_exec_env_t exec_env,
|
||||
uint32 handle, int32 data_offset, uint32 len);
|
||||
bool
|
||||
wasm_config_connection(wasm_exec_env_t exec_env,
|
||||
uint32 handle, int32 cfg_offset, uint32 len);
|
||||
|
||||
/**
|
||||
* gui interfaces
|
||||
*/
|
||||
|
||||
void
|
||||
wasm_obj_native_call(wasm_exec_env_t exec_env,
|
||||
int32 func_id, uint32 argv_offset, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_btn_native_call(wasm_exec_env_t exec_env,
|
||||
int32 func_id, uint32 argv_offset, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_label_native_call(wasm_exec_env_t exec_env,
|
||||
int32 func_id, uint32 argv_offset, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_cb_native_call(wasm_exec_env_t exec_env,
|
||||
int32 func_id, uint32 argv_offset, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_list_native_call(wasm_exec_env_t exec_env,
|
||||
int32 func_id, uint32 argv_offset, uint32 argc);
|
||||
|
||||
#endif /* end of _NATIVE_INTERFACE_H */
|
||||
|
||||
418
core/app-framework/app-native-shared/restful_utils.c
Normal file
418
core/app-framework/app-native-shared/restful_utils.c
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* 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;
|
||||
char * packet = (char*) wa_malloc(len);
|
||||
if (packet == NULL)
|
||||
return NULL;
|
||||
|
||||
// TODO: ensure little endian for words and dwords
|
||||
*packet = REQUES_PACKET_VER;
|
||||
*((uint8*) (packet + 1)) = request->action;
|
||||
*((uint16*) (packet + 2)) = htons(request->fmt);
|
||||
*((uint32*) (packet + 4)) = htonl(request->mid);
|
||||
*((uint32*) (packet + 8)) = htonl(request->sender);
|
||||
*((uint16*) (packet + 12)) = htons(url_len);
|
||||
*((uint32*) (packet + 14)) = htonl(request->payload_len);
|
||||
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)
|
||||
{
|
||||
if (*packet != REQUES_PACKET_VER) {
|
||||
printf("version fail\n");
|
||||
return NULL;
|
||||
}
|
||||
if (size < REQUEST_PACKET_FIX_PART_LEN) {
|
||||
printf("size error: %d\n", size);
|
||||
return NULL;
|
||||
}
|
||||
uint16 url_len = ntohs(*((uint16*) (packet + 12)));
|
||||
uint32 payload_len = ntohl(*((uint32*) (packet + 14)));
|
||||
|
||||
if (size != ( REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
|
||||
printf("size error: %d, expect: %d\n", size,
|
||||
REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len);
|
||||
return NULL;
|
||||
}
|
||||
if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
|
||||
printf("url not end with 0\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
request->action = *((uint8*) (packet + 1));
|
||||
request->fmt = ntohs(*((uint16*) (packet + 2)));
|
||||
request->mid = ntohl(*((uint32*) (packet + 4)));
|
||||
request->sender = ntohl(*((uint32*) (packet + 8)));
|
||||
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;
|
||||
char * packet = (char*) wa_malloc(len);
|
||||
if (packet == NULL)
|
||||
return NULL;
|
||||
|
||||
// TODO: ensure little endian for words and dwords
|
||||
*packet = REQUES_PACKET_VER;
|
||||
*((uint8*) (packet + 1)) = response->status;
|
||||
*((uint16*) (packet + 2)) = htons(response->fmt);
|
||||
*((uint32*) (packet + 4)) = htonl(response->mid);
|
||||
*((uint32*) (packet + 8)) = htonl(response->reciever);
|
||||
*((uint32*) (packet + 12)) = htonl(response->payload_len);
|
||||
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)
|
||||
{
|
||||
if (*packet != REQUES_PACKET_VER)
|
||||
return NULL;
|
||||
if (size < RESPONSE_PACKET_FIX_PART_LEN)
|
||||
return NULL;
|
||||
uint32 payload_len = ntohl(*((uint32*) (packet + 12)));
|
||||
if (size != ( RESPONSE_PACKET_FIX_PART_LEN + payload_len))
|
||||
return NULL;
|
||||
|
||||
response->status = *((uint8*) (packet + 1));
|
||||
response->fmt = ntohs(*((uint16*) (packet + 2)));
|
||||
response->mid = ntohl(*((uint32*) (packet + 4)));
|
||||
response->reciever = ntohl(*((uint32*) (packet + 8)));
|
||||
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;
|
||||
}
|
||||
|
||||
request_t * init_request(request_t * request, char *url, int action, int fmt,
|
||||
void *payload, int payload_len)
|
||||
{
|
||||
static unsigned int mid = 0;
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user