Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 /*
6 * disk structure conversion routines
7 */
8 #define U8GET(p) ((p)[0])
9 #define U16GET(p) (((p)[0]<<8)|(p)[1])
10 #define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
11 #define U64GET(p) (((u64int)U32GET(p)<<32)|(u64int)U32GET((p)+4))
13 #define U8PUT(p,v) (p)[0]=(v)&0xFF
14 #define U16PUT(p,v) (p)[0]=((v)>>8)&0xFF;(p)[1]=(v)&0xFF
15 #define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
16 #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
18 static struct {
19 u32int m;
20 char *s;
21 } magics[] = {
22 ArenaPartMagic, "ArenaPartMagic",
23 ArenaHeadMagic, "ArenaHeadMagic",
24 ArenaMagic, "ArenaMagic",
25 ISectMagic, "ISectMagic",
26 };
28 static char*
29 fmtmagic(char *s, u32int m)
30 {
31 int i;
33 for(i=0; i<nelem(magics); i++)
34 if(magics[i].m == m)
35 return magics[i].s;
36 sprint(s, "0x%08lux", m);
37 return s;
38 }
40 u32int
41 unpackmagic(u8int *buf)
42 {
43 return U32GET(buf);
44 }
46 void
47 packmagic(u32int magic, u8int *buf)
48 {
49 U32PUT(buf, magic);
50 }
52 int
53 unpackarenapart(ArenaPart *ap, u8int *buf)
54 {
55 u8int *p;
56 u32int m;
57 char fbuf[20];
59 p = buf;
61 m = U32GET(p);
62 if(m != ArenaPartMagic){
63 seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%lux)", fmtmagic(fbuf, m), ArenaPartMagic);
64 return -1;
65 }
66 p += U32Size;
67 ap->version = U32GET(p);
68 p += U32Size;
69 ap->blocksize = U32GET(p);
70 p += U32Size;
71 ap->arenabase = U32GET(p);
72 p += U32Size;
74 if(buf + ArenaPartSize != p)
75 sysfatal("unpackarenapart unpacked wrong amount");
77 return 0;
78 }
80 int
81 packarenapart(ArenaPart *ap, u8int *buf)
82 {
83 u8int *p;
85 p = buf;
87 U32PUT(p, ArenaPartMagic);
88 p += U32Size;
89 U32PUT(p, ap->version);
90 p += U32Size;
91 U32PUT(p, ap->blocksize);
92 p += U32Size;
93 U32PUT(p, ap->arenabase);
94 p += U32Size;
96 if(buf + ArenaPartSize != p)
97 sysfatal("packarenapart packed wrong amount");
99 return 0;
102 int
103 unpackarena(Arena *arena, u8int *buf)
105 u8int *p;
106 u32int m;
107 char fbuf[20];
109 p = buf;
111 m = U32GET(p);
112 if(m != ArenaMagic){
113 seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaMagic (%lux)", fmtmagic(fbuf, m), m, ArenaMagic);
114 return -1;
116 p += U32Size;
117 arena->version = U32GET(p);
118 p += U32Size;
119 namecp(arena->name, (char*)p);
120 p += ANameSize;
121 arena->clumps = U32GET(p);
122 p += U32Size;
123 arena->cclumps = U32GET(p);
124 p += U32Size;
125 arena->ctime = U32GET(p);
126 p += U32Size;
127 arena->wtime = U32GET(p);
128 p += U32Size;
129 arena->used = U64GET(p);
130 p += U64Size;
131 arena->uncsize = U64GET(p);
132 p += U64Size;
133 arena->sealed = U8GET(p);
134 p += U8Size;
136 if(buf + ArenaSize != p)
137 sysfatal("unpackarena unpacked wrong amount");
139 return 0;
142 int
143 packarena(Arena *arena, u8int *buf)
145 u8int *p;
146 u32int t32;
148 p = buf;
150 U32PUT(p, ArenaMagic);
151 p += U32Size;
152 U32PUT(p, arena->version);
153 p += U32Size;
154 namecp((char*)p, arena->name);
155 p += ANameSize;
156 U32PUT(p, arena->clumps);
157 p += U32Size;
158 U32PUT(p, arena->cclumps);
159 p += U32Size;
160 U32PUT(p, arena->ctime);
161 p += U32Size;
162 U32PUT(p, arena->wtime);
163 p += U32Size;
164 U64PUT(p, arena->used, t32);
165 p += U64Size;
166 U64PUT(p, arena->uncsize, t32);
167 p += U64Size;
168 U8PUT(p, arena->sealed);
169 p += U8Size;
171 if(buf + ArenaSize != p)
172 sysfatal("packarena packed wrong amount");
174 return 0;
177 int
178 unpackarenahead(ArenaHead *head, u8int *buf)
180 u8int *p;
181 u32int m;
182 char fbuf[20];
184 p = buf;
186 m = U32GET(p);
187 if(m != ArenaHeadMagic){
188 seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaHeadMagic (%lux)",
189 fmtmagic(fbuf, m), ArenaHeadMagic);
190 return -1;
192 p += U32Size;
193 head->version = U32GET(p);
194 p += U32Size;
195 namecp(head->name, (char*)p);
196 p += ANameSize;
197 head->blocksize = U32GET(p);
198 p += U32Size;
199 head->size = U64GET(p);
200 p += U64Size;
202 if(buf + ArenaHeadSize != p)
203 sysfatal("unpackarenahead unpacked wrong amount");
205 return 0;
208 int
209 packarenahead(ArenaHead *head, u8int *buf)
211 u8int *p;
212 u32int t32;
214 p = buf;
216 U32PUT(p, ArenaHeadMagic);
217 p += U32Size;
218 U32PUT(p, head->version);
219 p += U32Size;
220 namecp((char*)p, head->name);
221 p += ANameSize;
222 U32PUT(p, head->blocksize);
223 p += U32Size;
224 U64PUT(p, head->size, t32);
225 p += U64Size;
227 if(buf + ArenaHeadSize != p)
228 sysfatal("packarenahead packed wrong amount");
230 return 0;
233 static int
234 checkclump(Clump *w)
236 if(w->encoding == ClumpENone){
237 if(w->info.size != w->info.uncsize){
238 seterr(ECorrupt, "uncompressed wad size mismatch");
239 return -1;
241 }else if(w->encoding == ClumpECompress){
242 if(w->info.size >= w->info.uncsize){
243 seterr(ECorrupt, "compressed lump has inconsistent block sizes %d %d", w->info.size, w->info.uncsize);
244 return -1;
246 }else{
247 seterr(ECorrupt, "clump has illegal encoding");
248 return -1;
251 return 0;
254 int
255 unpackclump(Clump *c, u8int *buf)
257 u8int *p;
258 u32int magic;
260 p = buf;
261 magic = U32GET(p);
262 if(magic != ClumpMagic){
263 seterr(ECorrupt, "clump has bad magic number=%#8.8ux", magic);
264 return -1;
266 p += U32Size;
268 c->info.type = vtfromdisktype(U8GET(p));
269 p += U8Size;
270 c->info.size = U16GET(p);
271 p += U16Size;
272 c->info.uncsize = U16GET(p);
273 p += U16Size;
274 scorecp(c->info.score, p);
275 p += VtScoreSize;
277 c->encoding = U8GET(p);
278 p += U8Size;
279 c->creator = U32GET(p);
280 p += U32Size;
281 c->time = U32GET(p);
282 p += U32Size;
284 if(buf + ClumpSize != p)
285 sysfatal("unpackclump unpacked wrong amount");
287 return checkclump(c);
290 int
291 packclump(Clump *c, u8int *buf)
293 u8int *p;
295 p = buf;
296 U32PUT(p, ClumpMagic);
297 p += U32Size;
299 U8PUT(p, vttodisktype(c->info.type));
300 p += U8Size;
301 U16PUT(p, c->info.size);
302 p += U16Size;
303 U16PUT(p, c->info.uncsize);
304 p += U16Size;
305 scorecp(p, c->info.score);
306 p += VtScoreSize;
308 U8PUT(p, c->encoding);
309 p += U8Size;
310 U32PUT(p, c->creator);
311 p += U32Size;
312 U32PUT(p, c->time);
313 p += U32Size;
315 if(buf + ClumpSize != p)
316 sysfatal("packclump packed wrong amount");
318 return checkclump(c);
321 void
322 unpackclumpinfo(ClumpInfo *ci, u8int *buf)
324 u8int *p;
326 p = buf;
327 ci->type = vtfromdisktype(U8GET(p));
328 p += U8Size;
329 ci->size = U16GET(p);
330 p += U16Size;
331 ci->uncsize = U16GET(p);
332 p += U16Size;
333 scorecp(ci->score, p);
334 p += VtScoreSize;
336 if(buf + ClumpInfoSize != p)
337 sysfatal("unpackclumpinfo unpacked wrong amount");
340 void
341 packclumpinfo(ClumpInfo *ci, u8int *buf)
343 u8int *p;
345 p = buf;
346 U8PUT(p, vttodisktype(ci->type));
347 p += U8Size;
348 U16PUT(p, ci->size);
349 p += U16Size;
350 U16PUT(p, ci->uncsize);
351 p += U16Size;
352 scorecp(p, ci->score);
353 p += VtScoreSize;
355 if(buf + ClumpInfoSize != p)
356 sysfatal("packclumpinfo packed wrong amount");
359 int
360 unpackisect(ISect *is, u8int *buf)
362 u8int *p;
363 u32int m;
364 char fbuf[20];
366 p = buf;
369 m = U32GET(p);
370 if(m != ISectMagic){
371 seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%lux)",
372 fmtmagic(fbuf, m), ISectMagic);
373 return -1;
375 p += U32Size;
376 is->version = U32GET(p);
377 p += U32Size;
378 namecp(is->name, (char*)p);
379 p += ANameSize;
380 namecp(is->index, (char*)p);
381 p += ANameSize;
382 is->blocksize = U32GET(p);
383 p += U32Size;
384 is->blockbase = U32GET(p);
385 p += U32Size;
386 is->blocks = U32GET(p);
387 p += U32Size;
388 is->start = U32GET(p);
389 p += U32Size;
390 is->stop = U32GET(p);
391 p += U32Size;
393 if(buf + ISectSize != p)
394 sysfatal("unpackisect unpacked wrong amount");
396 return 0;
399 int
400 packisect(ISect *is, u8int *buf)
402 u8int *p;
404 p = buf;
406 U32PUT(p, ISectMagic);
407 p += U32Size;
408 U32PUT(p, is->version);
409 p += U32Size;
410 namecp((char*)p, is->name);
411 p += ANameSize;
412 namecp((char*)p, is->index);
413 p += ANameSize;
414 U32PUT(p, is->blocksize);
415 p += U32Size;
416 U32PUT(p, is->blockbase);
417 p += U32Size;
418 U32PUT(p, is->blocks);
419 p += U32Size;
420 U32PUT(p, is->start);
421 p += U32Size;
422 U32PUT(p, is->stop);
423 p += U32Size;
425 if(buf + ISectSize != p)
426 sysfatal("packisect packed wrong amount");
428 return 0;
431 void
432 unpackientry(IEntry *ie, u8int *buf)
434 u8int *p;
436 p = buf;
438 scorecp(ie->score, p);
439 p += VtScoreSize;
440 ie->wtime = U32GET(p);
441 p += U32Size;
442 ie->train = U16GET(p);
443 p += U16Size;
444 ie->ia.addr = U64GET(p);
445 if(ie->ia.addr>>56) print("%.8H => %llux\n", p, ie->ia.addr);
446 p += U64Size;
447 ie->ia.size = U16GET(p);
448 p += U16Size;
449 if(p - buf != IEntryTypeOff)
450 sysfatal("unpackientry bad IEntryTypeOff amount");
451 ie->ia.type = vtfromdisktype(U8GET(p));
452 p += U8Size;
453 ie->ia.blocks = U8GET(p);
454 p += U8Size;
456 if(p - buf != IEntrySize)
457 sysfatal("unpackientry unpacked wrong amount");
460 void
461 packientry(IEntry *ie, u8int *buf)
463 u32int t32;
464 u8int *p;
466 p = buf;
468 scorecp(p, ie->score);
469 p += VtScoreSize;
470 U32PUT(p, ie->wtime);
471 p += U32Size;
472 U16PUT(p, ie->train);
473 p += U16Size;
474 U64PUT(p, ie->ia.addr, t32);
475 p += U64Size;
476 U16PUT(p, ie->ia.size);
477 p += U16Size;
478 U8PUT(p, vttodisktype(ie->ia.type));
479 p += U8Size;
480 U8PUT(p, ie->ia.blocks);
481 p += U8Size;
483 if(p - buf != IEntrySize)
484 sysfatal("packientry packed wrong amount");
487 void
488 unpackibucket(IBucket *b, u8int *buf)
490 b->n = U16GET(buf);
491 b->depth = U32GET(&buf[U16Size]);
492 b->data = buf + IBucketSize;
495 void
496 packibucket(IBucket *b, u8int *buf)
498 U16PUT(buf, b->n);
499 U32PUT(&buf[U16Size], b->depth);