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; void *m_userData;
char *m_buffer; char *m_buffer;
char *m_bufferPtr; char *m_bufferPtr;
size_t m_bufferSize;
const char *m_bufferEnd; const char *m_bufferEnd;
OP_OrderHandler m_orderHandler; OP_OrderHandler m_orderHandler;
enum OP_Error m_errorCode; enum OP_Error m_errorCode;
@ -35,6 +36,7 @@ static void buffer_free(OP_Parser parser)
{ {
/* TODO: recycle buffers, reduce mallocs. */ /* TODO: recycle buffers, reduce mallocs. */
free(parser->m_buffer); free(parser->m_buffer);
parser->m_bufferSize = 0;
parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL; 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) 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) { 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) { if (!parser->m_buffer) {
return OP_ERROR_NO_MEMORY; 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; parser->m_bufferEnd = parser->m_buffer + len;
} }
else { else {
size_t total = len;
char * buffer; char * buffer;
total += (parser->m_bufferEnd - parser->m_bufferPtr);
/* TODO: recycle buffers, reduce mallocs. */ /* TODO: recycle buffers, reduce mallocs. */
buffer = malloc(total + 1); if (parser->m_bufferSize < total) {
memcpy(buffer, parser->m_bufferPtr, total - len); parser->m_bufferSize = total;
memcpy(buffer + total - len, s, len); buffer = malloc(parser->m_bufferSize);
buffer[total] = '\0'; if (!buffer) {
free(parser->m_buffer);
parser->m_buffer = buffer;
if (!parser->m_buffer) {
return OP_ERROR_NO_MEMORY; 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_bufferPtr = parser->m_buffer;
parser->m_bufferEnd = parser->m_buffer + total; parser->m_bufferEnd = parser->m_buffer + total - 1;
} }
return OP_ERROR_NONE; 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; enum OP_Error code;
if (parser->m_bufferPtr >= parser->m_bufferEnd) {
buffer_free(parser);
}
code = buffer_append(parser, s, len); code = buffer_append(parser, s, len);
if (code != OP_ERROR_NONE) { if (code != OP_ERROR_NONE) {
parser->m_errorCode = code; parser->m_errorCode = code;