diff options
author | Lars Wirzenius <liw@liw.fi> | 2010-10-25 12:06:17 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2010-10-25 12:06:17 +0100 |
commit | 7b7f94de3462845c36b2831719b6448fe173f2f7 (patch) | |
tree | eeda0eccdb2450722179692e063bce4494a9c780 | |
parent | fc6e2a8f7018a01ce84e566c252a545a55d5f70c (diff) | |
download | dynstr-7b7f94de3462845c36b2831719b6448fe173f2f7.tar.gz |
Avoid doing a large number of small allocs in readline_helper.
-rw-r--r-- | dynstr.c | 33 |
1 files changed, 26 insertions, 7 deletions
@@ -376,9 +376,11 @@ static Dynstr *readline_helper(int (*callback)(FILE *, int), FILE *f, int fd) Dynstr *temp1; Dynstr *temp2; int c; - unsigned char byte; + unsigned char buf[1024]; + size_t buflen; line = dynstr_new_empty(); + buflen = 0; for (;;) { temp1 = NULL; @@ -390,19 +392,36 @@ static Dynstr *readline_helper(int (*callback)(FILE *, int), FILE *f, int fd) else if (c == -2) break; - byte = c; - temp1 = dynstr_new_from_constant_memory(&byte, 1); + buf[buflen++] = c; + if (buflen == sizeof(buf)) { + temp1 = dynstr_new_from_memory(buf, buflen); + if (temp1 == NULL) + goto error; + temp2 = dynstr_cat(line, temp1, NULL); + if (temp2 == NULL) + goto error; + dynstr_free(temp1); + dynstr_free(line); + line = temp2; + buflen = 0; + } + + if (c == '\n') + break; + } + + if (buflen > 0) { + temp1 = dynstr_new_from_memory(buf, buflen); if (temp1 == NULL) goto error; temp2 = dynstr_cat(line, temp1, NULL); + if (temp2 == NULL) + goto error; dynstr_free(temp1); dynstr_free(line); line = temp2; - - if (c == '\n') - break; } - + return line; error: |