Added possibility to use user defined memory ops:

Now u can create a special ndbuf with your custom memory operations,
 this is useful to keep ndbuf in a special mapped areas for a:
  - keep it secure (example lock pages to avoid your info going to swap)
  - using your own custom optimized allocator for your own block sizes
 Function: ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *, const size_t);
  Args:
   1. Pointer to yout ops:
    struct ndbuf_memops {
     void *(*alloc)(size_t);
     uint32_t (*zero)(void *, size_t);
     void (*free)(void *ptr);
    };
   2. Size of chunk to grow buffer. if <= default value will be set.
master
Alexander Vdolainen 6 years ago
parent 0a9ff172a5
commit baa1574746

@ -1,3 +1,9 @@
0.0.2 (15-nov-2018)
* Added possibility to use user defined memory ops with:
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *, const size_t);
* Fixed bug with pkgconfig %VERSION% value
0.0.1 (24-nov-2017)
* initial version with all functions done
* tired from reuse this code and ... now it's lib

@ -29,14 +29,25 @@
#define NDBUF_BURN (1 << 1) /* burn buffer data before free */
#define NDBUF_NREA (1 << 2) /* non reallocatable buffer */
#define NDBUF_UCMO (1 << 3) /* user defined memops functions */
struct ndbuf_memops {
void *(*alloc)(size_t);
uint32_t (*zero)(void *, size_t);
void (*free)(void *ptr);
};
typedef struct __rawdatabuffer_type {
char *raw;
union {
void (*freebuf)(char *);
const struct ndbuf_memops *mop;
};
uint32_t rlength; /* raw buffer allocated length */
uint32_t ulength; /* length of used allocated space */
uint32_t curr; /* cursor for read/write operations */
int flags;
void (*freebuf)(char *);
size_t blk_size;
uint32_t flags;
} ndbuf_t;
/* variadic macro workaround */
@ -67,12 +78,15 @@ typedef struct __rawdatabuffer_type {
/* allocate raw buffer with defaults preallocation */
ndbuf_t *ndbuf_new(void);
/* will do the same as ndbuf_new but will allocate given length */
/* will do the same as ndbuf_new but will pre-allocate with the given length */
ndbuf_t *ndbuf_new_palloc(uint32_t);
/* create ndbuf from raw buffer */
ndbuf_t *ndbuf_new_frombuf(char *buf, size_t buf_len, void (*freebuf)(char *));
/* create a new buffer with user defined memops */
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *, const size_t);
/* free all allocated space and buffer itself */
void ndbuf_free(ndbuf_t *);

