zblock.c (1658B)
1 #include "stdinc.h" 2 #include "dat.h" 3 #include "fns.h" 4 5 void 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 * 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 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* 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* 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 }