entry.c 1.7 KB

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