1
/* VerifyPN - TAPAAL Petri Net Engine
2
* Copyright (C) 2016 Peter Gjøl Jensen <root@petergjoel.dk>
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
* File: binarywrapper.h
20
* Author: Peter G. Jensen
22
* Created on 10 June 2015, 19:20
32
#ifndef BINARYWRAPPER_H
33
#define BINARYWRAPPER_H
35
#define __BW_BSIZE__ sizeof(size_t) // SIZE OF POINTER!
38
typedef unsigned int uint;
39
typedef unsigned char uchar;
42
* Wrapper for binary data. This provides easy access to individual bits,
43
* heap allocation and comparison. Notice that one has to make sure to
44
* explicitly call release() if one wishes to deallocate (possibly shared data).
52
* Empty constructor, no data is allocated
55
binarywrapper_t() : _blob(NULL), _nbytes(0)
60
Allocates a room for at least size bits
63
binarywrapper_t(size_t size);
66
* Constructor for copying over data from latest the offset'th bit.
68
* @param other: wrapper to copy from
69
* @param offset: maximal number of bits to skip.
72
binarywrapper_t(const binarywrapper_t& other, uint offset);
74
inline void init(const binarywrapper_t& other, uint size, uint offset,
77
uint so = size + offset;
78
offset = ((so - 1) / 8) - ((size - 1) / 8);
80
_nbytes = ((encodingsize + this->overhead(encodingsize)) / 8);
87
_blob = allocate(_nbytes);
89
memcpy(raw(), &(other.const_raw()[offset]), _nbytes);
93
binarywrapper_t(uchar* raw, uint size, uint offset, uint encsize);
96
* Assign (not copy) raw data to pointer. Set number of bytes to size
97
* @param raw: some memory to point to
98
* @param size: number of bytes.
101
binarywrapper_t(uchar* raw, uint size);
104
* Empty destructor. Does NOT deallocate data - do this with explicit
113
* Makes a complete copy, including new heap-allocation
114
* @return an exact copy, but in a different area of the heap.
117
//binarywrapper_t clone() const;
120
* Copy over data and meta-data from other, but insert only into target
122
* Notice that this can cause memory-corruption if there is not enough
123
* room in target, or to many bits are skipped.
124
* @param other: wrapper to copy from
125
* @param offset: bits to skip
128
void copy(const binarywrapper_t& other, uint offset);
131
* Copy over size bytes form raw data. Assumes that current wrapper has
133
* @param raw: source data
134
* @param size: number of bytes to copy
137
void copy(const uchar* raw, uint size);
141
* Get value of the place'th bit
142
* @param place: bit index
145
inline bool at(const uint place) const
147
uint offset = place % 8;
149
if (place / 8 < _nbytes)
150
res2 = (const_raw()[place / 8] & _masks[offset]) != 0;
158
* number of bytes allocated in heap
162
inline uint size() const
168
* Raw access to data when in const setting
172
inline uchar* const_raw() const
174
if(_nbytes <= __BW_BSIZE__) return offset((uchar*)&_blob, _nbytes);
176
return offset(_blob, _nbytes);
190
* pretty print of content
193
void print(std::ostream& strean, size_t length = std::numeric_limits<size_t>::max()) const;
196
* finds the overhead (unused number of bits) when allocating for size
198
* @param size: number of bits
202
static size_t overhead(size_t size);
205
static size_t bytes(size_t size);
208
* Change value of place'th bit
209
* @param place: index of bit to change
210
* @param value: desired value
213
inline void set(const uint place, const bool value) const
215
assert(place < _nbytes*8);
216
uint offset = place % 8;
217
uint theplace = place / 8;
219
const_raw()[theplace] |= _masks[offset];
221
const_raw()[theplace] &= ~_masks[offset];
226
* Sets all memory on heap to 0
229
inline void zero() const
231
if(_nbytes > 0 && _blob != NULL)
233
memset(const_raw(), 0x0, _nbytes);
238
* Deallocates memory stored on heap
241
inline void release()
243
if(_nbytes > __BW_BSIZE__)
250
* Nice access to single bits
251
* @param i: index to access
255
inline uchar operator[](size_t i) const
260
return const_raw()[i];
265
* Compares two wrappers. Assumes that smaller number of bytes also means
266
* a smaller wrapper. Otherwise compares byte by byte.
267
* @param other: wrapper to compare to
268
* @return -1 if other is smaller, 0 if same, 1 if other is larger
270
inline int cmp(const binarywrapper_t &other) const
272
if(_nbytes < other._nbytes) return -1;
273
else if(_nbytes > other._nbytes) return 1;
275
size_t bcmp = std::min(_nbytes, other._nbytes);
276
return memcmp(const_raw(), other.const_raw(), bcmp);
280
* Compares wrappers bytes by bytes. If sizes do not match, they are not
281
* equal. If sizes match, compares byte by byte.
284
* @return true if a match, false otherwise
286
friend bool operator==( const binarywrapper_t &enc1,
287
const binarywrapper_t &enc2) {
288
return enc1.cmp(enc2) == 0;
291
const static uchar _masks[8];
294
static inline uchar* allocate(size_t n)
296
if(n <= __BW_BSIZE__) return 0;
300
if(n % __BW_BSIZE__ != 0) n = (1+(n/__BW_BSIZE__))*(__BW_BSIZE__);
301
assert(n % __BW_BSIZE__ == 0);
303
return (uchar*)malloc(n);
306
static inline uchar* zallocate(size_t n)
308
if(n <= __BW_BSIZE__) return 0;
312
if(n % __BW_BSIZE__ != 0)
314
n = (1+(n/__BW_BSIZE__))*(__BW_BSIZE__);
315
assert(n == on + (__BW_BSIZE__ - (on % __BW_BSIZE__)));
317
assert(n % __BW_BSIZE__ == 0);
319
return (uchar*)calloc(n, 1);
322
static inline void dealloc(uchar* data)
327
static inline uchar* offset(uchar* data, uint32_t size)
329
// if((size % __BW_BSIZE__) == 0) return data;
330
// else return &data[(__BW_BSIZE__ - (size % __BW_BSIZE__))];
334
// blob of heap-allocated data
337
// number of bytes allocated on heap
340
// masks for single-bit access
341
} __attribute__((packed));
344
std::ostream &operator<<(std::ostream &os, const ptrie::binarywrapper_t &b);
346
#endif /* BINARYWRAPPER_H */