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