在我的开源纯C代码中,我使用这个简单的结构来读取和解析字符串缓冲区中的数据:
typedef struct lts_LoadState
{
const unsigned char * pos;
size_t unread;
} lts_LoadState;
Run Code Online (Sandbox Code Playgroud)
使用这个简单的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);
Run Code Online (Sandbox Code Playgroud)
注意:ltsLS_unread可以在return (ltsLS_good(ls)) ? SIZE_MAX : 0不破坏当前实现的情况下替换.
此代码用于从字符串缓冲区以自定义格式加载某些数据.(这可能是一个更好的例证.)
现在我需要不是从字符串缓冲区加载数据,而是从FILE指针加载数据.
我不想复制粘贴实现,而是希望重用现有代码.(当然,我可以重构/改编它.)
这是C++中的教科书,但是如何在普通的C中做到这一点而不会产生运行时开销?
这是一个使用lts_LoadStateAPI 的示例函数,不能进行复制粘贴(当然,可以更改,以支持字符串缓冲区和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;
}
Run Code Online (Sandbox Code Playgroud)