2019-05-07 02:18:18 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
2019-11-11 23:45:21 +00:00
|
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-05-07 02:18:18 +00:00
|
|
|
*/
|
|
|
|
|
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
2020-01-21 05:26:14 +00:00
|
|
|
#include "bi-inc/attr_container.h"
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2020-03-10 11:54:44 +00:00
|
|
|
#ifndef bh_memcpy_s
|
|
|
|
int b_memcpy_s(void * s1, unsigned int s1max,
|
|
|
|
const void * s2, unsigned int n);
|
2019-05-07 02:18:18 +00:00
|
|
|
#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)
|
2020-03-10 11:54:44 +00:00
|
|
|
#endif
|
2019-05-07 02:18:18 +00:00
|
|
|
|
|
|
|
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));
|
2019-05-17 09:15:25 +00:00
|
|
|
attr_container_printf(", type: int64, value: 0x%llx\n", (long long unsigned int)(value.j));
|
2019-05-07 02:18:18 +00:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|