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