From 469bbcf0701e1eb8a6670c23145b0da87357e178 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 25 Mar 2012 20:00:08 +0000 Subject: Code is all reorganized. We're about ready to release. I should write up a little explenation of the arrangement. --- src/unstable/bitstring.cpp | 479 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 src/unstable/bitstring.cpp (limited to 'src/unstable/bitstring.cpp') diff --git a/src/unstable/bitstring.cpp b/src/unstable/bitstring.cpp new file mode 100644 index 0000000..bdd1bc2 --- /dev/null +++ b/src/unstable/bitstring.cpp @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2007-2011 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/bitstring.h" +#include +#include +#include + +#include "bu/exceptionbase.h" + +#ifdef _WIN32 +#define random() rand() +#endif + +#define bitsToBytes( iBits ) (((iBits/8)+((iBits%8)?(1):(0)))); + +Bu::BitString::BitString() +{ + caData = NULL; + cTopByteMask = 0; + iBits = iBytes = 0; +} + +Bu::BitString::BitString( const Bu::BitString &xSrc ) +{ + iBits = xSrc.iBits; + iBytes = xSrc.iBytes; + cTopByteMask = xSrc.cTopByteMask; + caData = new unsigned char[iBytes]; + memcpy( caData, xSrc.caData, iBytes ); + + fixup(); +} + +Bu::BitString::BitString( long iNewBits, bool bFillRandomly ) +{ + long j; + iBits = iNewBits; + iBytes = bitsToBytes( iNewBits );//(iNewBits/8)+((iNewBits%8)?(1):(0)); + caData = new unsigned char[iBytes]; + + setMask(); + + if( bFillRandomly ) + { + // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so + // I'll just use the low order byte) + for( j = 0; j < iBytes; j++ ) + { + caData[j] = (unsigned char)(random() & 0xFF); + } + } + else + { + clear(); + } + + fixup(); +} + +Bu::BitString::~BitString() +{ + if( caData != NULL ) delete[] caData; +} + +Bu::BitString &Bu::BitString::operator=( const Bu::BitString &xSrc ) +{ + if( caData != NULL ) + { + delete[] caData; + } + iBits = xSrc.iBits; + iBytes = xSrc.iBytes; + cTopByteMask = xSrc.cTopByteMask; + caData = new unsigned char[iBytes]; + memcpy( caData, xSrc.caData, iBytes ); + + fixup(); + + return *this; +} + +Bu::BitString Bu::BitString::operator~() +{ + Bu::BitString xRet( *this ); + + for( int j = 0; j < xRet.iBytes; j++ ) + { + xRet.caData[j] = ~xRet.caData[j]; + } + + xRet.fixup(); + + return xRet; +} + +Bu::BitString Bu::BitString::operator<<( const long iAmt ) +{ + if( iAmt == 0 ) + { + return (*this); + } + //int iByteShift = iAmt/8; + + Bu::BitString xSub( getSize() ); + + long shft = (iAmt%8); + long base = (iAmt/8); + unsigned char lowmask=0; + for( long j = 0; j < 8-shft; j++ ) + { + lowmask |= (1<>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask)); + } + xSub.fixup(); + + return xSub; +} + +Bu::BitString Bu::BitString::operator>>( const long iAmt ) +{ + if( iAmt == 0 ) + { + return (*this); + } + return (*this); +} + +void Bu::BitString::shiftLeft( long iAmt ) +{ + if( iAmt == 0 ) + { + return; + } + else if( iAmt < 0 ) + { + shiftRight( -iAmt ); + return; + } + + long iByteShift = iAmt/8; + long iBitShift = iAmt%8; + + long j; + for( j = iBytes-1; j >= 0; j-- ) + { + caData[j] = (((j-iByteShift)<0)?(0):((caData[j-iByteShift]<>(8-iBitShift)))); + } + + fixup(); +} + +void Bu::BitString::shiftRight( long iAmt ) +{ + if( iAmt == 0 ) + { + return; + } + else if( iAmt < 0 ) + { + shiftLeft( -iAmt ); + return; + } + + long iByteShift = iAmt/8; + long iBitShift = iAmt%8; + + long j; + for( j = 0; j < iBytes; j++ ) + { + caData[j] = (((j+iByteShift)>iBytes)?(0):((caData[j+iByteShift]>>iBitShift))) | (((j+iByteShift+1)>iBytes)?(0):((caData[j+iByteShift+1]<<(8-iBitShift)))); + } + + fixup(); +} +/* +long Bu::BitString::bitsToBytes( long iBits ) +{ + return (iBits/8)+((iBits%8)?(1):(0)); +} +*/ +void Bu::BitString::fixup() +{ + if( caData != NULL ) + { + caData[iBytes-1] &= cTopByteMask; + } +} + +void Bu::BitString::setBit( long iBit, bool bBitState ) +{ + if( iBit < 0 || iBit >= iBits ) + throw Bu::ExceptionBase("bit out of range: %d in (0-%d)", iBit, iBits ); + if( bBitState ) + { + caData[iBit/8] |= (1<<(iBit%8)); + } + else + { + caData[iBit/8] &= ~(1<<(iBit%8)); + } +} + +void Bu::BitString::flipBit( long iBit ) +{ + caData[iBit/8] ^= (1<<(iBit%8)); +} + +bool Bu::BitString::getBit( long iBit ) +{ + if( iBit >= iBits || iBit < 0 ) return false; + if( (caData[iBit/8] & (1<<(iBit%8))) == 0 ) + { + return false; + } + return true; +} + +long Bu::BitString::getBitLength() +{ + return iBits; +} + +long Bu::BitString::getSize() +{ + return iBits; +} + +class Bu::BitString Bu::BitString::getSubString( long iLower, long iUpper ) +{ + if( iUpper == 0 || iUpper < iLower ) iUpper = iBits; + + Bu::BitString xSub( iUpper-iLower+1 ); + + long shft = (iLower%8); + long base = (iLower/8); + unsigned char lowmask=0; + for( long j = 0; j < 8-shft; j++ ) + { + lowmask |= (1<>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask)); + } + xSub.fixup(); + + return xSub; +} + +long Bu::BitString::toLong( long iStart, long iSize ) +{ + if( iSize < 1 ) iSize = 1; + if( iSize > 32 ) iSize = 32; + if( iStart < 0 ) return 0; + if( iStart+iSize > getSize() ) return 0; + + Bu::BitString tmpo; + tmpo = getSubString( iStart, iStart+iSize-1 ); + long x = *((long *)tmpo.caData); + + return x; +} +/* +std::string Bu::BitString::toString( bool bAddSpacers ) +{ + long iSz = iBits; + if( bAddSpacers ) + { + iSz += (iBits/8); + if( iBits%8 == 0 ) iSz--; + } + std::string xStr; + + int bw=0; + int of=0; + for( int j = iBits-1; j >= 0; j-- ) + { + if( getBit( j ) ) + { + xStr += '1'; + } + else + { + xStr += '0'; + } + + if( bAddSpacers ) + { + bw++; + if( bw >= 8 && j < iBits-1 ) + { + bw = 0; + of++; + xStr += ' '; + } + } + } + + return xStr; +} +*/ +void Bu::BitString::clear() +{ + if( caData != NULL ) + { + memset( caData, 0, iBytes ); + } +} + +bool Bu::BitString::setBitLength( long iLength, bool bClear ) +{ + return setSize( iLength, bClear ); +} + +bool Bu::BitString::setSize( long iLength, bool bClear ) +{ + // First, if there's nothing, then allocate an empty one. + if( caData == NULL ) + { + iBits = iLength; + iBytes = bitsToBytes( iLength ); + caData = new unsigned char[iBytes]; + memset( caData, 0, iBytes ); + return true; + } + + // If the new length is the same as the old, don't do anything, but do + // check to see if we should still clear the data. + if( iBits != iLength ) + { + // Ok, we are changing the number if bits, but are we changing the + // number of bytes? + long iNewBytes = bitsToBytes( iLength ); + if( iBytes == iNewBytes ) + { + // No? That makes life easier + iBits = iLength; + setMask(); + if( bClear ) + { + clear(); + } + } + else + { + // Ok, reallocate and copy... + iBits = iLength; +// long iNewBytes = bitsToBytes( iLength ); + if( bClear ) + { + delete[] caData; + caData = new unsigned char[iNewBytes]; + memset( caData, 0, iNewBytes ); + } + else + { + unsigned char *tmp = caData; + caData = new unsigned char[iNewBytes]; + if( iNewBytes < iBytes ) + { + memcpy( caData, tmp, iNewBytes ); + } + else + { + memcpy( caData, tmp, iBytes ); + } + delete[] tmp; + } + iBytes = iNewBytes; + + setMask(); + } + + } + else if( bClear ) + { + clear(); + } + + return true; +} + +void Bu::BitString::setMask() +{ + // This can either mean that there are a multiple of eight bits or + // zero, if there are zero you're an idiot (zero can't happen, because + // we would allocate an extra byte and never use it) + if( (iBits%8 == 0) ) + { + cTopByteMask = 0xFF; + } + else + { + cTopByteMask = 0; + for( long j = 0; j < (iBits%8); j++ ) + { + cTopByteMask |= (1<= 0; j-- ) + { + if( getBit( j ) ) + { + return j; + } + } + + return -1; +} + +Bu::String Bu::BitString::toString() +{ + Bu::String sRet; + for( int j = iBits-1; j >= 0; j-- ) + sRet.append( getBit( j )?'1':'0' ); + return sRet; +} + +/* +bool Bu::BitString::writeToFile( FILE *fh ) +{ + fwrite( &iBits, sizeof(long), 1, fh ); + fwrite( caData, sizeof(char), iBytes, fh ); + + return true; +} + +bool Bu::BitString::readFromFile( FILE *fh ) +{ + fread( &iBits, sizeof(long), 1, fh ); + + iBytes = bitsToBytes( iBits ); + if( caData ) delete[] caData; + caData = new unsigned char[iBytes]; + + fread( caData, sizeof(char), iBytes, fh ); + + setMask(); + + fixup(); + + return true; +}*/ -- cgit v1.2.3