fusion/common/iobuffer/iobuffer.c

155 lines
3.7 KiB
C
Raw Normal View History

2025-08-05 07:53:44 +00:00
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "iobuffer.h"
#define ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
static int pow2gt (int x) {
--x;
x|=x>>1;
x|=x>>2;
x|=x>>4;
x|=x>>8;
x|=x>>16;
return x+1;
}
void iobuffer_init(iobuffer* p) {
p->iodata = NULL;
p->size = 0;
p->capacity = 0;
}
void iobuffer_deinit(iobuffer* p) {
free(p->iodata);
p->iodata = NULL;
p->size = 0;
p->capacity = 0;
}
int iobuffer_reserve(iobuffer* p, int cap) {
if (cap > p->capacity) {
// round up
//extra 1 byte for null-terminated char,
int alloc = pow2gt(cap+1);
printf(" allcate iobuffer %d=>%d\n", cap, alloc);
// at least 16 byte align for AES encrypt
alloc = ALIGN(alloc,16);
assert(alloc >= cap + 1);
assert(alloc >= p->size + 1);
char* new_data = (char*)realloc(p->iodata, alloc);
if (!new_data) {
printf("can't allcate iobuffer %d=>%d\n", p->capacity, alloc);
return ENOMEM;
}
p->iodata = new_data;
p->capacity = alloc - 1;
p->iodata[p->size] = '\0';
}
return 0;
}
int iobuffer_freesize(iobuffer* p){
assert(p->capacity >= p->size);
return p->capacity - p->size;
}
int iobuffer_appendData(iobuffer* p, const void* data, int count) {
if (count <= 0)
return EINVAL;
int ret = iobuffer_reserve(p, p->size + count);
if (ret == 0) {
memcpy(p->iodata + p->size, data, count);
p->size += count;
p->iodata[p->size] = '\0';
}
return ret;
}
int iobuffer_append_string(iobuffer* p, const void* str)
{
return iobuffer_appendData(p, str, strlen(str));
}
int iobuffer_prependData(iobuffer* p, const void* data, int count) {
int ret = iobuffer_reserve(p, p->size + count);
if (ret == 0) {
memmove(p->iodata + count, p->iodata, p->size);
memcpy(p->iodata, data, count);
p->size += count;
p->iodata[p->size] = '\0';
}
return ret;
}
void iobuffer_erase(iobuffer* p, int from, int to) {
int n = to - from;
if (n > 0) {
if ( n != p->size ){
memmove(p->iodata + from, p->iodata + to, p->size - to);
}
p->size -= n;
p->iodata[p->size] = '\0';
}
}
void iobuffer_eraseall(iobuffer* p)
{
iobuffer_erase(p, 0, p->size);
}
static int ioprintf(iobuffer* this, const char *format, va_list ap)
{
int n;
int buflen = this->capacity - this->size;
if ( buflen < 128) {
if ( 0 != iobuffer_reserve(this, this->size + 1024))
return ENOMEM;
buflen = this->capacity - this->size;
}
while(1) {
char * buf = this->iodata + this->size;
n = vsnprintf(buf, buflen, format, ap);
if ( n <= 0) {
printf("vsnprintf err %d/%d,format=%s", n, errno, format);
return -2;
}
if ( n > buflen) {
if ( 0 != iobuffer_reserve(this, this->size + n + 1024))
return ENOMEM;
buflen = this->capacity - this->size;
}
else {
this->size += n;
return 0;
}
}
}
int iobuffer_printf(iobuffer* p, const char *format, ...){
int result;
va_list ap;
va_start(ap, format);
result = ioprintf(p, format, ap);
va_end(ap);
return result;
}
void iobuffer_read(iobuffer* this, void* to, int size)
{
memcpy(to, this->iodata, size);
iobuffer_erase(this, 0, size);
}