void BitString::setString( const BitString & i_sStr, uint32_t i_sPos, uint32_t i_sLen, uint32_t i_dPos ) { // Ensure the source parameters are valid. PRDF_ASSERT( nullptr != i_sStr.getBufAddr() ); PRDF_ASSERT( 0 < i_sLen ); // at least one bit to copy PRDF_ASSERT( i_sPos + i_sLen <= i_sStr.getBitLen() ); // Ensure the destination has at least one bit available to copy. PRDF_ASSERT( nullptr != getBufAddr() ); PRDF_ASSERT( i_dPos < getBitLen() ); // If the source length is greater than the destination length than the // extra source bits are ignored. uint32_t actLen = std::min( i_sLen, getBitLen() - i_dPos ); // The bit strings may be in overlapping memory spaces. So we need to copy // the data in the correct direction to prevent overlapping. uint32_t sRelOffset = 0, dRelOffset = 0; CPU_WORD * sRelAddr = i_sStr.getRelativePosition( sRelOffset, i_sPos ); CPU_WORD * dRelAddr = getRelativePosition( dRelOffset, i_dPos ); // Copy the data. if ( (dRelAddr == sRelAddr) && (dRelOffset == sRelOffset) ) { // Do nothing. The source and destination are the same. } else if ( (dRelAddr < sRelAddr) || ((dRelAddr == sRelAddr) && (dRelOffset < sRelOffset)) ) { // Copy the data forward. for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD value = i_sStr.getField( i_sPos + pos, len ); setField( i_dPos + pos, len, value ); } } else // Copy the data backwards. { // Get the first position of the last chunk (CPU_WORD aligned). uint32_t lastPos = ((actLen-1) / CPU_WORD_BIT_LEN) * CPU_WORD_BIT_LEN; // Start with the last chunk and work backwards. for ( int32_t pos = lastPos; 0 <= pos; pos -= CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD value = i_sStr.getField( i_sPos + pos, len ); setField( i_dPos + pos, len, value ); } } }
void BitString::setPattern( uint32_t i_sPos, uint32_t i_sLen, CPU_WORD i_pattern, uint32_t i_pLen ) { PRDF_ASSERT(nullptr != getBufAddr()); // must to have a valid address PRDF_ASSERT(0 < i_sLen); // must have at least one bit PRDF_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range PRDF_ASSERT(0 < i_pLen); // must have at least one bit PRDF_ASSERT(i_pLen <= CPU_WORD_BIT_LEN); // i_pLen length must be valid // Get a bit string for the pattern subset (right justified). BitString bso ( i_pLen, &i_pattern, CPU_WORD_BIT_LEN - i_pLen ); // Iterate the range in chunks the size of i_pLen. uint32_t endPos = i_sPos + i_sLen; for ( uint32_t pos = i_sPos; pos < endPos; pos += i_pLen ) { // The true chunk size is either i_pLen or the leftovers at the end. uint32_t len = std::min( i_pLen, endPos - pos ); // Get this chunk's pattern value, truncate (left justified) if needed. CPU_WORD pattern = bso.getField( 0, len ); // Set the pattern in this string. setField( pos, len, pattern ); } }
bool BitString::isEqual( const BitString & i_str ) const { if ( getBitLen() != i_str.getBitLen() ) return false; // size not equal for ( uint32_t pos = 0; pos < getBitLen(); pos += CPU_WORD_BIT_LEN ) { uint32_t len = std::min( getBitLen() - pos, CPU_WORD_BIT_LEN ); if ( getField(pos, len) != i_str.getField(pos, len) ) return false; // bit strings do not match } return true; // bit strings match }
void BitString::maskString( const BitString & i_mask ) { // Get the length of the smallest string. uint32_t actLen = std::min( getBitLen(), i_mask.getBitLen() ); for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD dVal = getField( pos, len ); CPU_WORD sVal = i_mask.getField( pos, len ); setField( pos, len, dVal & ~sVal ); } }
BitStringBuffer BitString::operator|( const BitString & i_bs ) const { // Get the length of the smallest string. uint32_t actLen = std::min( getBitLen(), i_bs.getBitLen() ); BitStringBuffer bsb( actLen ); for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD dVal = getField( pos, len ); CPU_WORD sVal = i_bs.getField( pos, len ); bsb.setField( pos, len, dVal | sVal ); } return bsb; }