#include "buffer.h" #include "posix.h" #include #define ENSURE_SIZE(b, d) \ if ((ssize_t)(d) >= buf->asize && git_buf_grow(b, (d)) < GIT_SUCCESS)\ return; int git_buf_grow(git_buf *buf, size_t target_size) { char *new_ptr; if (buf->asize < 0) return GIT_ENOMEM; if (buf->asize == 0) buf->asize = target_size; /* grow the buffer size by 1.5, until it's big enough * to fit our target size */ while (buf->asize < (int)target_size) buf->asize = (buf->asize << 1) - (buf->asize >> 1); new_ptr = git__realloc(buf->ptr, buf->asize); if (!new_ptr) { buf->asize = -1; return GIT_ENOMEM; } buf->ptr = new_ptr; return GIT_SUCCESS; } int git_buf_oom(const git_buf *buf) { return (buf->asize < 0); } void git_buf_putc(git_buf *buf, char c) { ENSURE_SIZE(buf, buf->size + 1); buf->ptr[buf->size++] = c; } void git_buf_put(git_buf *buf, const char *data, size_t len) { ENSURE_SIZE(buf, buf->size + len); memcpy(buf->ptr + buf->size, data, len); buf->size += len; } void git_buf_puts(git_buf *buf, const char *string) { git_buf_put(buf, string, strlen(string)); } void git_buf_printf(git_buf *buf, const char *format, ...) { int len; va_list arglist; ENSURE_SIZE(buf, buf->size + 1); while (1) { va_start(arglist, format); len = p_vsnprintf(buf->ptr + buf->size, buf->asize - buf->size, format, arglist); va_end(arglist); if (len < 0) { buf->asize = -1; return; } if (len + 1 <= buf->asize - buf->size) { buf->size += len; return; } ENSURE_SIZE(buf, buf->size + len + 1); } } const char *git_buf_cstr(git_buf *buf) { if (buf->size + 1 >= buf->asize && git_buf_grow(buf, buf->size + 1) < GIT_SUCCESS) return NULL; buf->ptr[buf->size] = '\0'; return buf->ptr; } void git_buf_free(git_buf *buf) { free(buf->ptr); }