line_buffer creates a couple of static buffers and expose an API for using them. The idea is to maintain a fixed static memory pool to avoid constant allocation and de-allocation of memory. Taken directly from David Michael Barr's svn-dump-fast-export repository. Signed-off-by: Ramkumar Ramachandra <artagnon@xxxxxxxxx> --- vcs-svn/line_buffer.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ vcs-svn/line_buffer.h | 14 ++++++ 2 files changed, 129 insertions(+), 0 deletions(-) create mode 100644 vcs-svn/line_buffer.c create mode 100644 vcs-svn/line_buffer.h diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c new file mode 100644 index 0000000..6b47d38 --- /dev/null +++ b/vcs-svn/line_buffer.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "line_buffer.h" + +#define LINE_BUFFER_LEN 10000 +#define COPY_BUFFER_LEN 4096 + +static char line_buffer[LINE_BUFFER_LEN]; +static char byte_buffer[COPY_BUFFER_LEN]; +static uint32_t line_buffer_len = 0; +static uint32_t line_len = 0; + +char *buffer_read_line(void) +{ + char *end; + uint32_t n_read; + + if (line_len) { + memmove(line_buffer, &line_buffer[line_len], + line_buffer_len - line_len); + line_buffer_len -= line_len; + line_len = 0; + } + + end = memchr(line_buffer, '\n', line_buffer_len); + while (line_buffer_len < LINE_BUFFER_LEN - 1 && + !feof(stdin) && NULL == end) { + n_read = + fread(&line_buffer[line_buffer_len], 1, + LINE_BUFFER_LEN - 1 - line_buffer_len, + stdin); + end = memchr(&line_buffer[line_buffer_len], '\n', n_read); + line_buffer_len += n_read; + } + + if (ferror(stdin)) + return NULL; + + if (end != NULL) { + line_len = end - line_buffer; + line_buffer[line_len++] = '\0'; + } else { + line_len = line_buffer_len; + line_buffer[line_buffer_len] = '\0'; + } + + if (line_len == 0) + return NULL; + + return line_buffer; +} + +char *buffer_read_string(uint32_t len) +{ + char *s = malloc(len + 1); + uint32_t offset = 0; + if (line_buffer_len > line_len) { + offset = line_buffer_len - line_len; + if (offset > len) + offset = len; + memcpy(s, &line_buffer[line_len], offset); + line_len += offset; + } + while (offset < len && !feof(stdin)) { + offset += fread(&s[offset], 1, len - offset, stdin); + } + s[offset] = '\0'; + return s; +} + +void buffer_copy_bytes(uint32_t len) +{ + uint32_t in, out; + if (line_buffer_len > line_len) { + in = line_buffer_len - line_len; + if (in > len) + in = len; + out = 0; + while (out < in && !ferror(stdout)) { + out += + fwrite(&line_buffer[line_len + out], 1, in - out, stdout); + } + len -= in; + line_len += in; + } + while (len > 0 && !feof(stdin)) { + in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN; + in = fread(byte_buffer, 1, in, stdin); + len -= in; + out = 0; + while (out < in && !ferror(stdout)) { + out += fwrite(&byte_buffer[out], 1, in - out, stdout); + } + } +} + +void buffer_skip_bytes(uint32_t len) +{ + uint32_t in; + if (line_buffer_len > line_len) { + in = line_buffer_len - line_len; + if (in > len) + in = len; + line_len += in; + len -= in; + } + while (len > 0 && !feof(stdin)) { + in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN; + in = fread(byte_buffer, 1, in, stdin); + len -= in; + } +} + diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h new file mode 100644 index 0000000..e546f4d --- /dev/null +++ b/vcs-svn/line_buffer.h @@ -0,0 +1,14 @@ +#ifndef LINE_BUFFER_H_ +#define LINE_BUFFER_H_ + +#include <stdint.h> + +char *buffer_read_line(void); + +char *buffer_read_string(uint32_t len); + +void buffer_copy_bytes(uint32_t len); + +void buffer_skip_bytes(uint32_t len); + +#endif -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html