initial commit
This commit is contained in:
154
common/iobuffer/iobuffer.c
Executable file
154
common/iobuffer/iobuffer.c
Executable file
@@ -0,0 +1,154 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user