From 730b94fa4afd0d0384569b9d3800b08a41f35dfe Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 3 Oct 2018 20:29:45 +0200 Subject: [PATCH] reuse the internal buffer when we don't have to malloc. --- src/util/order_parser.c | 55 +++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 55b03accd..21268f163 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -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) { - return OP_ERROR_NO_MEMORY; + 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;