在my open-source plain C code我使用這個簡單的結構來讀出並從字符串緩衝區中解析數據:應用鴨打字在純C
typedef struct lts_LoadState
{
const unsigned char * pos;
size_t unread;
} lts_LoadState;
該緩衝區由this simple API訪問:
/* Initialize buffer */
void ltsLS_init(lts_LoadState * ls,const unsigned char * data, size_t len);
/* Do we have something to read? (Actually a macro.) */
BOOL ltsLS_good(ls);
/* How much do we have to read? (Actually a macro.) */
size_t ltsLS_unread(ls);
/* Eat given number of characters, return pointer to beginning of eaten data */
const unsigned char * ltsLS_eat(lts_LoadState * ls, size_t len);
注:ltsLS_unread
可以替換爲return (ltsLS_good(ls)) ? SIZE_MAX : 0
而不會破壞當前的實現。
此代碼用於load some data in a custom format from a string buffer。 (This可以是更好的說明。)
現在我需要負載數據未從字符串緩衝區,但是從FILE
指針。
我討厭複製粘貼實現,而想重複使用現有的代碼。 (當然,我可以重構/修改它。)
這是C++中的教科書,但是如何在純C中做到這一點,而不會產生運行時開銷?
這裏是使用lts_LoadState
API的示例功能,這是不被複制粘貼(但可被改變,當然,以支持字符串緩衝區和FILE *
):
static int ltsLS_readline(
lts_LoadState * ls,
const unsigned char ** dest,
size_t * len
)
{
const unsigned char * origin = ls->pos;
unsigned char last = 0;
size_t read = 0;
while (ltsLS_good(ls))
{
if (ltsLS_unread(ls) > 0)
{
unsigned char b = *ls->pos; /* OK, this should be ltsLS_eat_char macro. */
++ls->pos;
--ls->unread;
if (b == '\n')
{
*dest = origin;
*len = (last == '\r') ? read - 1 : read;
return LUATEXTS_ESUCCESS;
}
last = b;
++read;
}
else
{
ls->unread = 0;
ls->pos = NULL;
}
}
return LUATEXTS_ECLIPPED;
}
我正在考慮用某些腳本生成C代碼,因此「複製粘貼」會自動完成。這可能是最簡單的方法。但是我正在尋找沒有代碼生成的「正確」解決方案(當然,預處理器是OK的)。 – 2012-04-03 21:51:50
我結束了使用內存映射文件 - 這樣我可以重複使用完全相同的'lts_LoadState'及其訪問函數。 – 2012-04-04 20:25:40