00001 //---------------------------------------------------------------------------- 00002 /** @file Bitset.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include <sstream> 00007 #include <cstdio> 00008 #include "Bitset.hpp" 00009 00010 using namespace benzene; 00011 00012 //---------------------------------------------------------------------------- 00013 00014 void BitsetUtil::BitsetToBytes(const bitset_t& b, byte* out, int numbits) 00015 { 00016 numbits = ((numbits+7)/8)*8; 00017 assert(numbits <= BITSETSIZE); 00018 00019 for (int i=0; i<numbits; i+=8) { 00020 int c = 0; 00021 for (int j=0; j<8; j++) 00022 c += (b.test(i+j)) ? (1<<j) : 0; 00023 out[i/8] = static_cast<byte>(c); 00024 } 00025 } 00026 00027 bitset_t BitsetUtil::BytesToBitset(const byte* bytes, int numbits) 00028 { 00029 bitset_t ret; 00030 int numbytes = (numbits+7)/8; 00031 for (int i=0; i<numbytes; i++) { 00032 for (int j=0; j<8; j++) { 00033 if (bytes[i] & (1<<j)) 00034 ret.set(i*8 + j); 00035 } 00036 } 00037 return ret; 00038 } 00039 00040 std::string BitsetUtil::BitsetToHex(const bitset_t& b, int numbits) 00041 { 00042 numbits = ((numbits+3)/4)*4; 00043 assert(numbits <= BITSETSIZE); 00044 00045 std::string out; 00046 for (int i=0; i<numbits; i+=4) { 00047 int c = 0; 00048 for (int j=0; j<4; j++) 00049 c += (b.test(i+j)) ? (1<<j) : 0; 00050 00051 char buff[4]; 00052 sprintf(buff, "%x", c); 00053 out += buff; 00054 } 00055 return out; 00056 } 00057 00058 bitset_t BitsetUtil::HexToBitset(const std::string& str) 00059 { 00060 bitset_t out; 00061 for (unsigned i=0; i<str.size(); i++) { 00062 unsigned c; 00063 char buff[4]; 00064 buff[0] = str[i]; 00065 buff[1] = 0; 00066 sscanf(buff, "%x", &c); 00067 for (int j=0; j<4; j++) { 00068 if (c & (1<<j)) 00069 out.set(i*4 + j); 00070 } 00071 } 00072 return out; 00073 } 00074 00075 //---------------------------------------------------------------------------- 00076 00077 bitset_t BitsetUtil::Subtract(const bitset_t& b1, const bitset_t& b2) 00078 { 00079 return (b1 ^ (b1 & b2)); 00080 } 00081 00082 bool BitsetUtil::SubtractIfLeavesAny(bitset_t& removeFrom, 00083 const bitset_t& remove) 00084 { 00085 bitset_t leftover = removeFrom - remove; 00086 if (leftover.any()) { 00087 removeFrom = leftover; 00088 return true; 00089 } 00090 return false; 00091 } 00092 00093 int BitsetUtil::FindSetBit(const bitset_t& b) 00094 { 00095 assert(b.count() == 1); 00096 int ret; 00097 for (ret=0; ret<BITSETSIZE; ret++) { 00098 if (b.test(ret)) 00099 break; 00100 } 00101 return ret; 00102 } 00103 00104 /** @todo merge with FindSetBit()? */ 00105 int BitsetUtil::FirstSetBit(const bitset_t& b) 00106 { 00107 assert(b.any()); 00108 int ret; 00109 for (ret=0; ret<BITSETSIZE; ret++) { 00110 if (b.test(ret)) 00111 break; 00112 } 00113 return ret; 00114 } 00115 //---------------------------------------------------------------------------- 00116 00117 /** @note Must specify the namespace here for some reason. */ 00118 bitset_t benzene::operator-(const bitset_t& b1, const bitset_t& b2) 00119 { 00120 return BitsetUtil::Subtract(b1, b2); 00121 } 00122 00123 //----------------------------------------------------------------------------