@ -104,16 +104,51 @@ ndbuf_t *ndbuf_new_palloc(uint32_t alen)
return b;
}
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *o, const size_t blk_len)
{
ndbuf_t *b = NULL;
if(!o) return NULL;
else { /* avoid nil calls */
if(!o->alloc || !o->free) return NULL;
}
if(!(b = malloc(sizeof(ndbuf_t)))) return NULL;
else memset(b, 0, sizeof(ndbuf_t));
if(blk_len <= 0) b->blk_size = DEFAULT_PREALLOC_SIZE;
if(!(b->raw = o->alloc(b->blk_size))) {
free(b);
return NULL;
} else {
b->rlength = b->blk_size;
b->ulength = b->curr = 0;
b->mop = o;
b->flags |= NDBUF_UCMO;
}
return b;
}
/* free all allocated space and buffer itself */
void ndbuf_free(ndbuf_t *b)
{
const struct ndbuf_memops *o = NULL;
if(!b) return;
if((b->flags & NDBUF_BURN) && b->raw)
memset(b->raw, 0, b->rlength);
if(b->flags & NDBUF_UCMO) o = b->mop;
if((b->flags & NDBUF_NREA) && b->freebuf) b->freebuf(b->raw);
else if(b->raw) free(b->raw);
if(o) {
if((b->flags & NDBUF_BURN) && o->zero) o->zero((void *)b->raw, b->rlength);
o->free(b->raw);
} else {
if((b->flags & NDBUF_BURN) && b->raw)
memset(b->raw, 0, b->rlength);
if((b->flags & NDBUF_NREA) && b->freebuf) b->freebuf(b->raw);
else if(b->raw) free(b->raw);
}
if(b->flags & NDBUF_BURN) memset(b, 0, sizeof(ndbuf_t));
free(b);
@ -210,23 +245,37 @@ static int __rdb_grow(ndbuf_t *b, uint32_t len)
{
uint32_t rlen;
char *ne = NULL;
const struct ndbuf_memops *o = NULL;
size_t bs = b->blk_size;
if(!len) return -1;
if(b->rlength + len > NDBUF_MAXLENGTH) return -1;
rlen = len +
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
if(b->flags & NDBUF_UCMO) o = b->mop;
rlen = len + (len%bs != 0 ? (bs - len%bs) : 0);
if(b->rlength + rlen > NDBUF_MAXLENGTH) rlen = len;
rlen += b->rlength;
if(!(ne = malloc(rlen))) return -1;
if(o) ne = (char *)o->alloc(rlen);
else ne = malloc(rlen);
if(b->flags & NDBUF_BURN) memset(ne, 0, rlen);
if(!ne) return -1;
if(b->flags & NDBUF_BURN) {
if(o) o->zero((void *)ne, rlen);
else memset(ne, 0, rlen);
}
memcpy(ne, b->raw, b->ulength);
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
if(o) {
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
o->free((void *)b->raw);
} else {
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
}
b->raw = ne;
b->rlength = rlen;
@ -306,7 +355,9 @@ uint32_t ndbuf_write_raw(ndbuf_t *b, void *wi, uint32_t len)
uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *wi, uint32_t len)
{
char *ne;
const struct ndbuf_memops *o = NULL;
uint32_t rlen;
size_t bs = b->blk_size;
if(!b || !b->raw) return 0;
if(!wi || !len) return 0;
@ -314,19 +365,33 @@ uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *wi, uint32_t len)
/* allocate a new one and copy it right */
if(b->rlength + len > NDBUF_MAXLENGTH) return -1;
rlen = len +
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
rlen = len + (len%bs != 0 ? (bs - len%bs) : 0);
if(b->rlength + rlen > NDBUF_MAXLENGTH) rlen = len;
rlen += b->rlength;
if(!(ne = malloc(rlen))) return -1;
if(b->flags & NDBUF_BURN) memset(ne, 0, rlen);
if(b->flags & NDBUF_UCMO) o = b->mop;
if(o) ne = (char *)o->alloc(rlen);
else ne = malloc(rlen);
if(!ne) return -1;
if(b->flags & NDBUF_BURN) {
if(o) o->zero((void *)ne, rlen);
else memset(ne, 0, rlen);
}
memcpy((void *)ne + len, b->raw, b->ulength);
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
if(o) {
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
o->free((void *)b->raw);
} else {
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
}
b->raw = ne;
b->rlength = rlen;
} else {
@ -705,6 +770,8 @@ void ndbuf_setflags(ndbuf_t *b, int af)
{
if(!b) return;
if(((af & NDBUF_BURN) && (b->flags & NDBUF_UCMO)) && !b->mop->zero) return;
b->flags |= af;
return;
@ -715,6 +782,8 @@ void ndbuf_exflags(ndbuf_t *b, int nf)
{
if(!b) return;
if(b->flags & NDBUF_UCMO) nf |= NDBUF_UCMO;
b->flags = nf;
return;
@ -749,24 +818,43 @@ int ndbuf_cmp(ndbuf_t *b1, ndbuf_t *b2)
/* let the buffer to use actually used bytes, not all allocated space
* will return 0 on success (or in case if it doesn't required),
* ENOMEM or other error if fails
* TODO: ? make this buffer non reallocable ?
*/
int ndbuf_memopt(ndbuf_t *b)
{
uint32_t len;
size_t bs = b->blk_size;
char *ne;
const struct ndbuf_memops *o = NULL;
if(!b || !b->raw) return EINVAL;
if((b->rlength - b->ulength) > DEFAULT_PREALLOC_SIZE) {
if((b->rlength - b->ulength) > bs) {
len = b->ulength +
(b->ulength%DEFAULT_PREALLOC_SIZE != 0 ?
(DEFAULT_PREALLOC_SIZE - b->ulength%DEFAULT_PREALLOC_SIZE) : 0);
if(!(ne = malloc(len))) return ENOMEM;
(b->ulength%bs != 0 ? (bs - b->ulength%bs) : 0);
if(b->flags & NDBUF_UCMO) o = b->mop;
if(o) ne = (char *)o->alloc(len);
else ne = malloc(len);
if(!ne) return ENOMEM;
if(b->flags & NDBUF_BURN) {
if(o) o->zero((void *)ne, len);
else memset(ne, 0, len);
}
if(b->flags & NDBUF_BURN) memset(ne, 0, len);
memcpy(ne, b->raw, b->ulength);
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->ulength);
free(b->raw);
if(o) {
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
o->free((void *)b->raw);
} else {
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
free(b->raw);
}
b->raw = ne;
b->rlength = len;
}

Loading…
Cancel
Save