HoverRace  2.0
BitPacking.h
Go to the documentation of this file.
1 // BitPacking.h
2 //
3 // Copyright (c) 1995-1998 - Richard Langlois and Grokksoft Inc.
4 //
5 // Licensed under GrokkSoft HoverRace SourceCode License v1.0(the "License");
6 // you may not use this file except in compliance with the License.
7 //
8 // A copy of the license should have been attached to the package from which
9 // you have taken this file. If you can not find the license you can not use
10 // this file.
11 //
12 //
13 // The author makes no representations about the suitability of
14 // this software for any purpose. It is provided "as is" "AS IS",
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16 // implied.
17 //
18 // See the License for the specific language governing permissions
19 // and limitations under the License.
20 //
21 
22 #pragma once
23 
24 #include "MR_Types.h"
25 
26 namespace HoverRace {
27 namespace Util {
28 
29 template<int BYTES>
30 struct BitPack {
31  static const int SIZE = BYTES;
32 
33  // Need three bytes of padding to be safe in case we write
34  // to the array starting at the last byte.
35  static const int REALSIZE = BYTES + 3;
36  char bdata[REALSIZE];
37 
38  void InitFrom(const MR_UInt8 *data);
39 
40  void Clear();
41  void Set(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision, MR_Int32 pValue);
42  void Set(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision, MR_UInt32 pValue);
43 
44  MR_Int32 Get(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision) const;
45  MR_UInt32 Getu(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision) const;
46 };
47 
48 static_assert(std::is_pod<BitPack<32>>::value, "BitPack must be a POD type");
49 
50 template<int BYTES>
52  memcpy(bdata, data, SIZE);
53 }
54 
55 template<int BYTES>
56 MR_Int32 BitPack<BYTES>::Get(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision) const
57 {
58  union {
59  MR_Int32 s;
60  MR_UInt32 u;
61  } lReturnValue;
62 
63  const char *cdata = static_cast<const char*>(bdata);
64 
65  lReturnValue.u = (*(MR_UInt32 *) (cdata + pOffset / 8)) >> (pOffset % 8);
66 
67  if((pLen + (pOffset % 8)) > 32) {
68  lReturnValue.u |= (*(MR_UInt32 *) (cdata + (pOffset / 8) + 4)) << (32 - (pOffset % 8));
69  }
70  // Clear overhead bits and preserve sign
71  lReturnValue.s = lReturnValue.s << (32 - pLen) >> (32 - pLen);
72 
73  return lReturnValue.s << pPrecision;
74 }
75 
76 template<int BYTES>
78 {
79  MR_UInt32 lReturnValue;
80 
81  const char *cdata = static_cast<const char*>(bdata);
82 
83  lReturnValue = (*(MR_UInt32 *) (cdata + pOffset / 8)) >> (pOffset % 8);
84 
85  if(pLen + (pOffset % 8) > 32) {
86  lReturnValue |= (*(MR_UInt32 *) (cdata + (pOffset / 8) + 4)) << (32 - (pOffset % 8));
87  }
88  // Clear overhead bits
89  lReturnValue = lReturnValue << (32 - pLen) >> (32 - pLen);
90 
91  return lReturnValue << pPrecision;
92 }
93 
94 template<int BYTES>
96 {
97  memset(bdata, 0, REALSIZE);
98 }
99 
100 template<int BYTES>
101 inline void BitPack<BYTES>::Set(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision, MR_Int32 pValue)
102 {
103  char *cdata = static_cast<char*>(bdata);
104 
105  union {
106  MR_Int32 s;
107  MR_UInt32 u;
108  } conv;
109 
110  conv.s = pValue >> pPrecision;
111  MR_UInt32 lValue = conv.u;
112 
113  lValue = lValue << (32 - pLen) >> (32 - pLen);
114 
115  (*(MR_UInt32 *) (cdata + pOffset / 8)) |= lValue << (pOffset % 8);
116 
117  if((pLen + (pOffset % 8)) > 32) {
118  (*(MR_UInt32 *) (cdata + (pOffset / 8) + 4)) |= lValue >> (32 - (pOffset % 8));
119  }
120 }
121 
122 template<int BYTES>
123 inline void BitPack<BYTES>::Set(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision, MR_UInt32 pValue)
124 {
125  char *cdata = static_cast<char*>(bdata);
126 
127  MR_UInt32 lValue = pValue >> pPrecision;
128 
129  lValue = lValue << (32 - pLen) >> (32 - pLen);
130 
131  (*(MR_UInt32 *) (cdata + pOffset / 8)) |= lValue << (pOffset % 8);
132 
133  if((pLen + (pOffset % 8)) > 32) {
134  (*(MR_UInt32 *) (cdata + (pOffset / 8) + 4)) |= lValue >> (32 - (pOffset % 8));
135  }
136 }
137 
138 } // namespace Util
139 } // namespace HoverRace
char bdata[REALSIZE]
Definition: BitPacking.h:36
void InitFrom(const MR_UInt8 *data)
Definition: BitPacking.h:51
void Clear()
Definition: BitPacking.h:95
void Set(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision, MR_Int32 pValue)
Definition: BitPacking.h:101
int32_t MR_Int32
Definition: MR_Types.h:43
static const int SIZE
Definition: BitPacking.h:31
Definition: BitPacking.h:30
static const int REALSIZE
Definition: BitPacking.h:35
MR_Int32 Get(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision) const
Definition: BitPacking.h:56
Definition: Announcement.h:24
uint32_t MR_UInt32
Definition: MR_Types.h:44
MR_UInt32 Getu(MR_UInt32 pOffset, MR_UInt32 pLen, MR_UInt32 pPrecision) const
Definition: BitPacking.h:77
uint8_t MR_UInt8
Definition: MR_Types.h:40