pack.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <oventi.h>
  4. /*
  5. * integer conversion routines
  6. */
  7. #define U8GET(p) ((p)[0])
  8. #define U16GET(p) (((p)[0]<<8)|(p)[1])
  9. #define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
  10. #define U48GET(p) (((vlong)U16GET(p)<<32)|(vlong)U32GET((p)+2))
  11. #define U64GET(p) (((vlong)U32GET(p)<<32)|(vlong)U32GET((p)+4))
  12. #define U8PUT(p,v) (p)[0]=(v)
  13. #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
  14. #define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
  15. #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
  16. #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
  17. static int
  18. checkSize(int n)
  19. {
  20. if(n < 256 || n > VtMaxLumpSize) {
  21. vtSetError("bad block size");
  22. return 0;
  23. }
  24. return 1;
  25. }
  26. void
  27. vtRootPack(VtRoot *r, uchar *p)
  28. {
  29. uchar *op = p;
  30. U16PUT(p, r->version);
  31. p += 2;
  32. memmove(p, r->name, sizeof(r->name));
  33. p += sizeof(r->name);
  34. memmove(p, r->type, sizeof(r->type));
  35. p += sizeof(r->type);
  36. memmove(p, r->score, VtScoreSize);
  37. p += VtScoreSize;
  38. U16PUT(p, r->blockSize);
  39. p += 2;
  40. memmove(p, r->prev, VtScoreSize);
  41. p += VtScoreSize;
  42. assert(p-op == VtRootSize);
  43. }
  44. int
  45. vtRootUnpack(VtRoot *r, uchar *p)
  46. {
  47. uchar *op = p;
  48. memset(r, 0, sizeof(*r));
  49. r->version = U16GET(p);
  50. if(r->version != VtRootVersion) {
  51. vtSetError("unknown root version");
  52. return 0;
  53. }
  54. p += 2;
  55. memmove(r->name, p, sizeof(r->name));
  56. r->name[sizeof(r->name)-1] = 0;
  57. p += sizeof(r->name);
  58. memmove(r->type, p, sizeof(r->type));
  59. r->type[sizeof(r->type)-1] = 0;
  60. p += sizeof(r->type);
  61. memmove(r->score, p, VtScoreSize);
  62. p += VtScoreSize;
  63. r->blockSize = U16GET(p);
  64. if(!checkSize(r->blockSize))
  65. return 0;
  66. p += 2;
  67. memmove(r->prev, p, VtScoreSize);
  68. p += VtScoreSize;
  69. assert(p-op == VtRootSize);
  70. return 1;
  71. }
  72. void
  73. vtEntryPack(VtEntry *e, uchar *p, int index)
  74. {
  75. ulong t32;
  76. int flags;
  77. uchar *op;
  78. p += index * VtEntrySize;
  79. op = p;
  80. U32PUT(p, e->gen);
  81. p += 4;
  82. U16PUT(p, e->psize);
  83. p += 2;
  84. U16PUT(p, e->dsize);
  85. p += 2;
  86. flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
  87. U8PUT(p, flags);
  88. p++;
  89. memset(p, 0, 5);
  90. p += 5;
  91. U48PUT(p, e->size, t32);
  92. p += 6;
  93. memmove(p, e->score, VtScoreSize);
  94. p += VtScoreSize;
  95. assert(p-op == VtEntrySize);
  96. }
  97. int
  98. vtEntryUnpack(VtEntry *e, uchar *p, int index)
  99. {
  100. uchar *op;
  101. p += index * VtEntrySize;
  102. op = p;
  103. e->gen = U32GET(p);
  104. p += 4;
  105. e->psize = U16GET(p);
  106. p += 2;
  107. e->dsize = U16GET(p);
  108. p += 2;
  109. e->flags = U8GET(p);
  110. e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
  111. e->flags &= ~VtEntryDepthMask;
  112. p++;
  113. p += 5;
  114. e->size = U48GET(p);
  115. p += 6;
  116. memmove(e->score, p, VtScoreSize);
  117. p += VtScoreSize;
  118. assert(p-op == VtEntrySize);
  119. if(!(e->flags & VtEntryActive))
  120. return 1;
  121. if(!checkSize(e->psize) || !checkSize(e->dsize))
  122. return 0;
  123. return 1;
  124. }