120 lines
1.8 KiB
C
120 lines
1.8 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <ucore/ucore_buffer.h>
|
|
|
|
GBuf*
|
|
uc_new_gbuf(size_t initsz)
|
|
{
|
|
GBuf *p;
|
|
p = malloc(sizeof *p);
|
|
if (p == NULL)
|
|
return NULL;
|
|
|
|
p->used = 0;
|
|
p->len = initsz;
|
|
p->buf = NULL;
|
|
p->ref_cnt = 1;
|
|
|
|
if (initsz != 0 && (p->buf = malloc(initsz)) == NULL) {
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
void
|
|
uc_gbuf_ref(GBuf *buf)
|
|
{
|
|
buf->ref_cnt++;
|
|
}
|
|
|
|
void
|
|
uc_gbuf_unref(GBuf *buf)
|
|
{
|
|
buf->ref_cnt--;
|
|
|
|
if (buf->ref_cnt == 0) {
|
|
free(buf->buf);
|
|
free(buf);
|
|
}
|
|
}
|
|
|
|
int
|
|
uc_gbuf_append(GBuf *buf,const void *data,size_t len)
|
|
{
|
|
unsigned char *gbuf;
|
|
|
|
if (buf->len - buf->used < len)
|
|
if (uc_gbuf_grow(buf, len + len/2))
|
|
return -1;
|
|
|
|
gbuf = buf->buf;
|
|
memcpy(gbuf + buf->used, data, len);
|
|
buf->used += len;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int uc_gbuf_printf(GBuf *buf, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_list apc;
|
|
int rc = 0;
|
|
int remaining;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
//increment buffer if snprintf indicates the results were truncated
|
|
do {
|
|
|
|
va_copy(apc, ap);
|
|
char *gbuf;
|
|
|
|
remaining = uc_gbuf_remaining(buf);
|
|
if (rc >= remaining) {
|
|
if (uc_gbuf_grow(buf, buf->len + (rc - remaining) + 1)) {
|
|
rc = -1;
|
|
va_end(apc);
|
|
break;
|
|
}
|
|
remaining = uc_gbuf_remaining(buf);
|
|
}
|
|
|
|
gbuf = buf->buf;
|
|
|
|
rc = vsnprintf(gbuf + buf->used, remaining, fmt, apc);
|
|
va_end(apc);
|
|
|
|
} while (rc >= remaining);
|
|
|
|
if(rc > 0) {
|
|
buf->used += rc;
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
uc_gbuf_grow(GBuf *buf, size_t addlen)
|
|
{
|
|
void *tmp;
|
|
size_t newsz;
|
|
|
|
newsz = buf->len + addlen;
|
|
|
|
tmp = realloc(buf->buf,newsz);
|
|
if (tmp == NULL)
|
|
return -1;
|
|
|
|
buf->buf = tmp;
|
|
buf->len = newsz;
|
|
|
|
return 0;
|
|
}
|
|
|