mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-08 07:55:10 +00:00
305 lines
7.9 KiB
C
305 lines
7.9 KiB
C
/*
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
*/
|
|
|
|
#include "host_tool_utils.h"
|
|
#include "bi-inc/shared_utils.h"
|
|
|
|
#include <time.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.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;
|
|
|
|
#ifndef bh_memcpy_s
|
|
int b_memcpy_s(void * s1, unsigned int s1max,
|
|
const void * s2, unsigned int n);
|
|
#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)
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
|
|
char* attr_container_get_attr_begin(const attr_container_t *attr_cont,
|
|
uint32_t *p_total_length,
|
|
uint16_t *p_attr_num);
|
|
|
|
cJSON *attr2json(const attr_container_t *attr_cont)
|
|
{
|
|
uint32_t total_length;
|
|
uint16_t attr_num, i, j, type;
|
|
const char *p, *tag, *key;
|
|
jvalue value;
|
|
cJSON *root;
|
|
|
|
if (!attr_cont)
|
|
return NULL;
|
|
|
|
root = cJSON_CreateObject();
|
|
if (!root)
|
|
return NULL;
|
|
|
|
/* TODO: how to convert the tag? */
|
|
tag = attr_container_get_tag(attr_cont);
|
|
if (!tag)
|
|
goto fail;
|
|
|
|
p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num);
|
|
if (!p)
|
|
goto fail;
|
|
|
|
for (i = 0; i < attr_num; i++) {
|
|
cJSON *obj;
|
|
|
|
key = p + 2;
|
|
/* Skip key len and key */
|
|
p += 2 + get_uint16(p);
|
|
type = *p++;
|
|
|
|
switch (type) {
|
|
case ATTR_TYPE_SHORT:
|
|
bh_memcpy_s(&value.s, sizeof(int16_t), p, sizeof(int16_t));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.s)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
/* another approach: cJSON_AddNumberToObject(root, key, value.s) */
|
|
p += 2;
|
|
break;
|
|
case ATTR_TYPE_INT:
|
|
bh_memcpy_s(&value.i, sizeof(int32_t), p, sizeof(int32_t));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.i)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += 4;
|
|
break;
|
|
case ATTR_TYPE_INT64:
|
|
bh_memcpy_s(&value.j, sizeof(uint64_t), p, sizeof(uint64_t));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.j)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += 8;
|
|
break;
|
|
case ATTR_TYPE_BYTE:
|
|
bh_memcpy_s(&value.b, 1, p, 1);
|
|
if (NULL == (obj = cJSON_CreateNumber(value.b)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p++;
|
|
break;
|
|
case ATTR_TYPE_UINT16:
|
|
bh_memcpy_s(&value.c, sizeof(uint16_t), p, sizeof(uint16_t));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.c)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += 2;
|
|
break;
|
|
case ATTR_TYPE_FLOAT:
|
|
bh_memcpy_s(&value.f, sizeof(float), p, sizeof(float));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.f)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += 4;
|
|
break;
|
|
case ATTR_TYPE_DOUBLE:
|
|
bh_memcpy_s(&value.d, sizeof(double), p, sizeof(double));
|
|
if (NULL == (obj = cJSON_CreateNumber(value.d)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += 8;
|
|
break;
|
|
case ATTR_TYPE_BOOLEAN:
|
|
bh_memcpy_s(&value.z, 1, p, 1);
|
|
if (NULL == (obj = cJSON_CreateBool(value.z)))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p++;
|
|
break;
|
|
case ATTR_TYPE_STRING:
|
|
if (NULL == (obj = cJSON_CreateString(p + sizeof(uint16_t))))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
p += sizeof(uint16_t) + get_uint16(p);
|
|
break;
|
|
case ATTR_TYPE_BYTEARRAY:
|
|
if (NULL == (obj = cJSON_CreateArray()))
|
|
goto fail;
|
|
cJSON_AddItemToObject(root, key, obj);
|
|
for (j = 0; j < get_uint32(p); j++) {
|
|
cJSON *item = cJSON_CreateNumber(*(p + sizeof(uint32_t) + j));
|
|
if (item == NULL)
|
|
goto fail;
|
|
cJSON_AddItemToArray(obj, item);
|
|
}
|
|
p += sizeof(uint32_t) + get_uint32(p);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return root;
|
|
|
|
fail: cJSON_Delete(root);
|
|
return NULL;
|
|
}
|
|
|
|
attr_container_t *json2attr(const cJSON *json_obj)
|
|
{
|
|
attr_container_t *attr_cont;
|
|
cJSON *item;
|
|
|
|
if (NULL == (attr_cont = attr_container_create("")))
|
|
return NULL;
|
|
|
|
if (!cJSON_IsObject(json_obj))
|
|
goto fail;
|
|
|
|
cJSON_ArrayForEach(item, json_obj)
|
|
{
|
|
|
|
if (cJSON_IsNumber(item)) {
|
|
attr_container_set_double(&attr_cont, item->string,
|
|
item->valuedouble);
|
|
} else if (cJSON_IsTrue(item)) {
|
|
attr_container_set_bool(&attr_cont, item->string, true);
|
|
} else if (cJSON_IsFalse(item)) {
|
|
attr_container_set_bool(&attr_cont, item->string, false);
|
|
} else if (cJSON_IsString(item)) {
|
|
attr_container_set_string(&attr_cont, item->string,
|
|
item->valuestring);
|
|
} else if (cJSON_IsArray(item)) {
|
|
int8_t *array;
|
|
int i = 0, len = sizeof(int8_t) * cJSON_GetArraySize(item);
|
|
cJSON *array_item;
|
|
|
|
if (0 == len || NULL == (array = (int8_t *) malloc(len)))
|
|
goto fail;
|
|
memset(array, 0, len);
|
|
|
|
cJSON_ArrayForEach(array_item, item)
|
|
{
|
|
/* must be number array */
|
|
if (!cJSON_IsNumber(array_item))
|
|
break;
|
|
/* TODO: if array_item->valuedouble > 127 or < -128 */
|
|
array[i++] = (int8_t) array_item->valuedouble;
|
|
}
|
|
if (i > 0)
|
|
attr_container_set_bytearray(&attr_cont, item->string, array,
|
|
i);
|
|
free(array);
|
|
}
|
|
}
|
|
|
|
return attr_cont;
|
|
|
|
fail: attr_container_destroy(attr_cont);
|
|
return NULL;
|
|
}
|
|
|
|
int g_mid = 0;
|
|
|
|
int gen_random_id()
|
|
{
|
|
static bool init = false;
|
|
int r;
|
|
|
|
if (!init) {
|
|
srand(time(NULL));
|
|
init = true;
|
|
}
|
|
|
|
r = rand();
|
|
g_mid = r;
|
|
|
|
return r;
|
|
}
|
|
|
|
char *
|
|
read_file_to_buffer(const char *filename, int *ret_size)
|
|
{
|
|
char *buffer;
|
|
int file;
|
|
int file_size, read_size;
|
|
struct stat stat_buf;
|
|
|
|
if (!filename || !ret_size) {
|
|
return NULL;
|
|
}
|
|
|
|
if ((file = open(filename, O_RDONLY, 0)) == -1) {
|
|
return NULL;
|
|
}
|
|
|
|
if (fstat(file, &stat_buf) != 0) {
|
|
close(file);
|
|
return NULL;
|
|
}
|
|
|
|
file_size = stat_buf.st_size;
|
|
|
|
if (!(buffer = malloc(file_size))) {
|
|
close(file);
|
|
return NULL;
|
|
}
|
|
|
|
read_size = read(file, buffer, file_size);
|
|
close(file);
|
|
|
|
if (read_size < file_size) {
|
|
free(buffer);
|
|
return NULL;
|
|
}
|
|
|
|
*ret_size = file_size;
|
|
return buffer;
|
|
}
|
|
|
|
int wirte_buffer_to_file(const char *filename, const char *buffer, int size)
|
|
{
|
|
int file, ret;
|
|
|
|
if ((file = open(filename, O_RDWR | O_CREAT | O_APPEND, 0644)) == -1)
|
|
return -1;
|
|
|
|
ret = write(file, buffer, size);
|
|
|
|
close(file);
|
|
|
|
return ret;
|
|
}
|