wasm-micro-runtime/test-tools/host-tool/src/host_tool_utils.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;
}