IDA C++ SDK 9.2
Loading...
Searching...
No Matches
bitrange.hpp
Go to the documentation of this file.
1#ifndef _BITMASK_HPP
2#define _BITMASK_HPP
3
9
10//---------------------------------------------------------------------------
16{
17public:
19 explicit bitrange_t(uint16 bit_ofs = 0, uint16 size_in_bits = 0);
21 inline void init(uint16 bit_ofs, uint16 size_in_bits);
22
24 inline void reset();
26 inline bool empty() const;
27
29 inline uint bitoff() const;
31 inline uint bitsize() const;
33 inline uint bytesize() const;
35 inline uint64 mask64() const;
36
38 inline bool has_common(const bitrange_t &r) const;
39
46 inline bool apply_mask(const bitrange_t &subrange);
47
49 inline void intersect(const bitrange_t &r);
50
52 inline void create_union(const bitrange_t &r);
53
55 inline bool sub(const bitrange_t &r);
56
58 inline void shift_down(uint cnt);
60 inline void shift_up(uint cnt);
61
63 template <class T> inline void assign_max_nonzero(T mask);
64
72 inline bool extract(
73 bytevec_t *dst,
74 const void *src,
75 size_t src_size,
76 bool is_mf) const;
77 inline bool extract(
78 void *dst,
79 size_t dst_size,
80 const void *src,
81 size_t src_size,
82 bool is_mf) const;
84
92 inline bool inject(
93 void *dst,
94 size_t dst_size,
95 const void *src,
96 size_t src_size,
97 bool is_mf) const;
98 inline bool inject(
99 void *dst,
100 size_t dst_size,
101 const bytevec_t &src,
102 bool is_mf) const;
104
106
107private:
108 uint16 offset;
109 uint16 nbits;
110};
111
112//---------------------------------------------------------------------------
113inline bitrange_t::bitrange_t(uint16 bit_ofs, uint16 size_in_bits)
114 : offset(bit_ofs), nbits(size_in_bits)
115{
116}
117
118//---------------------------------------------------------------------------
119inline void bitrange_t::init(uint16 bit_ofs, uint16 size_in_bits)
120{
121 offset = bit_ofs;
122 nbits = size_in_bits;
123}
124
125//---------------------------------------------------------------------------
126inline void bitrange_t::reset()
127{
128 init(0, 0);
129}
130
131//---------------------------------------------------------------------------
132inline bool bitrange_t::empty() const
133{
134 return nbits == 0;
135}
136
137//---------------------------------------------------------------------------
139{
140 return offset;
141}
142
143//---------------------------------------------------------------------------
145{
146 return nbits;
147}
148
149//---------------------------------------------------------------------------
151{
152 return (nbits + 8-1) / 8;
153}
154
155//--------------------------------------------------------------------------
157{
158 return empty() ? 0 : (left_shift(uint64(1), nbits)-1) << offset;
159}
160
161//--------------------------------------------------------------------------
162inline bool bitrange_t::apply_mask(const bitrange_t &submask)
163{
164 if ( submask.bitoff() + submask.bitsize() > bitsize() )
165 return false;
166 init(bitoff() + submask.bitoff(), submask.bitsize());
167 return true;
168}
169
170//--------------------------------------------------------------------------
172{
173 uint16 e1 = offset + nbits;
174 uint16 e2 = r.offset + r.nbits;
175 uint16 e = qmin(e1, e2);
176 uint16 s = qmax(offset, r.offset);
177 if ( s > e )
178 {
179 s = 0;
180 e = 0;
181 }
182 init(s, e-s);
183}
184
185//--------------------------------------------------------------------------
186inline bool bitrange_t::has_common(const bitrange_t &r) const
187{
188 return interval::overlap(offset, nbits, r.offset, r.nbits);
189}
190
191//--------------------------------------------------------------------------
193{
194 uint16 e1 = offset + nbits;
195 uint16 e2 = r.offset + r.nbits;
196 uint16 e = qmax(e1, e2);
197 uint16 s = qmin(offset, r.offset);
198 init(s, e-s);
199}
200
201//--------------------------------------------------------------------------
202inline bool bitrange_t::sub(const bitrange_t &r)
203{
204 // r is in the middle of our bitrange, cannot handle this case
205 // because it would require 2 bitranges :/
206 uint16 end = offset + nbits;
207 uint16 rend = r.offset + r.nbits;
208 if ( r.offset > offset && rend < end )
209 return false;
210 if ( r.offset <= offset )
211 {
212 if ( rend > end )
213 {
214 reset();
215 }
216 else if ( rend > offset )
217 {
218 offset = rend;
219 nbits = end - offset;
220 }
221 }
222 else if ( r.offset < end )
223 {
224 nbits = r.offset - offset;
225 }
226 return true;
227}
228
229//--------------------------------------------------------------------------
230inline int bitrange_t::compare(const bitrange_t &r) const
231{
232 if ( offset != r.offset )
233 return offset < r.offset ? -1 : 1;
234 if ( nbits != r.nbits )
235 return nbits < r.nbits ? -1 : 1;
236 return 0;
237}
238
239//--------------------------------------------------------------------------
241{
242 if ( cnt > offset )
243 {
244 cnt -= offset;
245 offset = 0;
246 if ( cnt > nbits )
247 nbits = 0;
248 else
249 nbits -= cnt;
250 }
251 else
252 {
253 offset -= cnt;
254 }
255}
256
257//--------------------------------------------------------------------------
259{
260 offset += cnt;
261}
262
263//--------------------------------------------------------------------------
264template <class T> inline void bitrange_t::assign_max_nonzero(T mask)
265{
266 if ( mask == T(0) )
267 {
268 reset();
269 return;
270 }
271 int i = 0;
272 T bit = T(1);
273 for ( i=0; i < sizeof(T)*8; ++i, bit <<= 1 )
274 if ( (mask & bit) != 0 )
275 break;
276 offset = i;
277 i = sizeof(T)*8 - 1;
278 bit = left_shift(T(1), i);
279 while ( i >= offset )
280 {
281 if ( (mask & bit) != 0 )
282 break;
283 --i;
284 bit >>= 1;
285 }
286 nbits = i - offset + 1;
287}
288
289//--------------------------------------------------------------------------
290#ifndef SWIG
294idaman bool ida_export bitrange_t_extract_using_bitrange(const bitrange_t *bm, void *dst, size_t dst_size, const void *src, size_t src_size, bool is_mf);
295idaman bool ida_export bitrange_t_inject_using_bitrange(const bitrange_t *bm, void *dst, size_t dst_size, const void *src, size_t src_size, bool is_mf);
297#else
298#endif // SWIG
299
300//--------------------------------------------------------------------------
302 void *dst,
303 size_t dst_size,
304 const void *src,
305 size_t src_size,
306 bool is_mf) const
307{
308 return bitrange_t_extract_using_bitrange(this, dst, dst_size, src, src_size, is_mf);
309}
310
311//--------------------------------------------------------------------------
313 bytevec_t *dst,
314 const void *src,
315 size_t src_size,
316 bool is_mf) const
317{
318 size_t dst_size = empty() ? src_size : bytesize();
319 dst->resize(dst_size);
321 dst->begin(), dst_size,
322 src, src_size,
323 is_mf);
324}
325
326//--------------------------------------------------------------------------
328 void *dst,
329 size_t dst_size,
330 const void *src,
331 size_t src_size,
332 bool is_mf) const
333{
334 return bitrange_t_inject_using_bitrange(this, dst, dst_size, src, src_size, is_mf);
335}
336
337//--------------------------------------------------------------------------
339 void *dst,
340 size_t dst_size,
341 const bytevec_t &src,
342 bool is_mf) const
343{
345 dst, dst_size,
346 src.begin(), src.size(),
347 is_mf);
348}
349
350#endif // define _BITMASK_HPP
idaman bool ida_export bitrange_t_extract_using_bitrange(const bitrange_t *bm, void *dst, size_t dst_size, const void *src, size_t src_size, bool is_mf)
idaman bool ida_export bitrange_t_inject_using_bitrange(const bitrange_t *bm, void *dst, size_t dst_size, const void *src, size_t src_size, bool is_mf)
idaman int ida_export nbits(ea_t ea)
Get number of bits in a byte at the given address.
This class manages the offset and size of a value that occupies a number of contiguous bits within so...
Definition bitrange.hpp:16
uint bytesize() const
Size of the value in bytes.
Definition bitrange.hpp:150
bool empty() const
Is the bitrange empty?
Definition bitrange.hpp:132
bool sub(const bitrange_t &r)
Subtract a bitrange.
Definition bitrange.hpp:202
bool has_common(const bitrange_t &r) const
Does have common bits with another bitrange?
Definition bitrange.hpp:186
void shift_down(uint cnt)
Shift range down (left)
Definition bitrange.hpp:240
uint64 mask64() const
Convert to mask of 64 bits.
Definition bitrange.hpp:156
bool inject(void *dst, size_t dst_size, const void *src, size_t src_size, bool is_mf) const
Definition bitrange.hpp:327
void shift_up(uint cnt)
Shift range up (right)
Definition bitrange.hpp:258
bool extract(bytevec_t *dst, const void *src, size_t src_size, bool is_mf) const
Definition bitrange.hpp:312
bool apply_mask(const bitrange_t &subrange)
Apply mask to a bitrange.
Definition bitrange.hpp:162
uint bitoff() const
Get offset of 1st bit.
Definition bitrange.hpp:138
bitrange_t(uint16 bit_ofs=0, uint16 size_in_bits=0)
Constructor.
Definition bitrange.hpp:113
DECLARE_COMPARISONS(bitrange_t)
void reset()
Make the bitrange empty.
Definition bitrange.hpp:126
void assign_max_nonzero(T mask)
Initialize bitrange_t with offset/size defined by given mask.
Definition bitrange.hpp:264
void init(uint16 bit_ofs, uint16 size_in_bits)
Initialize offset and size to given values.
Definition bitrange.hpp:119
uint bitsize() const
Get size of the value in bits.
Definition bitrange.hpp:144
void create_union(const bitrange_t &r)
Create union of 2 ranges including the hole between them.
Definition bitrange.hpp:192
void intersect(const bitrange_t &r)
Intersect two ranges.
Definition bitrange.hpp:171
Vector of bytes (use for dynamic memory)
Definition pro.h:3773
void resize(size_t _newsize, const T &x)
Resize to the given size.
Definition pro.h:2469
iterator begin(void)
Get an iterator that points to the first element in the qvector.
Definition pro.h:2609
size_t size(void) const
Get the number of elements in the qvector.
Definition pro.h:2423
idaman const char * end
Definition pro.h:1001
cexpr_t * e
Definition hexrays.hpp:7308
unsigned __int64 uint64
Definition llong.hpp:13
THREAD_SAFE constexpr bool overlap(uval_t off1, asize_t s1, uval_t off2, asize_t s2)
Do (off1,s1) and (off2,s2) overlap?
Definition pro.h:1459
unsigned short uint16
unsigned 16 bit value
Definition pro.h:346
unsigned int uint
unsigned 32 bit value
Definition pro.h:339
constexpr T left_shift(const T &value, int shift)
Shift by the amount exceeding the operand size*8 is undefined by the standard.
Definition pro.h:1481