#include "stdinc.h"
#include "dat.h"
#include "fns.h"
void
fmtzbinit(Fmt *f, ZBlock *b)
{
memset(f, 0, sizeof *f);
#ifdef PLAN9PORT
fmtlocaleinit(f, nil, nil, nil);
#endif
f->start = b->data;
f->to = f->start;
f->stop = (char*)f->start + b->len;
}
#define ROUNDUP(p, n) ((void*)(((uintptr)(p)+(n)-1)&~(uintptr)((n)-1)))
enum {
OverflowCheck = 32
};
static char zmagic[] = "1234567890abcdefghijklmnopqrstuvxyz";
ZBlock *
alloczblock(u32int size, int zeroed, uint blocksize)
{
uchar *p, *data;
ZBlock *b;
static ZBlock z;
int n;
if(blocksize == 0)
blocksize = 32; /* try for cache line alignment */
n = size+OverflowCheck+sizeof(ZBlock)+blocksize+8;
p = malloc(n);
if(p == nil){
seterr(EOk, "out of memory");
return nil;
}
data = ROUNDUP(p, blocksize);
b = ROUNDUP(data+size+OverflowCheck, 8);
if(0) fprint(2, "alloc %p-%p data %p-%p b %p-%p\n",
p, p+n, data, data+size, b, b+1);
*b = z;
b->data = data;
b->free = p;
b->len = size;
b->_size = size;
if(zeroed)
memset(b->data, 0, size);
memmove(b->data+size, zmagic, OverflowCheck);
return b;
}
void
freezblock(ZBlock *b)
{
if(b){
if(memcmp(b->data+b->_size, zmagic, OverflowCheck) != 0)
abort();
memset(b->data+b->_size, 0, OverflowCheck);
free(b->free);
}
}
ZBlock*
packet2zblock(Packet *p, u32int size)
{
ZBlock *b;
if(p == nil)
return nil;
b = alloczblock(size, 0, 0);
if(b == nil)
return nil;
if(packetcopy(p, b->data, 0, size) < 0){
freezblock(b);
return nil;
}
return b;
}
Packet*
zblock2packet(ZBlock *zb, u32int size)
{
Packet *p;
if(zb == nil)
return nil;
p = packetalloc();
packetappend(p, zb->data, size);
return p;
}
|