File indexing completed on 2024-02-25 05:07:03

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by Joris Guisson                                   *
0003  *   joris.guisson@gmail.com                                               *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
0019  ***************************************************************************/
0020 #include "bitset.h"
0021 #include <algorithm>
0022 #include <string.h>
0023 
0024 BitSet BitSet::null;
0025 
0026 BitSet::BitSet(quint32 num_bits)
0027     : num_bits(num_bits)
0028     , data(nullptr)
0029 {
0030     num_bytes = (num_bits / 8) + ((num_bits % 8 > 0) ? 1 : 0);
0031     data = new quint8[num_bytes];
0032     std::fill(data, data + num_bytes, 0x00);
0033     num_on = 0;
0034 }
0035 
0036 BitSet::BitSet(const quint8 *d, quint32 num_bits)
0037     : num_bits(num_bits)
0038     , data(nullptr)
0039 {
0040     num_bytes = (num_bits / 8) + ((num_bits % 8 > 0) ? 1 : 0);
0041     data = new quint8[num_bytes];
0042     memcpy(data, d, num_bytes);
0043     num_on = 0;
0044     quint32 i = 0;
0045     while (i < num_bits) {
0046         if (get(i))
0047             num_on++;
0048         i++;
0049     }
0050 }
0051 
0052 BitSet::BitSet(const BitSet &bs)
0053     : num_bits(bs.num_bits)
0054     , num_bytes(bs.num_bytes)
0055     , data(nullptr)
0056     , num_on(bs.num_on)
0057 {
0058     data = new quint8[num_bytes];
0059     std::copy(bs.data, bs.data + num_bytes, data);
0060 }
0061 
0062 BitSet::~BitSet()
0063 {
0064     delete[] data;
0065 }
0066 
0067 BitSet &BitSet::operator=(const BitSet &bs)
0068 {
0069     if (data)
0070         delete[] data;
0071     num_bytes = bs.num_bytes;
0072     num_bits = bs.num_bits;
0073     data = new quint8[num_bytes];
0074     std::copy(bs.data, bs.data + num_bytes, data);
0075     num_on = bs.num_on;
0076     return *this;
0077 }
0078 
0079 void BitSet::setAll(bool on)
0080 {
0081     std::fill(data, data + num_bytes, on ? 0xFF : 0x00);
0082     num_on = on ? num_bits : 0;
0083 }
0084 
0085 void BitSet::getContinuousRange(qint32 *start, qint32 *end, bool on)
0086 {
0087     *start = -1;
0088     *end = -1;
0089 
0090     const bool nothingFound = on ? allOff() : allOn();
0091     if (nothingFound) {
0092         return;
0093     }
0094 
0095     const bool everythingMatches = on ? allOn() : allOff();
0096     if (everythingMatches) {
0097         *start = 0;
0098         *end = num_bits - 1;
0099         return;
0100     }
0101 
0102     for (quint32 i = 0; i < num_bits; ++i) {
0103         if (get(i) == on) {
0104             if (*start == -1) {
0105                 *start = i;
0106             }
0107             *end = i;
0108         } else {
0109             if (*start != -1) {
0110                 return;
0111             }
0112         }
0113     }
0114 }
0115 
0116 void BitSet::clear()
0117 {
0118     setAll(false);
0119 }
0120 
0121 void BitSet::orBitSet(const BitSet &other)
0122 {
0123     quint32 i = 0;
0124     while (i < num_bits) {
0125         bool val = get(i) || other.get(i);
0126         set(i, val);
0127         i++;
0128     }
0129 }
0130 
0131 bool BitSet::allOn() const
0132 {
0133     return num_on == num_bits;
0134 }
0135 
0136 bool BitSet::allOff() const
0137 {
0138     return !num_on;
0139 }
0140 
0141 bool BitSet::operator==(const BitSet &bs)
0142 {
0143     if (this->getNumBits() != bs.getNumBits())
0144         return false;
0145 
0146     return memcmp(data, bs.data, num_bytes) == 0;
0147 }