You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
9.8 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2021-2021. All rights reserved.
* Description: baseparam database operation function
* Author: huanglong
* Create: 2021-4-6
*/
#include <stdlib.h>
#include <string.h>
#include "securec.h"
#include "soc_module.h"
#include "soc_errno.h"
#include "db_ext.h"
/*
* the db struct:
* DB : | dbcheck | datalen | table 0 | ... ... | table n |
* TABLE: | name | datasize | key 0 | ... ...| key n |
* KEY: | name | valuelen | value |
*/
static td_char g_db_check[EXT_DB_CHECK_LEN] = {"###"};
td_s32 ext_db_create(ext_db *db)
{
td_s32 ret;
if (db == TD_NULL) {
soc_log_err("ERR: para is null\n");
return TD_FAILURE;
}
db->data = malloc(EXT_DB_MAX_SIZE);
if (db->data == TD_NULL) {
soc_log_err("ERR: malloc error\n");
return TD_FAILURE;
}
memset_s(db->data, EXT_DB_MAX_SIZE, 0x00, EXT_DB_MAX_SIZE);
ret = memcpy_s(db->data, EXT_DB_MAX_SIZE, (td_u8 *)g_db_check, EXT_DB_CHECK_LEN);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
free(db->data);
db->data = TD_NULL;
return ret;
}
db->data_len = EXT_DB_CHECK_LEN + sizeof(td_u32);
ret = memcpy_s((db->data + EXT_DB_CHECK_LEN), (EXT_DB_MAX_SIZE - EXT_DB_CHECK_LEN),
(td_u8 *)(&(db->data_len)), sizeof(td_u32));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
free(db->data);
db->data = TD_NULL;
return ret;
}
return TD_SUCCESS;
}
td_s32 ext_db_destroy(ext_db *db)
{
if (db == TD_NULL) {
soc_log_err("ERR: para is null\n");
return TD_FAILURE;
}
if (db->data_len > EXT_DB_MAX_SIZE) {
soc_log_err("ERR: data len too large\n");
return TD_FAILURE;
}
db->data_len = 0;
if (db->data != TD_NULL) {
free(db->data);
db->data = TD_NULL;
}
return TD_SUCCESS;
}
td_s32 ext_db_get_db_from_mem(td_u8 *db_mem, ext_db *db)
{
td_s32 ret;
td_char db_check[EXT_DB_CHECK_LEN] = {0};
if ((db_mem == TD_NULL) || (db == TD_NULL)) {
soc_log_err("ERR: para is null\n");
return TD_FAILURE;
}
ret = memcpy_s(db_check, sizeof(db_check), (td_char *)db_mem, EXT_DB_CHECK_LEN);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
if (strncmp(db_check, g_db_check, strlen(g_db_check)) != 0) {
soc_log_err("ERR: this is not a db\n");
return TD_FAILURE;
}
db->data_len = *(td_u32 *)(db_mem + EXT_DB_CHECK_LEN);
if (db->data_len > EXT_DB_MAX_SIZE) {
soc_log_err("ERR: db size is error\n");
return TD_FAILURE;
}
db->data = db_mem;
return TD_SUCCESS;
}
td_s32 ext_db_insert_table(ext_db *db, ext_db_table *table)
{
td_u32 need_len;
td_s32 ret;
if ((db == TD_NULL) || (table == TD_NULL)) {
soc_log_err("ERR: para is null\n");
return TD_FAILURE;
}
need_len = EXT_DB_MAX_NAME_LEN + sizeof(td_u32);
if (db->data_len + need_len > EXT_DB_MAX_SIZE) {
soc_log_err("ERR: db is full\n");
return TD_FAILURE;
}
table->db = db;
ret = memcpy_s((db->data + db->data_len), (EXT_DB_MAX_SIZE - db->data_len),
table->name, EXT_DB_MAX_NAME_LEN);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
db->data_len += EXT_DB_MAX_NAME_LEN;
table->data_size = 0;
ret = memcpy_s((db->data + db->data_len), (EXT_DB_MAX_SIZE - db->data_len),
(td_u8 *)(&(table->data_size)), sizeof(td_u32));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
db->data_len += sizeof(td_u32);
/* we need to update db datalen */
ret = memcpy_s(db->data + EXT_DB_CHECK_LEN, sizeof(td_u32),
(td_u8 *)(&(db->data_len)), sizeof(db->data_len));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
table->data = db->data + db->data_len;
return TD_SUCCESS;
}
td_s32 ext_db_delete_table(const ext_db *db, const td_char table_name[])
{
TD_UNUSED(db);
TD_UNUSED(table_name);
soc_log_err("ERR: delete table is not support\n");
return TD_FAILURE;
}
td_s32 ext_db_get_table_by_name(ext_db *db, td_char table_name[], ext_db_table *table)
{
ext_db_table table_tmp;
td_u8 *data = TD_NULL;
td_s32 ret;
if ((db == TD_NULL) || (table == TD_NULL) || (table_name == TD_NULL)) {
soc_log_err("ERR: para is null\n");
return TD_FAILURE;
}
data = db->data + EXT_DB_CHECK_LEN + sizeof(td_u32);
while ((td_u32)(data - db->data) < db->data_len) {
table_tmp.db = db;
ret = memset_s(table_tmp.name, sizeof(table_tmp.name), 0, sizeof(table_tmp.name));
if (ret != TD_SUCCESS) {
soc_log_err("ERR: memset_s failed !\n");
return ret;
}
ret = memcpy_s(table_tmp.name, sizeof(table_tmp.name), data, EXT_DB_MAX_NAME_LEN - 1);
if (ret != TD_SUCCESS) {
soc_log_err("ERR: memcpy_s failed !\n");
return ret;
}
data += EXT_DB_MAX_NAME_LEN;
if ((td_u32)(data - db->data + sizeof(td_u32)) > db->data_len) {
soc_log_err("ERR: pointer has been damaged! data isn't in db now!");
return TD_FAILURE;
}
table_tmp.data_size = *((td_u32 *)(data));
if ((td_u32)(data - db->data + sizeof(td_u32)) + table_tmp.data_size > db->data_len) {
soc_log_err("ERR: got bad data size!");
return TD_FAILURE;
}
data += sizeof(td_u32);
table_tmp.data = data;
/* find the table */
if (strncmp(table_tmp.name, table_name, strlen(table_name)) == 0) {
*table = table_tmp;
break;
} else {
data += table_tmp.data_size;
}
}
if ((td_u32)(data - db->data) >= db->data_len) {
soc_log_err("ERR: can not find table %s\n", table_name);
return TD_FAILURE;
}
return TD_SUCCESS;
}
td_s32 ext_db_insert_key(ext_db_table *table, ext_db_key *key)
{
td_u32 need_len;
td_s32 ret;
if ((table == TD_NULL) || (table->db == TD_NULL) || (key == TD_NULL) || (key->value == TD_NULL)) {
soc_log_err("ERR: para is null\n");
return SOC_ERR_PDM_PTR_NULL;
}
need_len = EXT_DB_MAX_NAME_LEN + sizeof(td_u32) + key->value_size;
if (table->db->data_len + need_len > EXT_DB_MAX_SIZE) {
soc_log_err("ERR: db is full\n");
return TD_FAILURE;
}
ret = memcpy_s((table->data + table->data_size), (EXT_DB_MAX_SIZE - table->db->data_len),
key->name, EXT_DB_MAX_NAME_LEN);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
table->data_size += EXT_DB_MAX_NAME_LEN;
ret = memcpy_s((table->data + table->data_size), (EXT_DB_MAX_SIZE - table->db->data_len - EXT_DB_MAX_NAME_LEN),
(td_u8 *)(&(key->value_size)), sizeof(td_u32));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
table->data_size += sizeof(td_u32);
ret = memcpy_s((table->data + table->data_size),
(EXT_DB_MAX_SIZE - table->db->data_len - EXT_DB_MAX_NAME_LEN - sizeof(td_u32)),
(td_u8 *)(key->value), key->value_size);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
table->data_size += key->value_size;
/* we need update table datasize */
ret = memcpy_s(table->data - sizeof(td_u32), sizeof(td_u32),
(td_u8 *)(&(table->data_size)), sizeof(table->data_size));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
/* we need update db datalen */
table->db->data_len += need_len;
ret = memcpy_s(table->db->data + EXT_DB_CHECK_LEN, sizeof(td_u32),
(td_u8 *)(&(table->db->data_len)), sizeof(table->db->data_len));
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
return TD_SUCCESS;
}
td_s32 ext_db_delete_key(const ext_db_table *table, const td_char key_name[])
{
TD_UNUSED(table);
TD_UNUSED(key_name);
soc_log_err("ERR: delete key is not support\n");
return TD_FAILURE;
}
td_s32 ext_db_get_key_by_name(const ext_db_table *table, td_char *key_name, td_u32 key_len, ext_db_key *key)
{
ext_db_key key_tmp;
td_u8 *data = TD_NULL;
td_s32 ret;
td_u32 str_len;
if ((table == TD_NULL) || (key == TD_NULL) || (key_name == TD_NULL) || (key_len == 0)) {
soc_log_err("ERR: para is null\n");
return SOC_ERR_PDM_PTR_NULL;
}
data = table->data;
if (data == TD_NULL) {
soc_log_err("data is null\n");
return SOC_ERR_PDM_PTR_NULL;
}
while ((td_u32)(data - table->data) < table->data_size) {
memset_s(key_tmp.name, sizeof(key_tmp.name), 0, sizeof(key_tmp.name));
ret = memcpy_s(key_tmp.name, sizeof(key_tmp.name) - 1, data, EXT_DB_MAX_NAME_LEN - 1);
if (ret != TD_SUCCESS) {
soc_log_err("memcpy_s failed !\n");
return ret;
}
data += EXT_DB_MAX_NAME_LEN;
key_tmp.value_size = *((td_u32 *)data);
data += sizeof(td_u32);
key_tmp.value = data;
str_len = strlen(key_tmp.name) > key_len ? strlen(key_tmp.name) : key_len;
/* find the key */
if (strncmp(key_tmp.name, key_name, str_len) == 0) {
*key = key_tmp;
break;
} else {
data += key_tmp.value_size;
}
}
if ((td_u32)(data - table->data) >= table->data_size) {
soc_log_info("ERR: can not find key %s\n", key_name);
return TD_FAILURE;
}
return TD_SUCCESS;
}