diff options
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 93 |
1 files changed, 19 insertions, 74 deletions
diff --git a/src/buffer.c b/src/buffer.c index 07725b9c..f8d47d92 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -32,7 +32,8 @@ void git_buf_init(git_buf *buf, size_t initial_size) git_buf_grow(buf, initial_size); } -int git_buf_try_grow(git_buf *buf, size_t target_size, bool mark_oom) +int git_buf_try_grow( + git_buf *buf, size_t target_size, bool mark_oom, bool preserve_external) { char *new_ptr; size_t new_size; @@ -40,6 +41,9 @@ int git_buf_try_grow(git_buf *buf, size_t target_size, bool mark_oom) if (buf->ptr == git_buf__oom) return -1; + if (!target_size) + target_size = buf->size; + if (target_size <= buf->asize) return 0; @@ -67,6 +71,9 @@ int git_buf_try_grow(git_buf *buf, size_t target_size, bool mark_oom) return -1; } + if (preserve_external && !buf->asize && buf->ptr != NULL && buf->size > 0) + memcpy(new_ptr, buf->ptr, min(buf->size, new_size)); + buf->asize = new_size; buf->ptr = new_ptr; @@ -78,11 +85,16 @@ int git_buf_try_grow(git_buf *buf, size_t target_size, bool mark_oom) return 0; } +int git_buf_grow(git_buf *buffer, size_t target_size) +{ + return git_buf_try_grow(buffer, target_size, true, true); +} + void git_buf_free(git_buf *buf) { if (!buf) return; - if (buf->ptr != git_buf__initbuf && buf->ptr != git_buf__oom) + if (buf->asize > 0 && buf->ptr != NULL && buf->ptr != git_buf__oom) git__free(buf->ptr); git_buf_init(buf, 0); @@ -91,11 +103,15 @@ void git_buf_free(git_buf *buf) void git_buf_clear(git_buf *buf) { buf->size = 0; + + if (!buf->ptr) + buf->ptr = git_buf__initbuf; + if (buf->asize > 0) buf->ptr[0] = '\0'; } -int git_buf_set(git_buf *buf, const char *data, size_t len) +int git_buf_set(git_buf *buf, const void *data, size_t len) { if (len == 0 || data == NULL) { git_buf_clear(buf); @@ -485,74 +501,3 @@ int git_buf_splice( buf->ptr[buf->size] = '\0'; return 0; } - -/* - * Public buffers API - */ - -void git_buffer_free(git_buffer *buffer) -{ - if (!buffer) - return; - - if (buffer->ptr != NULL && buffer->available > 0) - git__free(buffer->ptr); - - git__memzero(buffer, sizeof(*buffer)); -} - -static int git_buffer__resize( - git_buffer *buffer, size_t want_size, int preserve_data) -{ - int non_allocated_buffer = 0; - char *new_ptr; - - assert(buffer); - - /* check if buffer->ptr points to memory owned elsewhere */ - non_allocated_buffer = (buffer->ptr != NULL && buffer->available == 0); - - if (non_allocated_buffer && !want_size) - want_size = buffer->size; - - if (buffer->available >= want_size) - return 0; - - if (non_allocated_buffer) { - new_ptr = NULL; - if (want_size < buffer->size) - want_size = buffer->size; - } else { - new_ptr = buffer->ptr; - } - - want_size = (want_size + 7) & ~7; /* round up to multiple of 8 */ - - new_ptr = git__realloc(new_ptr, want_size); - GITERR_CHECK_ALLOC(new_ptr); - - if (non_allocated_buffer && preserve_data) - memcpy(new_ptr, buffer->ptr, buffer->size); - - buffer->ptr = new_ptr; - buffer->available = want_size; - - return 0; -} - -int git_buffer_resize(git_buffer *buffer, size_t want_size) -{ - return git_buffer__resize(buffer, want_size, true); -} - -int git_buffer_copy( - git_buffer *buffer, const void *data, size_t datalen) -{ - if (git_buffer__resize(buffer, datalen + 1, false) < 0) - return -1; - memcpy(buffer->ptr, data, datalen); - buffer->ptr[datalen] = '\0'; - buffer->size = datalen; - return 0; -} - |