File indexing completed on 2025-01-05 04:37:29
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef BTBITSET_H 0007 #define BTBITSET_H 0008 0009 #include "constants.h" 0010 #include <ktorrent_export.h> 0011 0012 namespace bt 0013 { 0014 /** 0015 * @author Joris Guisson 0016 * @brief Simple implementation of a BitSet 0017 * 0018 * Simple implementation of a BitSet, can only turn on and off bits. 0019 * BitSet's are used to indicate which chunks we have or not. 0020 */ 0021 class KTORRENT_EXPORT BitSet 0022 { 0023 Uint32 num_bits, num_bytes; 0024 Uint8 *data; 0025 Uint32 num_on; 0026 0027 public: 0028 /** 0029 * Constructor. 0030 * @param num_bits The number of bits 0031 */ 0032 BitSet(Uint32 num_bits = 8); 0033 0034 /** 0035 * Manually set data. 0036 * @param data The data 0037 * @param num_bits The number of bits 0038 */ 0039 BitSet(const Uint8 *data, Uint32 num_bits); 0040 0041 /** 0042 * Copy constructor. 0043 * @param bs BitSet to copy 0044 * @return 0045 */ 0046 BitSet(const BitSet &bs); 0047 virtual ~BitSet(); 0048 0049 /// See if the BitSet is null 0050 bool isNull() const 0051 { 0052 return num_bits == 0; 0053 } 0054 0055 /** 0056 * Get the value of a bit, false means 0, true 1. 0057 * @param i Index of Bit 0058 */ 0059 bool get(Uint32 i) const; 0060 0061 /** 0062 * Set the value of a bit, false means 0, true 1. 0063 * @param i Index of Bit 0064 * @param on False means 0, true 1 0065 */ 0066 void set(Uint32 i, bool on); 0067 0068 /// Set all bits on or off 0069 void setAll(bool on); 0070 0071 Uint32 getNumBytes() const 0072 { 0073 return num_bytes; 0074 } 0075 Uint32 getNumBits() const 0076 { 0077 return num_bits; 0078 } 0079 const Uint8 *getData() const 0080 { 0081 return data; 0082 } 0083 Uint8 *getData() 0084 { 0085 return data; 0086 } 0087 0088 /// Get the number of on bits 0089 Uint32 numOnBits() const 0090 { 0091 return num_on; 0092 } 0093 0094 /** 0095 * Set all bits to 0 0096 */ 0097 void clear(); 0098 0099 /** 0100 * invert this BitSet 0101 */ 0102 void invert(); 0103 0104 /** 0105 * or this BitSet with another. 0106 * @param other The other BitSet 0107 */ 0108 void orBitSet(const BitSet &other); 0109 0110 /** 0111 * and this BitSet with another. 0112 * @param other The other BitSet 0113 */ 0114 void andBitSet(const BitSet &other); 0115 0116 /** 0117 * see if this BitSet includes another. 0118 * @param other The other BitSet 0119 */ 0120 bool includesBitSet(const BitSet &other) const; 0121 0122 /** 0123 * Assignment operator. 0124 * @param bs BitSet to copy 0125 * @return *this 0126 */ 0127 BitSet &operator=(const BitSet &bs); 0128 0129 /** 0130 * Subtraction assignment operator. 0131 * @param bs BitSet to copy and subtract from this one 0132 * @return *this 0133 */ 0134 BitSet &operator-=(const BitSet &bs); 0135 0136 /** 0137 * Subtraction operator. 0138 * @param bs BitSet to subtract from this one 0139 * @return difference 0140 */ 0141 BitSet operator-(const BitSet &bs) const; 0142 0143 /// Check if all bit are set to 1 0144 bool allOn() const; 0145 0146 /** 0147 * Check for equality of bitsets 0148 * @param bs BitSet to compare 0149 * @return true if equal 0150 */ 0151 bool operator==(const BitSet &bs) const; 0152 0153 /** 0154 * Opposite of operator == 0155 */ 0156 bool operator!=(const BitSet &bs) const 0157 { 0158 return !operator==(bs); 0159 } 0160 0161 /** 0162 * Update the number of on bits 0163 */ 0164 void updateNumOnBits(); 0165 0166 static BitSet null; 0167 }; 0168 0169 const Uint8 set_on_lookup[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; 0170 const Uint8 set_off_lookup[8] = {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}; 0171 0172 inline bool BitSet::get(Uint32 i) const 0173 { 0174 if (i >= num_bits) 0175 return false; 0176 // i >> 3 equal to i / 8 0177 // i & 7 equal to i % 8 0178 return (data[i >> 3] & set_on_lookup[i & 7]) != 0; 0179 } 0180 0181 // Fast lookup table to see how many bits are there in a byte 0182 // (macro compacted variant) 0183 static const Uint8 BitCount[256] = { 0184 #define B2(n) n, n + 1, n + 1, n + 2 0185 #define B4(n) B2(n), B2(n + 1), B2(n + 1), B2(n + 2) 0186 #define B6(n) B4(n), B4(n + 1), B4(n + 1), B4(n + 2) 0187 B6(0), 0188 B6(1), 0189 B6(1), 0190 B6(2)}; 0191 0192 inline void BitSet::set(Uint32 i, bool on) 0193 { 0194 if (i >= num_bits) 0195 return; 0196 0197 Uint8 *d = data + (i >> 3); 0198 num_on -= BitCount[*d]; 0199 if (on) { 0200 *d |= set_on_lookup[i & 7]; 0201 } else { 0202 *d &= set_off_lookup[i & 7]; 0203 } 0204 num_on += BitCount[*d]; 0205 } 0206 } 0207 0208 #endif