Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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;
}