rsc | 056fe1b | 2003-11-23 18:19:58 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <venti.h> |
| 4 | #include "cvt.h" |
| 5 | |
| 6 | static int |
| 7 | checksize(int n) |
| 8 | { |
| 9 | if(n < 256 || n > VtMaxLumpSize) { |
rsc | 23fb2ed | 2005-07-24 20:15:44 +0000 | [diff] [blame] | 10 | werrstr("bad block size %#ux", n); |
rsc | 056fe1b | 2003-11-23 18:19:58 +0000 | [diff] [blame] | 11 | return -1; |
| 12 | } |
| 13 | return 0; |
| 14 | } |
| 15 | |
| 16 | void |
| 17 | vtentrypack(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; |
rsc | d23a617 | 2004-03-15 01:57:29 +0000 | [diff] [blame] | 34 | flags = (e->flags&~(_VtEntryDir|_VtEntryDepthMask)); |
| 35 | flags |= depth << _VtEntryDepthShift; |
| 36 | if(e->type - depth == VtDirType) |
| 37 | flags |= _VtEntryDir; |
rsc | 056fe1b | 2003-11-23 18:19:58 +0000 | [diff] [blame] | 38 | 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 | |
| 50 | int |
| 51 | vtentryunpack(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); |
rsc | d23a617 | 2004-03-15 01:57:29 +0000 | [diff] [blame] | 65 | e->type = (e->flags&_VtEntryDir) ? VtDirType : VtDataType; |
| 66 | e->type += (e->flags & _VtEntryDepthMask) >> _VtEntryDepthShift; |
| 67 | e->flags &= ~(_VtEntryDir|_VtEntryDepthMask); |
rsc | 056fe1b | 2003-11-23 18:19:58 +0000 | [diff] [blame] | 68 | 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 | |
rsc | 23fb2ed | 2005-07-24 20:15:44 +0000 | [diff] [blame] | 80 | /* |
| 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 | } |
rsc | 056fe1b | 2003-11-23 18:19:58 +0000 | [diff] [blame] | 90 | if(checksize(e->psize) < 0 || checksize(e->dsize) < 0) |
| 91 | return -1; |
| 92 | |
| 93 | return 0; |
| 94 | } |
| 95 | |