VLEPacker.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* Copyright The kNet Project.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License. */
  11. #pragma once
  12. /** @file VLEPacker.h
  13. @brief The VLEType2<int,int> and VLEType3<int,int,int> template classes. */
  14. #include "BitOps.h"
  15. #include "NetException.h"
  16. namespace kNet
  17. {
  18. /// VLEPacker performs variable-length encoding of unsigned integer values by omitting leading
  19. /// zeroes from big numbers.
  20. template<int bits1, int bits2>
  21. class VLEType2
  22. {
  23. public:
  24. static const int numBits1 = bits1;
  25. static const int numBits2 = bits2;
  26. // For compatibility when inter-using with VLEType3
  27. static const int numBits3 = 0;
  28. static const u32 maxValue1 = static_cast<u32>(LSBT<numBits1>::val);
  29. static const u32 maxValue2 = static_cast<u32>(LSBT<numBits1+numBits2>::val);
  30. static const u32 maxValue = maxValue2;
  31. static const u32 bitsValue1 = numBits1 + 1;
  32. static const u32 bitsValue2 = numBits1 + 1 + numBits2;
  33. static const u32 maxBits = bitsValue2;
  34. static const u32 bitMask1 = static_cast<u32>(BitMaskT<0, numBits1>::val);
  35. static const u32 bitMask2 = static_cast<u32>(BitMaskT<bitsValue1, numBits2>::val);// == ((1 << numBits2) - 1) << bitsValue1;
  36. static int GetEncodedBitLength(u32 value)
  37. {
  38. if (value <= maxValue1)
  39. return bitsValue1;
  40. else
  41. return bitsValue2;
  42. }
  43. static u32 Encode(u32 value)
  44. {
  45. if (value > maxValue)
  46. throw NetException("VLEType2::Encode: Trying to encode too large value!");
  47. if (value <= maxValue1)
  48. return value;
  49. else
  50. {
  51. if (value > maxValue)
  52. value = maxValue;
  53. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  54. u32 medPart = value & BitMaskT<numBits1, numBits2>::val;
  55. assert(medPart != 0);
  56. return lowPart | (1 << numBits1) | (medPart << 1);
  57. }
  58. }
  59. static u32 Decode(u32 value)
  60. {
  61. if ((value & (1 << numBits1)) == 0)
  62. return value;
  63. else
  64. {
  65. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  66. u32 medPart = value & BitMaskT<numBits1+1, numBits2>::val;
  67. return lowPart | (medPart >> 1);
  68. }
  69. }
  70. };
  71. /// VLEPacker performs variable-length encoding of unsigned integer values by omitting leading
  72. /// zeroes from big numbers.
  73. template<int bits1, int bits2, int bits3>
  74. class VLEType3
  75. {
  76. public:
  77. static const int numBits1 = bits1;
  78. static const int numBits2 = bits2;
  79. static const int numBits3 = bits3;
  80. static const u32 maxValue1 = static_cast<u32>(LSBT<numBits1>::val);
  81. static const u32 maxValue2 = static_cast<u32>(LSBT<numBits1+numBits2>::val);
  82. static const u32 maxValue3 = static_cast<u32>(LSBT<numBits1+numBits2+numBits3>::val);
  83. static const u32 maxValue = maxValue3;
  84. static const u32 bitsValue1 = numBits1 + 1;
  85. static const u32 bitsValue2 = numBits1 + 1 + numBits2 + 1;
  86. static const u32 bitsValue3 = numBits1 + 1 + numBits2 + 1 + numBits3;
  87. static const u32 maxBits = bitsValue3;
  88. static const u32 bitMask1 = static_cast<u32>(BitMaskT<0, numBits1>::val);
  89. static const u32 bitMask2 = static_cast<u32>(BitMaskT<bitsValue1, numBits2>::val); // == ((1 << numBits2) - 1) << bitsValue1;
  90. static const u32 bitMask3 = static_cast<u32>(BitMaskT<bitsValue2, numBits3>::val); // == ((1 << numBits3) - 1) << bitsValue2;
  91. static int GetEncodedBitLength(u32 value)
  92. {
  93. if (value <= maxValue1)
  94. return bitsValue1;
  95. else if (value <= maxValue2)
  96. return bitsValue2;
  97. else
  98. return bitsValue3;
  99. }
  100. static u32 Encode(u32 value)
  101. {
  102. if (value > maxValue)
  103. throw NetException("VLEType2::Encode: Trying to encode too large value!");
  104. if (value > maxValue)
  105. value = maxValue;
  106. if (value <= maxValue1)
  107. return value;
  108. else if (value <= maxValue2)
  109. {
  110. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  111. u32 medPart = value & BitMaskT<numBits1, numBits2>::val;
  112. assert(medPart != 0);
  113. return lowPart | (1 << numBits1) | (medPart << 1);
  114. }
  115. else
  116. {
  117. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  118. u32 medPart = value & BitMaskT<numBits1, numBits2>::val;
  119. u32 highPart = value & BitMaskT<numBits1+numBits2, numBits3>::val;
  120. assert(highPart != 0);
  121. return lowPart | (1 << numBits1) | (medPart << 1) | (1 << (bitsValue1 + numBits2)) | (highPart << 2);
  122. }
  123. }
  124. static u32 Decode(u32 value)
  125. {
  126. if ((value & (1 << numBits1)) == 0)
  127. return value;
  128. else if ((value & (1 << (bitsValue1 + numBits2))) == 0)
  129. {
  130. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  131. u32 medPart = value & BitMaskT<numBits1+1, numBits2>::val;
  132. return lowPart | (medPart >> 1);
  133. }
  134. else
  135. {
  136. u32 lowPart = value & BitMaskT<0, numBits1>::val;
  137. u32 medPart = (value & BitMaskT<numBits1+1, numBits2>::val);
  138. u32 highPart = (value & BitMaskT<numBits1+1+numBits2+1, numBits3>::val);
  139. return lowPart | (medPart >> 1) | (highPart >> 2);
  140. }
  141. }
  142. };
  143. typedef VLEType3<7, 7, 16> VLE8_16_32;
  144. typedef VLEType2<7, 8> VLE8_16;
  145. typedef VLEType2<7, 24> VLE8_32;
  146. typedef VLEType2<15, 16> VLE16_32;
  147. } // ~kNet