pack.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. #include "error.h"
  5. /*
  6. * integer conversion routines
  7. */
  8. #define U8GET(p) ((p)[0])
  9. #define U16GET(p) (((p)[0]<<8)|(p)[1])
  10. #define U32GET(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
  11. #define U48GET(p) (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2))
  12. #define U64GET(p) (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4))
  13. #define U8PUT(p,v) (p)[0]=(v)
  14. #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
  15. #define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
  16. #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
  17. #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
  18. void
  19. headerPack(Header *h, uchar *p)
  20. {
  21. memset(p, 0, HeaderSize);
  22. U32PUT(p, HeaderMagic);
  23. U16PUT(p+4, HeaderVersion);
  24. U16PUT(p+6, h->blockSize);
  25. U32PUT(p+8, h->super);
  26. U32PUT(p+12, h->label);
  27. U32PUT(p+16, h->data);
  28. U32PUT(p+20, h->end);
  29. }
  30. int
  31. headerUnpack(Header *h, uchar *p)
  32. {
  33. if(U32GET(p) != HeaderMagic){
  34. vtSetError("vac header bad magic");
  35. return 0;
  36. }
  37. h->version = U16GET(p+4);
  38. if(h->version != HeaderVersion){
  39. vtSetError("vac header bad version");
  40. return 0;
  41. }
  42. h->blockSize = U16GET(p+6);
  43. h->super = U32GET(p+8);
  44. h->label = U32GET(p+12);
  45. h->data = U32GET(p+16);
  46. h->end = U32GET(p+20);
  47. return 1;
  48. }
  49. void
  50. labelPack(Label *l, uchar *p, int i)
  51. {
  52. p += i*LabelSize;
  53. U8PUT(p, l->state);
  54. U8PUT(p+1, l->type);
  55. U32PUT(p+2, l->epoch);
  56. U32PUT(p+6, l->epochClose);
  57. U32PUT(p+10, l->tag);
  58. }
  59. int
  60. labelUnpack(Label *l, uchar *p, int i)
  61. {
  62. p += i*LabelSize;
  63. l->state = p[0];
  64. l->type = p[1];
  65. l->epoch = U32GET(p+2);
  66. l->epochClose = U32GET(p+6);
  67. l->tag = U32GET(p+10);
  68. if(l->type > BtMax){
  69. Bad:
  70. vtSetError(EBadLabel);
  71. fprint(2, "%s: labelUnpack: bad label: 0x%.2ux 0x%.2ux 0x%.8ux "
  72. "0x%.8ux 0x%.8ux\n", argv0, l->state, l->type, l->epoch,
  73. l->epochClose, l->tag);
  74. return 0;
  75. }
  76. if(l->state != BsBad && l->state != BsFree){
  77. if(!(l->state&BsAlloc) || l->state & ~BsMask)
  78. goto Bad;
  79. if(l->state&BsClosed){
  80. if(l->epochClose == ~(u32int)0)
  81. goto Bad;
  82. }else{
  83. if(l->epochClose != ~(u32int)0)
  84. goto Bad;
  85. }
  86. }
  87. return 1;
  88. }
  89. u32int
  90. globalToLocal(uchar score[VtScoreSize])
  91. {
  92. int i;
  93. for(i=0; i<VtScoreSize-4; i++)
  94. if(score[i] != 0)
  95. return NilBlock;
  96. return U32GET(score+VtScoreSize-4);
  97. }
  98. void
  99. localToGlobal(u32int addr, uchar score[VtScoreSize])
  100. {
  101. memset(score, 0, VtScoreSize-4);
  102. U32PUT(score+VtScoreSize-4, addr);
  103. }
  104. void
  105. entryPack(Entry *e, uchar *p, int index)
  106. {
  107. ulong t32;
  108. int flags;
  109. p += index * VtEntrySize;
  110. U32PUT(p, e->gen);
  111. U16PUT(p+4, e->psize);
  112. U16PUT(p+6, e->dsize);
  113. flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
  114. U8PUT(p+8, flags);
  115. memset(p+9, 0, 5);
  116. U48PUT(p+14, e->size, t32);
  117. if(flags & VtEntryLocal){
  118. if(globalToLocal(e->score) == NilBlock)
  119. abort();
  120. memset(p+20, 0, 7);
  121. U8PUT(p+27, e->archive);
  122. U32PUT(p+28, e->snap);
  123. U32PUT(p+32, e->tag);
  124. memmove(p+36, e->score+16, 4);
  125. }else
  126. memmove(p+20, e->score, VtScoreSize);
  127. }
  128. int
  129. entryUnpack(Entry *e, uchar *p, int index)
  130. {
  131. p += index * VtEntrySize;
  132. e->gen = U32GET(p);
  133. e->psize = U16GET(p+4);
  134. e->dsize = U16GET(p+6);
  135. e->flags = U8GET(p+8);
  136. e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
  137. e->flags &= ~VtEntryDepthMask;
  138. e->size = U48GET(p+14);
  139. if(e->flags & VtEntryLocal){
  140. e->archive = p[27];
  141. e->snap = U32GET(p+28);
  142. e->tag = U32GET(p+32);
  143. memset(e->score, 0, 16);
  144. memmove(e->score+16, p+36, 4);
  145. }else{
  146. e->archive = 0;
  147. e->snap = 0;
  148. e->tag = 0;
  149. memmove(e->score, p+20, VtScoreSize);
  150. }
  151. return 1;
  152. }
  153. int
  154. entryType(Entry *e)
  155. {
  156. return (((e->flags & VtEntryDir) != 0) << 3) | e->depth;
  157. }
  158. void
  159. superPack(Super *s, uchar *p)
  160. {
  161. u32int t32;
  162. memset(p, 0, SuperSize);
  163. U32PUT(p, SuperMagic);
  164. assert(s->version == SuperVersion);
  165. U16PUT(p+4, s->version);
  166. U32PUT(p+6, s->epochLow);
  167. U32PUT(p+10, s->epochHigh);
  168. U64PUT(p+14, s->qid, t32);
  169. U32PUT(p+22, s->active);
  170. U32PUT(p+26, s->next);
  171. U32PUT(p+30, s->current);
  172. memmove(p+34, s->last, VtScoreSize);
  173. memmove(p+54, s->name, sizeof(s->name));
  174. }
  175. int
  176. superUnpack(Super *s, uchar *p)
  177. {
  178. memset(s, 0, sizeof(*s));
  179. if(U32GET(p) != SuperMagic)
  180. goto Err;
  181. s->version = U16GET(p+4);
  182. if(s->version != SuperVersion)
  183. goto Err;
  184. s->epochLow = U32GET(p+6);
  185. s->epochHigh = U32GET(p+10);
  186. s->qid = U64GET(p+14);
  187. if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0)
  188. goto Err;
  189. s->active = U32GET(p+22);
  190. s->next = U32GET(p+26);
  191. s->current = U32GET(p+30);
  192. memmove(s->last, p+34, VtScoreSize);
  193. memmove(s->name, p+54, sizeof(s->name));
  194. s->name[sizeof(s->name)-1] = 0;
  195. return 1;
  196. Err:
  197. memset(s, 0, sizeof(*s));
  198. vtSetError(EBadSuper);
  199. return 0;
  200. }