File indexing completed on 2024-04-28 08:49:19

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 #ifndef BTBITSET_H
0021 #define BTBITSET_H
0022 
0023 #include <QObject>
0024 #include <kget_export.h>
0025 /**
0026  * @author Joris Guisson
0027  * @brief Simple implementation of a BitSet
0028  *
0029  * Simple implementation of a BitSet, can only turn on and off bits.
0030  * BitSet's are used to indicate which chunks we have or not.
0031  */
0032 class KGET_EXPORT BitSet
0033 {
0034     quint32 num_bits, num_bytes;
0035     quint8 *data;
0036     quint32 num_on;
0037 
0038 public:
0039     /**
0040      * Constructor.
0041      * @param num_bits The number of bits
0042      */
0043     BitSet(quint32 num_bits = 8);
0044 
0045     /**
0046      * Manually set data.
0047      * @param data The data
0048      * @param num_bits The number of bits
0049      */
0050     BitSet(const quint8 *data, quint32 num_bits);
0051 
0052     /**
0053      * Copy constructor.
0054      * @param bs BitSet to copy
0055      * @return
0056      */
0057     BitSet(const BitSet &bs);
0058     virtual ~BitSet();
0059 
0060     /// See if the BitSet is null
0061     bool isNull() const
0062     {
0063         return num_bits == 0;
0064     }
0065 
0066     /**
0067      * Get the value of a bit, false means 0, true 1.
0068      * @param i Index of Bit
0069      */
0070     bool get(quint32 i) const;
0071 
0072     /**
0073      * Set the value of a bit, false means 0, true 1.
0074      * @param i Index of Bit
0075      * @param on False means 0, true 1
0076      */
0077     void set(quint32 i, bool on);
0078 
0079     /**
0080      * Sets the value of a range of bits
0081      * @param start of the range
0082      * @param end of the range
0083      * @param value to set the range to
0084      */
0085     void setRange(quint32 start, quint32 end, bool value);
0086 
0087     /// Set all bits on or off
0088     void setAll(bool on);
0089 
0090     quint32 getNumBytes() const
0091     {
0092         return num_bytes;
0093     }
0094     quint32 getNumBits() const
0095     {
0096         return num_bits;
0097     }
0098     const quint8 *getData() const
0099     {
0100         return data;
0101     }
0102     quint8 *getData()
0103     {
0104         return data;
0105     }
0106 
0107     /// Get the number of on bits
0108     quint32 numOnBits() const
0109     {
0110         return num_on;
0111     }
0112 
0113     /**
0114      * Finds a continuous range of bits that on/off
0115      * @param start here the start bit will be stored, -1 if nothing is found
0116      * @param end stores the end bit, -1 if nothing is found
0117      * @param on whether a continuous range of bits on (set) or off (not set) should be searched for
0118      */
0119     void getContinuousRange(qint32 *start, qint32 *end, bool on);
0120 
0121     /**
0122      * Set all bits to 0
0123      */
0124     void clear();
0125 
0126     /**
0127      * or this BitSet with another.
0128      * @param other The other BitSet
0129      */
0130     void orBitSet(const BitSet &other);
0131 
0132     /**
0133      * Assignment operator.
0134      * @param bs BitSet to copy
0135      * @return *this
0136      */
0137     BitSet &operator=(const BitSet &bs);
0138 
0139     /// Check if all bit are set to 1
0140     bool allOn() const;
0141     bool allOff() const;
0142 
0143     /**
0144      * Check for equality of bitsets
0145      * @param bs BitSet to compare
0146      * @return true if equal
0147      */
0148     bool operator==(const BitSet &bs);
0149 
0150     /**
0151      * Opposite of operator ==
0152      */
0153     bool operator!=(const BitSet &bs)
0154     {
0155         return !operator==(bs);
0156     }
0157 
0158     static BitSet null;
0159 };
0160 
0161 inline bool BitSet::get(quint32 i) const
0162 {
0163     if (i >= num_bits)
0164         return false;
0165 
0166     quint32 byte = i / 8;
0167     quint32 bit = i % 8;
0168     quint8 b = data[byte] & (0x01 << (7 - bit));
0169     return b != 0x00;
0170 }
0171 
0172 inline void BitSet::set(quint32 i, bool on)
0173 {
0174     if (i >= num_bits)
0175         return;
0176 
0177     quint32 byte = i / 8;
0178     quint32 bit = i % 8;
0179     if (on && !get(i)) {
0180         num_on++;
0181         data[byte] |= (0x01 << (7 - bit));
0182     } else if (!on && get(i)) {
0183         num_on--;
0184         quint8 b = (0x01 << (7 - bit));
0185         data[byte] &= (~b);
0186     }
0187 }
0188 
0189 inline void BitSet::setRange(quint32 start, quint32 end, bool value)
0190 {
0191     if ((start >= num_bits) || (end >= num_bits)) {
0192         return;
0193     }
0194 
0195     for (quint32 i = start; i <= end; ++i) {
0196         set(i, value);
0197     }
0198 }
0199 
0200 #endif