/*
* File: DataSourceImager.cpp
*
* Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
* See included license file for license details.
*/
//! \param dataSource Pointer to an instance of a concrete data source subclass.
//!
void DataSourceImager::addDataSource(DataSource * source)
{
unsigned segmentCount = source->getSegmentCount();
unsigned index = 0;
for (; index < segmentCount; ++index)
{
addDataSegment(source->getSegmentAt(index));
}
}
//! \param segment The segment to add. May be any type of data segment, including
//! a pattern segment.
void DataSourceImager::addDataSegment(DataSource::Segment * segment)
{
DataSource::PatternSegment * patternSegment = dynamic_cast<DataSource::PatternSegment*>(segment);
// If a pattern segment's length is 0 then make it as big as the fill pattern.
// This needs to be done before the buffer is adjusted.
if (patternSegment && segmentLength == 0)
{
SizedIntegerValue & pattern = patternSegment->getPattern();
segmentLength = pattern.getSize();
}
if (segmentLength)
{
if (segmentHasLocation)
{
// Make sure a base address is set.
if (!m_isBaseAddressSet)
{
m_baseAddress = segmentAddress;
m_isBaseAddressSet = true;
}
// The segment is located before our buffer's first address.
// toPtr is not set in this if, but in the else branch of the next if.
// Unless the segment completely overwrite the current data.
if (segmentAddress < m_baseAddress)
{
addressDelta = m_baseAddress - segmentAddress;
// This segment is located or extends outside of our buffer.
if (segmentAddress + segmentLength > m_baseAddress + m_length)
{
newLength = segmentAddress + segmentLength - m_baseAddress;
m_data = (uint8_t *)realloc(m_data, newLength);
// Clear any bytes between the old data and the new segment.
addressDelta = segmentAddress - (m_baseAddress + m_length);
if (addressDelta)
{
memset(m_data + m_length, 0, addressDelta);
}
toPtr = m_data + (segmentAddress - m_baseAddress);
m_length = newLength;
}
else
{
toPtr = m_data + (segmentAddress - m_baseAddress);
}
}
// Segment has no natural location, so just append it to the end of our buffer.
else
{
newLength = m_length + segmentLength;
m_data = (uint8_t *)realloc(m_data, newLength);
toPtr = m_data + m_length;
m_length = newLength;
}
}
// A loop is used because getData() may fill in less than the requested
// number of bytes per call.
unsigned offset = 0;
while (offset < segmentLength)
{
offset += segment->getData(offset, segmentLength - offset, toPtr + offset);
}
}