blob: de74b65a59d27788feee7d5d545ee6de07447eed [file] [log] [blame]
/*
* Author: Shoufu Zhao <shoufu.zhao@amlogic.com>
*/
#include "ini_config.h"
#define LOG_TAG "ini_handler"
#define LOG_NDEBUG 0
#include "ini_log.h"
#include "ini_core.h"
#include "ini_handler.h"
#include "ini_platform.h"
static void trim(char *str, char ch);
static void trim_all(char *str);
static INI_SECTION* getSection(const char* section, INI_HANDLER_DATA *pHandlerData);
static INI_LINE* getKeyLineAtSec(INI_SECTION* pSec, const char* key);
static int setKeyValue(void* user, const char* section, const char* name, const char* value, int set_mode);
static int handler(void* user, const char* section, const char* name, const char* value);
static INI_LINE* newLine(const char* name, const char* value);
static INI_SECTION* newSection(const char* section, INI_LINE* pLINE);
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
static void alloc_mem(const char *fun_name, const char *var_name, void *ptr);
static void free_mem(const char *fun_name, const char *var_name, void *ptr);
static void printAllocMemND(const char *fun_name);
static void printFreeMemND(const char *fun_name);
static void clearMemND(void);
#endif
int ini_file_parse(const char* filename, INI_HANDLER_DATA *pHandlerData) {
int tmp_ret = -1, rd_cnt = 0, file_size = 0;
unsigned char *tmp_buf = NULL;
if (!iniIsFileExist(filename)) {
ALOGE("%s, file \"%s\" is not exist!\n", __FUNCTION__, filename);
return -1;
}
file_size = iniGetFileSize(filename);
if (file_size <= 0) {
ALOGE("%s, file \"%s\" size error!\n", __FUNCTION__, filename);
return -1;
}
tmp_buf = (unsigned char *) malloc(file_size * 2);
if (tmp_buf != NULL) {
strncpy(pHandlerData->mpFileName, filename, CC_MAX_INI_FILE_NAME_LEN - 1);
rd_cnt = iniReadFileToBuffer(filename, 0, file_size, tmp_buf);
if (rd_cnt > 0) {
tmp_ret = ini_mem_parse(tmp_buf, pHandlerData);
}
free(tmp_buf);
tmp_buf = NULL;
}
return tmp_ret;
}
int ini_mem_parse(unsigned char* file_buf, INI_HANDLER_DATA *pHandlerData) {
//ALOGD("%s, entering...\n", __FUNCTION__);
return ini_parse_mem((char *)file_buf, handler, (void *)pHandlerData);
}
int ini_set_save_file_name(const char* filename, INI_HANDLER_DATA *pHandlerData) {
//ALOGD("%s, entering...\n", __FUNCTION__);
strncpy(pHandlerData->mpFileName, filename, CC_MAX_INI_FILE_NAME_LEN - 1);
return 0;
}
void ini_free_mem(INI_HANDLER_DATA *pHandlerData) {
//ALOGD("%s, entering...\n", __FUNCTION__);
INI_SECTION* pNextSec = NULL;
INI_SECTION* pSec = NULL;
for (pSec = pHandlerData->mpFirstSection; pSec != NULL;) {
pNextSec = pSec->pNext;
INI_LINE* pNextLine = NULL;
INI_LINE* pLine = NULL;
for (pLine = pSec->pLine; pLine != NULL;) {
pNextLine = pLine->pNext;
if (pLine != NULL) {
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
free_mem(__FUNCTION__, "pLine", pLine);
#endif
free(pLine);
pLine = NULL;
}
pLine = pNextLine;
}
if (pSec != NULL) {
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
free_mem(__FUNCTION__, "pSec", pSec);
#endif
free(pSec);
pSec = NULL;
}
pSec = pNextSec;
}
pHandlerData->mpFirstSection = NULL;
pHandlerData->mpCurSection = NULL;
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
printAllocMemND(__FUNCTION__);
printFreeMemND(__FUNCTION__);
clearMemND();
#endif
}
static void trim(char *str, char ch) {
char* pStr;
pStr = str;
while (*pStr != '\0') {
if (*pStr == ch) {
char* pTmp = pStr;
while (*pTmp != '\0') {
*pTmp = *(pTmp + 1);
pTmp++;
}
} else {
pStr++;
}
}
}
static void trim_all(char *str) {
char* pStr = NULL;
pStr = strchr(str, '\n');
if (pStr != NULL) {
*pStr = 0;
}
int Len = strlen(str);
if (Len > 0) {
if (str[Len - 1] == '\r') {
str[Len - 1] = '\0';
}
}
pStr = strchr(str, '#');
if (pStr != NULL) {
*pStr = 0;
}
pStr = strchr(str, ';');
if (pStr != NULL) {
*pStr = 0;
}
trim(str, ' ');
trim(str, '{');
trim(str, '\\');
trim(str, '}');
trim(str, '\"');
return;
}
void ini_print_all(INI_HANDLER_DATA *pHandlerData) {
INI_SECTION* pSec = NULL;
for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
ALOGD("[%s]\n", pSec->Name);
INI_LINE* pLine = NULL;
for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
ALOGD("%s = %s\n", pLine->Name, pLine->Value);
}
ALOGD("\n\n\n");
}
}
static INI_SECTION* getSection(const char* section, INI_HANDLER_DATA *pHandlerData) {
INI_SECTION* pSec = NULL;
for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
if (strncmp(pSec->Name, section, strlen(section)) == 0) {
return pSec;
}
}
return NULL;
}
static INI_LINE* getKeyLineAtSec(INI_SECTION* pSec, const char* key) {
INI_LINE* pLine = NULL;
for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
if (strncmp(pLine->Name, key, strlen(key)) == 0) {
return pLine;
}
}
return NULL;
}
const char* ini_get_string(const char* section, const char* key,
const char* def_value, INI_HANDLER_DATA *pHandlerData) {
INI_SECTION* pSec = getSection(section, pHandlerData);
if (pSec == NULL) {
//ALOGD("%s, section %s is NULL\n", __FUNCTION__, section);
return def_value;
}
INI_LINE* pLine = getKeyLineAtSec(pSec, key);
if (pLine == NULL) {
//ALOGD("%s, key \"%s\" is NULL\n", __FUNCTION__, key);
return def_value;
}
return pLine->Value;
}
int ini_set_string(const char *section, const char *key, const char *value, INI_HANDLER_DATA *pHandlerData) {
setKeyValue(pHandlerData, section, key, value, 1);
return 0;
}
int ini_save_to_file(const char *filename, INI_HANDLER_DATA *pHandlerData) {
#if (defined CC_COMPILE_IN_PC || defined CC_COMPILE_IN_ANDROID)
const char *fname = NULL;
FILE *fp = NULL;
if (filename == NULL) {
if (strlen(pHandlerData->mpFileName) == 0) {
ALOGE("%s, save file name is NULL!!!\n", __FUNCTION__);
return -1;
} else {
fname = pHandlerData->mpFileName;
}
} else {
fname = filename;
}
if ((fp = fopen (fname, "wb")) == NULL) {
ALOGE("%s, Open file \"%s\" ERROR (%s)!!!\n", __FUNCTION__, fname, strerror(errno));
return -1;
}
INI_SECTION* pSec = NULL;
for (pSec = pHandlerData->mpFirstSection; pSec != NULL; pSec = pSec->pNext) {
fprintf(fp, "[%s]\r\n", pSec->Name);
INI_LINE* pLine = NULL;
for (pLine = pSec->pLine; pLine != NULL; pLine = pLine->pNext) {
fprintf(fp, "%s = %s\r\n", pLine->Name, pLine->Value);
}
}
fflush(fp);
fsync(fileno(fp));
fclose(fp);
fp = NULL;
return 0;
#elif (defined CC_COMPILE_IN_UBOOT)
return 0;
#endif
}
static INI_LINE* newLine(const char* name, const char* value) {
INI_LINE* pLine = NULL;
pLine = (INI_LINE*) malloc(sizeof(INI_LINE));
if (pLine != NULL) {
pLine->pNext = NULL;
strcpy(pLine->Name, name);
strcpy(pLine->Value, value);
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
alloc_mem(__FUNCTION__, "pLine", pLine);
#endif
}
return pLine;
}
static INI_SECTION* newSection(const char* section, INI_LINE* pLine) {
INI_SECTION* pSec = NULL;
pSec = (INI_SECTION*) malloc(sizeof(INI_SECTION));
if (pSec != NULL) {
pSec->pLine = pLine;
pSec->pNext = NULL;
strcpy(pSec->Name, section);
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
alloc_mem(__FUNCTION__, "pSec", pSec);
#endif
}
return pSec;
}
static int setKeyValue(void* user, const char* section, const char* key, const char* value, int set_mode) {
INI_LINE* pLine = NULL;
INI_SECTION *pSec = NULL;
INI_HANDLER_DATA *pHandlerData = (INI_HANDLER_DATA *) user;
if (section == NULL || key == NULL || value == NULL) {
return 1;
}
trim_all((char *) value);
if (value[0] == '\0') {
return 1;
}
if (strlen(key) > CC_MAX_INI_LINE_NAME_LEN) {
ALOGE("key name is too long, limit %d.\n", CC_MAX_INI_LINE_NAME_LEN);
return 1;
}
if (strlen(value) > CC_MAX_INI_FILE_LINE_LEN) {
ALOGE("key name is too long, limit %d.\n", CC_MAX_INI_FILE_LINE_LEN);
return 1;
}
if (pHandlerData->mpFirstSection == NULL) {
pLine = newLine(key, value);
pSec = newSection(section, pLine);
pHandlerData->mpFirstSection = pSec;
pHandlerData->mpCurSection = pSec;
pSec->pCurLine = pLine;
} else {
pSec = getSection(section, pHandlerData);
if (pSec == NULL) {
pLine = newLine(key, value);
pSec = newSection(section, pLine);
pHandlerData->mpCurSection->pNext = pSec;
pHandlerData->mpCurSection = pSec;
pSec->pCurLine = pLine;
pSec->pCurLine = pLine;
} else {
pLine = getKeyLineAtSec(pSec, key);
if (pLine == NULL) {
pLine = newLine(key, value);
pSec->pCurLine->pNext = pLine;
pSec->pCurLine = pLine;
} else {
if (set_mode == 1) {
strcpy(pLine->Value, value);
} else {
strcat(pLine->Value, value);
}
}
}
}
return 0;
}
static int handler(void* user, const char* section, const char* name,
const char* value) {
//ALOGD("%s, section = %s, name = %s, value = %s\n", __FUNCTION__, section, name, value);
setKeyValue(user, section, name, value, 0);
return 1;
}
#if CC_MEMORY_ALLOC_FREE_TRACE == 1
#define CC_MEM_RECORD_CNT (1024)
typedef struct tag_memnd {
char fun_name[50];
char var_name[50];
void *ptr;
} memnd;
static memnd gMemAllocItems[CC_MEM_RECORD_CNT];
static int gMemAllocInd = 0;
static memnd gMemFreeItems[CC_MEM_RECORD_CNT];
static int gMemFreeInd = 0;
static void alloc_mem(const char *fun_name, const char *var_name, void *ptr) {
strcpy(gMemAllocItems[gMemAllocInd].fun_name, fun_name);
strcpy(gMemAllocItems[gMemAllocInd].var_name, var_name);
gMemAllocItems[gMemAllocInd].ptr = ptr;
gMemAllocInd += 1;
}
static void free_mem(const char *fun_name, const char *var_name, void *ptr) {
strcpy(gMemFreeItems[gMemFreeInd].fun_name, fun_name);
strcpy(gMemFreeItems[gMemFreeInd].var_name, var_name);
gMemFreeItems[gMemFreeInd].ptr = ptr;
gMemFreeInd += 1;
}
static void printMemND(const char *fun_name, memnd *tmp_nd, int tmp_cnt) {
#if CC_MEMORY_ALLOC_FREE_TRACE_PRINT_ALL == 1
int i = 0;
ALOGD("fun_name = %s, total_cnt = %d\n", fun_name, tmp_cnt);
for (i = 0; i < tmp_cnt; i++) {
ALOGD("fun_name = %s, var_name = %s, ptr = %p\n", tmp_nd[i].fun_name, tmp_nd[i].var_name, tmp_nd[i].ptr);
}
#endif
}
static void printFreeMemND(const char *fun_name) {
printMemND(__FUNCTION__, gMemFreeItems, gMemFreeInd);
}
static void printAllocMemND(const char *fun_name) {
printMemND(__FUNCTION__, gMemAllocItems, gMemAllocInd);
}
static void clearMemND(void) {
gMemAllocInd = 0;
gMemFreeInd = 0;
memset((void *)gMemAllocItems, 0, sizeof(memnd) * CC_MEM_RECORD_CNT);
memset((void *)gMemFreeItems, 0, sizeof(memnd) * CC_MEM_RECORD_CNT);
}
#endif