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 ); } } }