Hash :
3286c408
Author :
Date :
2011-10-28T14:51:13
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
/*
* Copyright (C) 2009-2011 the libgit2 contributors
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "buffer.h"
#include "posix.h"
#include <stdarg.h>
#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)
{
git__free(buf->ptr);
}
void git_buf_clear(git_buf *buf)
{
buf->size = 0;
}
void git_buf_consume(git_buf *buf, const char *end)
{
size_t consumed = end - buf->ptr;
memmove(buf->ptr, end, buf->size - consumed);
buf->size -= consumed;
}