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