Files

349 lines
7.9 KiB
C

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <common.h>
#include <malloc.h>
#include <amlogic/aml_model.h>
#include "ini_parser.h"
#include "model_log.h"
#include "model.h"
#define LOG_TAG "ini_handle"
#define LOG_NDEBUG 0
int handle_ini_mem_check(void *inip)
{
struct ini_s *ini_buf;
char *identifier;
unsigned char *p;
unsigned int crc32;
unsigned char *local_ini_mem = (unsigned char *)inip;
//check identifier
p = (unsigned char *)inip;
identifier = (char *)(p + sizeof(struct ini_s));
if (strcmp(identifier, INI_IDENTIFIER_STR)) {
//not ini mem
return -1;
}
ini_buf = (struct ini_s *)inip;
if (ini_buf->mem_start_pos != sizeof(struct ini_s)) {
//mem start position not correct
return -1;
}
crc32 = cal_CRC32(0, local_ini_mem +ini_buf->mem_start_pos, ini_buf->mem_cur_pos);
if (ini_buf->crc32 != crc32) {
//not sure ini mem
return -1;
}
return 0;
}
//maybe other file type mem
void handle_ini_parser_uninit(void *inip)
{
struct ini_s *ini_buf;
int total_size;
int ret;
if (!inip)
return;
ret = handle_ini_mem_check(inip);
if (ret) {
//not sure mem_size, only free without clear
free(inip);
return;
}
ini_buf = (struct ini_s *)inip;
ini_handler_mem_free(ini_buf);
total_size = ini_buf->total_size;
memset(inip, 0, total_size);
free(inip);
}
unsigned char *handle_ini_parser_init(int mem_size)
{
unsigned char *local_ini_mem;
struct ini_s *ini_buf;
char *identifier;
int total_size;
if (mem_size)
total_size = mem_size;
else
total_size = INI_PARSER_MEM_SIZE_DFT;
local_ini_mem = malloc(total_size);
if (!local_ini_mem) {
ALOGE("%s: error\n", __func__);
return NULL;
}
memset(local_ini_mem, 0, total_size);
ini_buf = (struct ini_s *)local_ini_mem;
ini_buf->total_size = total_size;
ini_buf->mem_size = total_size - sizeof(struct ini_s);
ini_buf->mem_start_pos = sizeof(struct ini_s);
//init identifier:
identifier = local_ini_mem + ini_buf->mem_start_pos;
strlcpy(identifier, INI_IDENTIFIER_STR, INI_MEM_DATA_OFFSET);
//init parser data offset
ini_buf->mem_cur_pos = INI_MEM_DATA_OFFSET;
return local_ini_mem;
}
void *handle_ini_file_parse(const char *filename, int mem_size)
{
unsigned char *local_ini_mem = NULL;
struct ini_s *ini_buf;
unsigned char *tmp_buf = NULL;
int file_size = 0;
int ret = 0;
ALOGD("%s: %s, mem_size:%d\n", __func__, filename, mem_size);
tmp_buf = model_read_file_to_buffer(filename, &file_size);
if (!tmp_buf) {
ret = -1;
goto handle_ini_file_parse_end;
}
local_ini_mem = handle_ini_parser_init(mem_size);
if (!local_ini_mem)
goto handle_ini_file_parse_end;
ini_buf = (struct ini_s *)local_ini_mem;
ret = ini_parse_mem(ini_buf, (const char *)tmp_buf);
if (ret)
handle_ini_parser_uninit(local_ini_mem);
else
ini_buf->crc32 = cal_CRC32(0, local_ini_mem + ini_buf->mem_start_pos, ini_buf->mem_cur_pos);
handle_ini_file_parse_end:
memset((void *)tmp_buf, 0, file_size);
free(tmp_buf);
if (ret)
return NULL;
return (void *)local_ini_mem;
}
int handle_ini_parser_mem_get_size(void *inip)
{
struct ini_s *ini_buf;
int size, ret;
if (!inip) {
ALOGE("%s: error\n", __func__);
return -1;
}
ret = handle_ini_mem_check(inip);
if (ret)
return -1;
ini_buf = (struct ini_s *)inip;
size = ini_buf->mem_start_pos + ini_buf->mem_cur_pos; //real mem size
return size;
}
void *handle_ini_parser_dupmem(void *inip, int *buf_size)
{
void *local_ini_mem;
struct ini_s *ini_buf;
unsigned char *p;
int size;
if (!inip) {
ALOGE("%s: error\n", __func__);
return NULL;
}
ini_buf = (struct ini_s *)inip;
size = ini_buf->mem_start_pos + ini_buf->mem_cur_pos; //real mem size
local_ini_mem = (void *)malloc(size);
if (!local_ini_mem) {
ALOGE("%s: error\n", __func__);
return NULL;
}
memcpy(local_ini_mem, inip, size);
//update dest_buf value
ini_buf = (struct ini_s *)local_ini_mem;
ini_buf->total_size = size;
ini_buf->mem_size = ini_buf->mem_cur_pos;
p = (unsigned char *)local_ini_mem;
ini_buf->crc32 = cal_CRC32(0, p + ini_buf->mem_start_pos, ini_buf->mem_cur_pos);
*buf_size = size;
return local_ini_mem;
}
void *handle_ini_get_section(void *inip, const char *section)
{
struct ini_s *ini_buf;
struct ini_section_s *psec;
if (!inip || !section)
return NULL;
ini_buf = (struct ini_s *)inip;
psec = ini_get_section(ini_buf, section);
return (void *)psec;
}
const char *handle_ini_get_str(void *inip, void *psec, const char *key, const char *def_val)
{
struct ini_s *ini_buf;
struct ini_section_s *ini_section;
const char *value;
if (!inip || !psec || !key)
return def_val;
ini_buf = (struct ini_s *)inip;
ini_section = (struct ini_section_s *)psec;
value = ini_get_string(ini_buf, ini_section, key, def_val);
return value;
}
unsigned int handle_ini_get_val(void *inip, void *psec, const char *key, unsigned int def_val)
{
struct ini_s *ini_buf;
struct ini_section_s *ini_section;
const char *str;
if (!inip || !psec || !key)
return def_val;
ini_buf = (struct ini_s *)inip;
ini_section = (struct ini_section_s *)psec;
str = ini_get_string(ini_buf, ini_section, key, NULL);
if (!str)
return def_val;
return (unsigned int)(simple_strtoul(str, NULL, 0));
}
int handle_ini_key_exist(void *inip, void *psec, const char *key)
{
struct ini_s *ini_buf;
struct ini_section_s *ini_section;
const char *str;
if (!inip || !psec || !key)
return 0;
ini_buf = (struct ini_s *)inip;
ini_section = (struct ini_section_s *)psec;
str = ini_get_string(ini_buf, ini_section, key, NULL);
if (!str)
return 0;
return 1;
}
int handle_ini_set_exist_single_key(void *inip, void *psec, const char *key, const char *str)
{
struct ini_s *ini_buf;
struct ini_section_s *ini_section;
struct ini_line_s *ini_line;
unsigned char *local_ini_mem = (unsigned char *)inip;
int ret;
if (!inip || !psec || !key)
return -1;
ini_buf = (struct ini_s *)inip;
ini_section = (struct ini_section_s *)psec;
ini_line = ini_get_key_line_at_sec(ini_buf, ini_section, key);
ret = ini_set_line_exist_key_val(ini_buf, ini_section, ini_line, str,
INI_SET_KEY_VAL_MODE_OVERWRITE);
if (!ret)
ini_buf->crc32 = cal_CRC32(0,
local_ini_mem + ini_buf->mem_start_pos, ini_buf->mem_cur_pos);
return ret;
}
int handle_ini_set_exist_keys(void *inip, void *psec,
const char *new_line, const char *new_value, int line_cnt)
{
struct ini_s *ini_buf;
struct ini_section_s *ini_section;
unsigned char *local_ini_mem = (unsigned char *)inip;
int ret;
if (!inip || !psec || !new_line || !new_value)
return -1;
ini_buf = (struct ini_s *)inip;
ini_section = (struct ini_section_s *)psec;
ret = ini_set_line_exist_keys(ini_buf, ini_section, new_line, new_value, line_cnt);
if (!ret)
ini_buf->crc32 = cal_CRC32(0,
local_ini_mem + ini_buf->mem_start_pos, ini_buf->mem_cur_pos);
return ret;
}
/* case 1: cur_psec & new_psec same name, overwrite
* case 2: cur_psec & new_psec different name, append after cur_psec
* case 3: cur_psec is NULL, append after last section
*/
int handle_ini_write_new_section(void *cur_inip, void *cur_psec, void *new_inip, void *new_psec)
{
struct ini_s *cur_ini_buf, *new_ini_buf;
struct ini_section_s *ini_sec_cur, *ini_sec_new;
unsigned char *local_ini_mem = (unsigned char *)cur_inip;
int ret;
if (!cur_inip || !new_inip || !new_psec)
return -1;
cur_ini_buf = (struct ini_s *)cur_inip;
new_ini_buf = (struct ini_s *)new_inip;
ini_sec_cur = (struct ini_section_s *)cur_psec;
ini_sec_new = (struct ini_section_s *)new_psec;
ret = ini_write_new_section(cur_ini_buf, ini_sec_cur, new_ini_buf, ini_sec_new);
if (!ret) {
cur_ini_buf->crc32 = cal_CRC32(0, local_ini_mem + cur_ini_buf->mem_start_pos,
cur_ini_buf->mem_cur_pos);
}
return ret;
}
void handle_ini_list_key_value(void *inip)
{
struct ini_s *ini_buf;
if (!inip)
return;
ini_buf = (struct ini_s *)inip;
ini_list_key_value(ini_buf);
}
void handle_ini_list_section(void *inip)
{
struct ini_s *ini_buf;
if (!inip)
return;
ini_buf = (struct ini_s *)inip;
ini_list_section(ini_buf);
}