Merge branch 'dev'

pull/4/head
yuqing 2015-08-25 15:07:32 +08:00
commit 757ae81e35
2 changed files with 246 additions and 43 deletions

View File

@ -22,11 +22,70 @@
#define _LINE_BUFFER_SIZE 512
#define _INIT_ALLOC_ITEM_COUNT 32
static AnnotationMap *g_annotataionMap = NULL;
static int remallocSection(IniSection *pSection, IniItem **pItem);
static int iniDoLoadFromFile(const char *szFilename, \
IniContext *pContext);
static int iniDoLoadItemsFromBuffer(char *content, \
IniContext *pContext);
int iniSetAnnotationCallBack(AnnotationMap *map, int count)
{
int bytes;
AnnotationMap *p;
if (count <= 0)
{
logWarning("file: "__FILE__", line: %d, " \
"iniSetAnnotationCallBack fail count(%d) is incorrectly.", \
__LINE__, count);
return EINVAL;
}
bytes = sizeof(AnnotationMap) * (count + 1);
g_annotataionMap = (AnnotationMap *) malloc(bytes);
if (g_annotataionMap == NULL)
{
logError("file: "__FILE__", line: %d, " \
"malloc (%d) fail, errno: %d, error info: %s", \
__LINE__, bytes, errno, STRERROR(errno));
return ENOMEM;
}
memcpy(g_annotataionMap, map, sizeof(AnnotationMap) * count);
p = g_annotataionMap + count;
p->func_name = NULL;
p->func_init = NULL;
p->func_destroy = NULL;
p->func_get = NULL;
return 0;
}
void iniDestroyAnnotationCallBack()
{
AnnotationMap *pAnnoMap;
pAnnoMap = g_annotataionMap;
if (pAnnoMap == NULL)
{
return;
}
while (pAnnoMap->func_name)
{
if (pAnnoMap->func_destroy)
{
pAnnoMap->func_destroy();
}
pAnnoMap++;
}
g_annotataionMap = NULL;
}
static int iniCompareByItemName(const void *p1, const void *p2)
{
return strcmp(((IniItem *)p1)->name, ((IniItem *)p2)->name);
@ -241,19 +300,29 @@ int iniLoadFromBuffer(char *content, IniContext *pContext)
static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
{
AnnotationMap *pAnnoMap;
IniSection *pSection;
IniItem *pItem;
char *pLine;
char *pLastEnd;
char *pEqualChar;
char *pItemName;
char *pAnnoItemLine;
char *pIncludeFilename;
char *pItemValues[100];
char pFuncName[FAST_INI_ITEM_NAME_LEN + 1];
char full_filename[MAX_PATH_SIZE];
int i;
int nLineLen;
int nNameLen;
int nItemCnt;
int nValueLen;
int result;
int isAnnotation;
result = 0;
pAnnoItemLine = NULL;
isAnnotation = 0;
pLastEnd = content - 1;
pSection = pContext->current_section;
pItem = pSection->items + pSection->count;
@ -267,6 +336,14 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
*pLastEnd = '\0';
}
if (isAnnotation && pLine != pAnnoItemLine)
{
logWarning("file: "__FILE__", line: %d, " \
"the @function and annotation item " \
"must be next to each other", __LINE__);
isAnnotation = 0;
}
if (*pLine == '#' && \
strncasecmp(pLine+1, "include", 7) == 0 && \
(*(pLine+8) == ' ' || *(pLine+8) == '\t'))
@ -328,6 +405,22 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
free(pIncludeFilename);
continue;
}
else if ((*pLine == '#' && \
strncasecmp(pLine+1, "@function", 9) == 0 && \
(*(pLine+10) == ' ' || *(pLine+10) == '\t')))
{
nNameLen = strlen(pLine + 11);
if (nNameLen > FAST_INI_ITEM_NAME_LEN)
{
nNameLen = FAST_INI_ITEM_NAME_LEN;
}
memcpy(pFuncName, pLine + 11, nNameLen);
pFuncName[nNameLen] = '\0';
trim(pFuncName);
isAnnotation = 1;
pAnnoItemLine = pLastEnd + 1;
continue;
}
trim(pLine);
if (*pLine == '#' || *pLine == '\0')
@ -415,38 +508,12 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
}
if (pSection->count >= pSection->alloc_count)
{
int bytes;
IniItem *pNew;
if (pSection->alloc_count == 0)
{
result = remallocSection(pSection, &pItem);
if (result)
{
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
break;
}
else
{
pSection->alloc_count *= 2;
}
bytes = sizeof(IniItem) * pSection->alloc_count;
pNew = (IniItem *)malloc(bytes);
if (pNew == NULL)
{
logError("file: "__FILE__", line: %d, " \
"malloc %d bytes fail", __LINE__, bytes);
result = errno != 0 ? errno : ENOMEM;
break;
}
if (pSection->count > 0)
{
memcpy(pNew, pSection->items,
sizeof(IniItem) * pSection->count);
free(pSection->items);
}
pSection->items = pNew;
pItem = pSection->items + pSection->count;
memset(pItem, 0, sizeof(IniItem) * \
(pSection->alloc_count - pSection->count));
}
memcpy(pItem->name, pLine, nNameLen);
@ -455,13 +522,139 @@ static int iniDoLoadItemsFromBuffer(char *content, IniContext *pContext)
trim(pItem->name);
trim(pItem->value);
if (isAnnotation)
{
isAnnotation = 0;
if (g_annotataionMap == NULL)
{
logWarning("file: "__FILE__", line: %d, " \
"not set annotataionMap and (%s) will use " \
"the item value (%s)", __LINE__, pItem->name,
pItem->value);
pSection->count++;
pItem++;
continue;
}
nItemCnt = -1;
pAnnoMap = g_annotataionMap;
while (pAnnoMap->func_name)
{
if (strcasecmp(pFuncName, pAnnoMap->func_name) == 0)
{
if (pAnnoMap->func_init)
{
pAnnoMap->func_init();
}
if (pAnnoMap->func_get)
{
nItemCnt = pAnnoMap->func_get(pItem->value, pItemValues, 100);
}
break;
}
pAnnoMap++;
}
if (nItemCnt == -1)
{
logWarning("file: "__FILE__", line: %d, " \
"not found corresponding annotation func (%s)" \
" and (%s) will use the item value (%s).", __LINE__,
pItem->name, pFuncName, pItem->value);
pSection->count++;
pItem++;
continue;
}
else if (nItemCnt == 0)
{
logWarning("file: "__FILE__", line: %d, " \
"annotation func(%s) execute failed and"
"(%s) will use the item value (%s)", __LINE__,
pItem->name, pFuncName, pItem->value);
pSection->count++;
pItem++;
continue;
}
pItemName = pItem->name;
nNameLen = strlen(pItemName) + 1;
for (i = 0; i < nItemCnt; i++)
{
nValueLen = strlen(pItemValues[i]);
if (nValueLen > FAST_INI_ITEM_VALUE_LEN)
{
nValueLen = FAST_INI_ITEM_VALUE_LEN;
}
memcpy(pItem->name, pItemName, nNameLen);
memcpy(pItem->value, pItemValues[i], nValueLen);
pItem->value[nValueLen] = '\0';
pSection->count++;
pItem++;
if (pSection->count >= pSection->alloc_count)
{
result = remallocSection(pSection, &pItem);
if (result)
{
break;
}
}
}
continue;
}
pSection->count++;
pItem++;
}
if (!result && isAnnotation)
{
logWarning("file: "__FILE__", line: %d, " \
"the @function and annotation item " \
"must be next to each other", __LINE__);
}
return result;
}
static int remallocSection(IniSection *pSection, IniItem **pItem)
{
int bytes, result;
IniItem *pNew;
if (pSection->alloc_count == 0)
{
pSection->alloc_count = _INIT_ALLOC_ITEM_COUNT;
}
else
{
pSection->alloc_count *= 2;
}
bytes = sizeof(IniItem) * pSection->alloc_count;
pNew = (IniItem *)malloc(bytes);
if (pNew == NULL)
{
logError("file: "__FILE__", line: %d, " \
"malloc %d bytes fail", __LINE__, bytes);
result = errno != 0 ? errno : ENOMEM;
return result;
}
if (pSection->count > 0)
{
memcpy(pNew, pSection->items,
sizeof(IniItem) * pSection->count);
free(pSection->items);
}
pSection->items = pNew;
*pItem = pSection->items + pSection->count;
memset(*pItem, 0, sizeof(IniItem) * \
(pSection->alloc_count - pSection->count));
return 0;
}
static int iniFreeHashData(const int index, const HashData *data, void *args)
{
IniSection *pSection;

View File

@ -19,6 +19,13 @@
#define FAST_INI_ITEM_NAME_LEN 64
#define FAST_INI_ITEM_VALUE_LEN 256
typedef struct {
char *func_name;
int (*func_init) ();
void (*func_destroy) ();
int (*func_get) (char *key, char **pOutValue, int max_values);
} AnnotationMap;
typedef struct
{
char name[FAST_INI_ITEM_NAME_LEN + 1];
@ -44,6 +51,9 @@ typedef struct
extern "C" {
#endif
int iniSetAnnotationCallBack(AnnotationMap *map, int count);
void iniDestroyAnnotationCallBack();
/** load ini items from file
* parameters:
* szFilename: the filename, can be an URL