reuse the internal buffer when we don't have to malloc.

This commit is contained in:
Enno Rehling 2018-10-03 20:29:45 +02:00
parent fbce8f326a
commit 730b94fa4a
1 changed files with 39 additions and 16 deletions

View File

@ -13,6 +13,7 @@ struct OrderParserStruct {
void *m_userData;
char *m_buffer;
char *m_bufferPtr;
size_t m_bufferSize;
const char *m_bufferEnd;
OP_OrderHandler m_orderHandler;
enum OP_Error m_errorCode;
@ -35,6 +36,7 @@ static void buffer_free(OP_Parser parser)
{
/* TODO: recycle buffers, reduce mallocs. */
free(parser->m_buffer);
parser->m_bufferSize = 0;
parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL;
}
@ -58,8 +60,28 @@ void OP_ParserFree(OP_Parser parser) {
static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
{
size_t total = len + 1;
size_t remain = parser->m_bufferEnd - parser->m_bufferPtr;
total += remain;
if (remain > 0) {
/* there is remaining data in the buffer, should we move it to the front? */
if (total <= parser->m_bufferSize) {
/* reuse existing buffer */
memmove(parser->m_buffer, parser->m_bufferPtr, remain);
memcpy(parser->m_buffer + remain, s, len);
parser->m_buffer[total - 1] = '\0';
parser->m_bufferPtr = parser->m_buffer;
parser->m_bufferEnd = parser->m_bufferPtr + total - 1;
return OP_ERROR_NONE;
}
}
else if (parser->m_bufferPtr >= parser->m_bufferEnd) {
buffer_free(parser);
}
if (parser->m_buffer == NULL) {
parser->m_buffer = malloc(len + 1);
parser->m_bufferSize = len + 1;
parser->m_buffer = malloc(parser->m_bufferSize);
if (!parser->m_buffer) {
return OP_ERROR_NO_MEMORY;
}
@ -69,21 +91,26 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
parser->m_bufferEnd = parser->m_buffer + len;
}
else {
size_t total = len;
char * buffer;
total += (parser->m_bufferEnd - parser->m_bufferPtr);
/* TODO: recycle buffers, reduce mallocs. */
buffer = malloc(total + 1);
memcpy(buffer, parser->m_bufferPtr, total - len);
memcpy(buffer + total - len, s, len);
buffer[total] = '\0';
free(parser->m_buffer);
parser->m_buffer = buffer;
if (!parser->m_buffer) {
if (parser->m_bufferSize < total) {
parser->m_bufferSize = total;
buffer = malloc(parser->m_bufferSize);
if (!buffer) {
return OP_ERROR_NO_MEMORY;
}
memcpy(buffer, parser->m_bufferPtr, total - len - 1);
memcpy(buffer + total - len - 1, s, len);
free(parser->m_buffer);
parser->m_buffer = buffer;
}
else {
memcpy(parser->m_buffer, parser->m_bufferPtr, total - len);
memcpy(parser->m_buffer + total - len, s, len);
}
parser->m_buffer[total - 1] = '\0';
parser->m_bufferPtr = parser->m_buffer;
parser->m_bufferEnd = parser->m_buffer + total;
parser->m_bufferEnd = parser->m_buffer + total - 1;
}
return OP_ERROR_NONE;
}
@ -250,10 +277,6 @@ enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal)
{
enum OP_Error code;
if (parser->m_bufferPtr >= parser->m_bufferEnd) {
buffer_free(parser);
}
code = buffer_append(parser, s, len);
if (code != OP_ERROR_NONE) {
parser->m_errorCode = code;