1 /***************************************************************************
2 * Copyright (C) 2005 by Joris Guisson *
3 * joris.guisson@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
20 #include "bitset.h"
21 #include <algorithm>
22 #include <string.h>
23
24 BitSet BitSet::null;
25
BitSet(quint32 num_bits)26 BitSet::BitSet(quint32 num_bits) : num_bits(num_bits),data(nullptr)
27 {
28 num_bytes = (num_bits / 8) + ((num_bits % 8 > 0) ? 1 : 0);
29 data = new quint8[num_bytes];
30 std::fill(data,data+num_bytes,0x00);
31 num_on = 0;
32 }
33
BitSet(const quint8 * d,quint32 num_bits)34 BitSet::BitSet(const quint8* d,quint32 num_bits) : num_bits(num_bits),data(nullptr)
35 {
36 num_bytes = (num_bits / 8) + ((num_bits % 8 > 0) ? 1 : 0);
37 data = new quint8[num_bytes];
38 memcpy(data,d,num_bytes);
39 num_on = 0;
40 quint32 i = 0;
41 while (i < num_bits)
42 {
43 if (get(i))
44 num_on++;
45 i++;
46 }
47 }
48
BitSet(const BitSet & bs)49 BitSet::BitSet(const BitSet & bs) : num_bits(bs.num_bits),num_bytes(bs.num_bytes),data(nullptr),num_on(bs.num_on)
50 {
51 data = new quint8[num_bytes];
52 std::copy(bs.data,bs.data+num_bytes,data);
53 }
54
~BitSet()55 BitSet::~BitSet()
56 {
57 delete [] data;
58 }
59
60
61
operator =(const BitSet & bs)62 BitSet & BitSet::operator = (const BitSet & bs)
63 {
64 if (data)
65 delete [] data;
66 num_bytes = bs.num_bytes;
67 num_bits = bs.num_bits;
68 data = new quint8[num_bytes];
69 std::copy(bs.data,bs.data+num_bytes,data);
70 num_on = bs.num_on;
71 return *this;
72 }
73
setAll(bool on)74 void BitSet::setAll(bool on)
75 {
76 std::fill(data,data+num_bytes,on ? 0xFF : 0x00);
77 num_on = on ? num_bits : 0;
78 }
79
getContinuousRange(qint32 * start,qint32 * end,bool on)80 void BitSet::getContinuousRange(qint32 *start, qint32 *end, bool on)
81 {
82 *start = -1;
83 *end = -1;
84
85 const bool nothingFound = on ? allOff() : allOn();
86 if (nothingFound) {
87 return;
88 }
89
90 const bool everythingMatches = on ? allOn() : allOff();
91 if (everythingMatches) {
92 *start = 0;
93 *end = num_bits -1;
94 return;
95 }
96
97 for (quint32 i = 0; i < num_bits; ++i) {
98 if (get(i) == on) {
99 if (*start == -1) {
100 *start = i;
101 }
102 *end = i;
103 } else {
104 if (*start != -1) {
105 return;
106 }
107 }
108 }
109 }
110
clear()111 void BitSet::clear()
112 {
113 setAll(false);
114 }
115
orBitSet(const BitSet & other)116 void BitSet::orBitSet(const BitSet & other)
117 {
118 quint32 i = 0;
119 while (i < num_bits)
120 {
121 bool val = get(i) || other.get(i);
122 set(i,val);
123 i++;
124 }
125 }
126
allOn() const127 bool BitSet::allOn() const
128 {
129 return num_on == num_bits;
130 }
131
allOff() const132 bool BitSet::allOff() const
133 {
134 return !num_on;
135 }
136
operator ==(const BitSet & bs)137 bool BitSet::operator == (const BitSet & bs)
138 {
139 if (this->getNumBits() != bs.getNumBits())
140 return false;
141
142 return memcmp(data,bs.data,num_bytes) == 0;
143 }
144
145
146