zblock.c 1.6 KB

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