blob: aeb8dada34e85b03f6cb5d76dd8495ddeba82b74 [file] [log] [blame]
rsc056fe1b2003-11-23 18:19:58 +00001#include <u.h>
2#include <libc.h>
3#include <venti.h>
4#include "cvt.h"
5
6static int
7checksize(int n)
8{
9 if(n < 256 || n > VtMaxLumpSize) {
rsc23fb2ed2005-07-24 20:15:44 +000010 werrstr("bad block size %#ux", n);
rsc056fe1b2003-11-23 18:19:58 +000011 return -1;
12 }
13 return 0;
14}
15
16void
17vtentrypack(VtEntry *e, uchar *p, int index)
18{
19 ulong t32;
20 int flags;
21 uchar *op;
22 int depth;
23
24 p += index * VtEntrySize;
25 op = p;
26
27 U32PUT(p, e->gen);
28 p += 4;
29 U16PUT(p, e->psize);
30 p += 2;
31 U16PUT(p, e->dsize);
32 p += 2;
33 depth = e->type&VtTypeDepthMask;
rscd23a6172004-03-15 01:57:29 +000034 flags = (e->flags&~(_VtEntryDir|_VtEntryDepthMask));
35 flags |= depth << _VtEntryDepthShift;
36 if(e->type - depth == VtDirType)
37 flags |= _VtEntryDir;
rsc056fe1b2003-11-23 18:19:58 +000038 U8PUT(p, flags);
39 p++;
40 memset(p, 0, 5);
41 p += 5;
42 U48PUT(p, e->size, t32);
43 p += 6;
44 memmove(p, e->score, VtScoreSize);
45 p += VtScoreSize;
46
47 assert(p-op == VtEntrySize);
48}
49
50int
51vtentryunpack(VtEntry *e, uchar *p, int index)
52{
53 uchar *op;
54
55 p += index * VtEntrySize;
56 op = p;
57
58 e->gen = U32GET(p);
59 p += 4;
60 e->psize = U16GET(p);
61 p += 2;
62 e->dsize = U16GET(p);
63 p += 2;
64 e->flags = U8GET(p);
rscd23a6172004-03-15 01:57:29 +000065 e->type = (e->flags&_VtEntryDir) ? VtDirType : VtDataType;
66 e->type += (e->flags & _VtEntryDepthMask) >> _VtEntryDepthShift;
67 e->flags &= ~(_VtEntryDir|_VtEntryDepthMask);
rsc056fe1b2003-11-23 18:19:58 +000068 p++;
69 p += 5;
70 e->size = U48GET(p);
71 p += 6;
72 memmove(e->score, p, VtScoreSize);
73 p += VtScoreSize;
74
75 assert(p-op == VtEntrySize);
76
77 if(!(e->flags & VtEntryActive))
78 return 0;
79
rsc23fb2ed2005-07-24 20:15:44 +000080 /*
81 * Some old vac files use psize==0 and dsize==0 when the
82 * file itself has size 0 or is zeros. Just to make programs not
83 * have to figure out what block sizes of 0 means, rewrite them.
84 */
85 if(e->psize == 0 && e->dsize == 0
86 && memcmp(e->score, vtzeroscore, VtScoreSize) == 0){
87 e->psize = 4096;
88 e->dsize = 4096;
89 }
rsc056fe1b2003-11-23 18:19:58 +000090 if(checksize(e->psize) < 0 || checksize(e->dsize) < 0)
91 return -1;
92
93 return 0;
94}
95