Beispiel #1
0
void SmartBuffer::InheritFixups( const SmartBufferPtr& buffer, u32 offset )
{
    // inherit all the incoming fixups
    if ( !buffer->GetIncomingFixups().Empty() )
    {
        // first we copy the incoming fixups, since we are messing with that map 
        S_DumbBufferLocation incoming_fixup_copy = buffer->GetIncomingFixups();

        S_DumbBufferLocation::Iterator itr = incoming_fixup_copy.Begin();
        S_DumbBufferLocation::Iterator end = incoming_fixup_copy.End();
        for( ; itr != end; ++itr )
        {
            // this is the old incoming fixup data
            DumbBufferLocation source_location = (*itr);

            // get the target location from the source buffer
            M_OffsetToFixup::iterator i = source_location.second->m_OutgoingFixups.find( source_location.first );
            HELIUM_ASSERT( i != source_location.second->m_OutgoingFixups.end() );

            // get a pointer to the fixup
            FixupPtr fixup = (*i).second;

            // get the previous destination, we know this fixup must have one or else there 
            // wouldn't be an incoming entry for it
            BufferLocation old_destination;
            bool found_destination = fixup->GetDestination( old_destination );
            HELIUM_ASSERT( found_destination && old_destination.second == buffer );

            // null out the old fixup
            AddFixup( source_location, NULL );

            // now change the fixup to have the right Helium::SmartPtr
            BufferLocation new_destination (old_destination.first + offset, this);
            fixup->ChangeDestination( new_destination );

            // optimization just incase this fixup is completely internal to buffer
            if ( source_location.second == buffer.Ptr() )
            {
                source_location.first  += offset;
                source_location.second  = this;
            }

            // restore the fixup with the correct destination
            AddFixup( source_location, fixup );
        }
    }

    // inherit all the outgoing fixups from the buffer
    if ( !buffer->m_OutgoingFixups.empty() )
    {
        M_OffsetToFixup outgoing_fixups_copy = buffer->m_OutgoingFixups;

        SmartBuffer::M_OffsetToFixup::const_iterator itr = outgoing_fixups_copy.begin();
        SmartBuffer::M_OffsetToFixup::const_iterator end = outgoing_fixups_copy.end();
        for( ; itr != end; ++itr )
        {
            // get a pointer to the fixup
            FixupPtr fixup = (*itr).second;

            // first remove the old fixup
            DumbBufferLocation old_source_location ( (*itr).first, buffer );
            AddFixup( old_source_location, NULL );

            // we need to offset the previous fixup by the correct offset in the current buffer
            DumbBufferLocation new_source_location ( offset + (*itr).first, this );
            AddFixup( new_source_location, fixup );
        }
    }
}