2 * File: DataSourceImager.cpp
4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
8 #include "DataSourceImager.h"
12 using namespace elftosb;
14 DataSourceImager::DataSourceImager()
18 m_isBaseAddressSet(false)
22 void DataSourceImager::setBaseAddress(uint32_t address)
24 m_baseAddress = address;
25 m_isBaseAddressSet = true;
28 void DataSourceImager::setFillPattern(uint8_t pattern)
33 void DataSourceImager::reset()
39 m_isBaseAddressSet = false;
42 //! \param dataSource Pointer to an instance of a concrete data source subclass.
44 void DataSourceImager::addDataSource(DataSource * source)
46 unsigned segmentCount = source->getSegmentCount();
48 for (; index < segmentCount; ++index)
50 addDataSegment(source->getSegmentAt(index));
54 //! \param segment The segment to add. May be any type of data segment, including
55 //! a pattern segment.
56 void DataSourceImager::addDataSegment(DataSource::Segment * segment)
58 DataSource::PatternSegment * patternSegment = dynamic_cast<DataSource::PatternSegment*>(segment);
60 unsigned segmentLength = segment->getLength();
61 bool segmentHasLocation = segment->hasNaturalLocation();
62 uint32_t segmentAddress = segment->getBaseAddress();
64 uint8_t * toPtr = NULL;
65 unsigned addressDelta;
68 // If a pattern segment's length is 0 then make it as big as the fill pattern.
69 // This needs to be done before the buffer is adjusted.
70 if (patternSegment && segmentLength == 0)
72 SizedIntegerValue & pattern = patternSegment->getPattern();
73 segmentLength = pattern.getSize();
78 if (segmentHasLocation)
80 // Make sure a base address is set.
81 if (!m_isBaseAddressSet)
83 m_baseAddress = segmentAddress;
84 m_isBaseAddressSet = true;
87 // The segment is located before our buffer's first address.
88 // toPtr is not set in this if, but in the else branch of the next if.
89 // Unless the segment completely overwrite the current data.
90 if (segmentAddress < m_baseAddress)
92 addressDelta = m_baseAddress - segmentAddress;
94 uint8_t * newData = (uint8_t *)malloc(m_length + addressDelta);
95 memcpy(&newData[addressDelta], m_data, m_length);
99 m_length += addressDelta;
100 m_baseAddress = segmentAddress;
103 // This segment is located or extends outside of our buffer.
104 if (segmentAddress + segmentLength > m_baseAddress + m_length)
106 newLength = segmentAddress + segmentLength - m_baseAddress;
108 m_data = (uint8_t *)realloc(m_data, newLength);
110 // Clear any bytes between the old data and the new segment.
111 addressDelta = segmentAddress - (m_baseAddress + m_length);
114 memset(m_data + m_length, 0, addressDelta);
117 toPtr = m_data + (segmentAddress - m_baseAddress);
118 m_length = newLength;
122 toPtr = m_data + (segmentAddress - m_baseAddress);
125 // Segment has no natural location, so just append it to the end of our buffer.
128 newLength = m_length + segmentLength;
129 m_data = (uint8_t *)realloc(m_data, newLength);
130 toPtr = m_data + m_length;
131 m_length = newLength;
135 // A loop is used because getData() may fill in less than the requested
136 // number of bytes per call.
138 while (offset < segmentLength)
140 offset += segment->getData(offset, segmentLength - offset, toPtr + offset);