1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4 
5 void
fmtzbinit(Fmt * f,ZBlock * b)6 fmtzbinit(Fmt *f, ZBlock *b)
7 {
8 	memset(f, 0, sizeof *f);
9 #ifdef PLAN9PORT
10 	fmtlocaleinit(f, nil, nil, nil);
11 #endif
12 	f->start = b->data;
13 	f->to = f->start;
14 	f->stop = (char*)f->start + b->len;
15 }
16 
17 #define ROUNDUP(p, n) ((void*)(((uintptr)(p)+(n)-1)&~(uintptr)((n)-1)))
18 
19 enum {
20 	OverflowCheck = 32
21 };
22 static char zmagic[] = "1234567890abcdefghijklmnopqrstuvxyz";
23 
24 ZBlock *
alloczblock(u32int size,int zeroed,uint blocksize)25 alloczblock(u32int size, int zeroed, uint blocksize)
26 {
27 	uchar *p, *data;
28 	ZBlock *b;
29 	static ZBlock z;
30 	int n;
31 
32 	if(blocksize == 0)
33 		blocksize = 32;	/* try for cache line alignment */
34 
35 	n = size+OverflowCheck+sizeof(ZBlock)+blocksize+8;
36 	p = malloc(n);
37 	if(p == nil){
38 		seterr(EOk, "out of memory");
39 		return nil;
40 	}
41 
42 	data = ROUNDUP(p, blocksize);
43 	b = ROUNDUP(data+size+OverflowCheck, 8);
44 	if(0) fprint(2, "alloc %p-%p data %p-%p b %p-%p\n",
45 		p, p+n, data, data+size, b, b+1);
46 	*b = z;
47 	b->data = data;
48 	b->free = p;
49 	b->len = size;
50 	b->_size = size;
51 	if(zeroed)
52 		memset(b->data, 0, size);
53 	memmove(b->data+size, zmagic, OverflowCheck);
54 	return b;
55 }
56 
57 void
freezblock(ZBlock * b)58 freezblock(ZBlock *b)
59 {
60 	if(b){
61 		if(memcmp(b->data+b->_size, zmagic, OverflowCheck) != 0)
62 			abort();
63 		memset(b->data+b->_size, 0, OverflowCheck);
64 		free(b->free);
65 	}
66 }
67 
68 ZBlock*
packet2zblock(Packet * p,u32int size)69 packet2zblock(Packet *p, u32int size)
70 {
71 	ZBlock *b;
72 
73 	if(p == nil)
74 		return nil;
75 	b = alloczblock(size, 0, 0);
76 	if(b == nil)
77 		return nil;
78 	if(packetcopy(p, b->data, 0, size) < 0){
79 		freezblock(b);
80 		return nil;
81 	}
82 	return b;
83 }
84 
85 Packet*
zblock2packet(ZBlock * zb,u32int size)86 zblock2packet(ZBlock *zb, u32int size)
87 {
88 	Packet *p;
89 
90 	if(zb == nil)
91 		return nil;
92 	p = packetalloc();
93 	packetappend(p, zb->data, size);
94 	return p;
95 }
96