/* * 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 #include #include #include #include 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; }