pack.c 5.2 KB

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