forked from github/server
reuse the internal buffer when we don't have to malloc.
This commit is contained in:
parent
fbce8f326a
commit
730b94fa4a
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue