pack.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <oventi.h>
  12. /*
  13. * integer conversion routines
  14. */
  15. #define U8GET(p) ((p)[0])
  16. #define U16GET(p) (((p)[0]<<8)|(p)[1])
  17. #define U32GET(p) ((uint32_t)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
  18. #define U48GET(p) (((int64_t)U16GET(p)<<32)|(int64_t)U32GET((p)+2))
  19. #define U64GET(p) (((int64_t)U32GET(p)<<32)|(int64_t)U32GET((p)+4))
  20. #define U8PUT(p,v) (p)[0]=(v)
  21. #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
  22. #define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
  23. #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
  24. #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
  25. static int
  26. checkSize(int n)
  27. {
  28. if(n < 256 || n > VtMaxLumpSize) {
  29. vtSetError("bad block size");
  30. return 0;
  31. }
  32. return 1;
  33. }
  34. void
  35. vtRootPack(VtRoot *r, uint8_t *p)
  36. {
  37. uint8_t *op = p;
  38. U16PUT(p, r->version);
  39. p += 2;
  40. memmove(p, r->name, sizeof(r->name));
  41. p += sizeof(r->name);
  42. memmove(p, r->type, sizeof(r->type));
  43. p += sizeof(r->type);
  44. memmove(p, r->score, VtScoreSize);
  45. p += VtScoreSize;
  46. U16PUT(p, r->blockSize);
  47. p += 2;
  48. memmove(p, r->prev, VtScoreSize);
  49. p += VtScoreSize;
  50. assert(p-op == VtRootSize);
  51. }
  52. int
  53. vtRootUnpack(VtRoot *r, uint8_t *p)
  54. {
  55. uint8_t *op = p;
  56. memset(r, 0, sizeof(*r));
  57. r->version = U16GET(p);
  58. if(r->version != VtRootVersion) {
  59. vtSetError("unknown root version");
  60. return 0;
  61. }
  62. p += 2;
  63. memmove(r->name, p, sizeof(r->name));
  64. r->name[sizeof(r->name)-1] = 0;
  65. p += sizeof(r->name);
  66. memmove(r->type, p, sizeof(r->type));
  67. r->type[sizeof(r->type)-1] = 0;
  68. p += sizeof(r->type);
  69. memmove(r->score, p, VtScoreSize);
  70. p += VtScoreSize;
  71. r->blockSize = U16GET(p);
  72. if(!checkSize(r->blockSize))
  73. return 0;
  74. p += 2;
  75. memmove(r->prev, p, VtScoreSize);
  76. p += VtScoreSize;
  77. assert(p-op == VtRootSize);
  78. return 1;
  79. }
  80. void
  81. vtEntryPack(VtEntry *e, uint8_t *p, int index)
  82. {
  83. uint32_t t32;
  84. int flags;
  85. uint8_t *op;
  86. p += index * VtEntrySize;
  87. op = p;
  88. U32PUT(p, e->gen);
  89. p += 4;
  90. U16PUT(p, e->psize);
  91. p += 2;
  92. U16PUT(p, e->dsize);
  93. p += 2;
  94. flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
  95. U8PUT(p, flags);
  96. p++;
  97. memset(p, 0, 5);
  98. p += 5;
  99. U48PUT(p, e->size, t32);
  100. p += 6;
  101. memmove(p, e->score, VtScoreSize);
  102. p += VtScoreSize;
  103. assert(p-op == VtEntrySize);
  104. }
  105. int
  106. vtEntryUnpack(VtEntry *e, uint8_t *p, int index)
  107. {
  108. uint8_t *op;
  109. p += index * VtEntrySize;
  110. op = p;
  111. e->gen = U32GET(p);
  112. p += 4;
  113. e->psize = U16GET(p);
  114. p += 2;
  115. e->dsize = U16GET(p);
  116. p += 2;
  117. e->flags = U8GET(p);
  118. e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
  119. e->flags &= ~VtEntryDepthMask;
  120. p++;
  121. p += 5;
  122. e->size = U48GET(p);
  123. p += 6;
  124. memmove(e->score, p, VtScoreSize);
  125. p += VtScoreSize;
  126. assert(p-op == VtEntrySize);
  127. if(!(e->flags & VtEntryActive))
  128. return 1;
  129. if(!checkSize(e->psize) || !checkSize(e->dsize))
  130. return 0;
  131. return 1;
  132. }