00001
00044 #include "hexfile.h"
00045 #include <iomanip>
00046 #include <stdexcept>
00047
00048
00049
00051 #define HEXDATARECORDTYPE ( (byte) 0x00 )
00053 #define HEXEOFRECORDTYPE ( (byte) 0x01 )
00054
00055
00056
00057 void HEXRecord::Add( byte data )
00058 {
00059 if( data > 255 ) {
00060 throw std::runtime_error( "Data larger than 255" );
00061 }
00062
00063 m_data.push_back( data );
00064 }
00065
00066
00067
00068 void HEXRecord::Add( std::vector< byte > data )
00069 {
00070 for( size_t idx = 0; idx < data.size(); ++idx ) {
00071 Add( data.at( idx ) );
00072 }
00073 }
00074
00075
00076
00077 void HEXRecord::Print( std::ostream & os ) const
00078 {
00079 if( GetByteCount() > 255 ) {
00080 throw std::runtime_error( "HEX record have more than 255 data bytes" );
00081 }
00082
00083 if( m_address > 65535 ) {
00084 throw std::runtime_error( "HEX record base address exceeds 16 bits" );
00085 }
00086
00087 if( m_address + GetByteCount() > 65536 ) {
00088 throw std::runtime_error( "HEX record data crosses segment boundary" );
00089 }
00090
00091 byte checksum = 0;
00092 checksum += GetByteCount();
00093 checksum += m_address & 0xff;
00094 checksum += (m_address >> 8) & 0xff;
00095 checksum += HEXDATARECORDTYPE;
00096
00097 os << ":" << std::setfill('0') << std::hex
00098 << std::setw(2) << GetByteCount()
00099 << std::setw(2) << ((m_address >> 8) & 0xff)
00100 << std::setw(2) << (m_address & 0xff)
00101 << std::setw(2) << HEXDATARECORDTYPE;
00102
00103 for( size_t idx = 0; idx < GetByteCount(); ++idx ) {
00104 byte data = m_data.at( idx );
00105 os << std::setw(2) << data;
00106 checksum += data;
00107 }
00108
00109 os << std::setw(2) << ((-checksum) & 0xff)
00110 << std::endl;
00111 }
00112
00113
00114
00115 HEXRecord & operator<<( HEXRecord & record, byte data )
00116 {
00117 record.Add( data );
00118 return record;
00119 }
00120
00121
00122
00123 HEXRecord & operator<<( HEXRecord & record, std::vector< byte > data )
00124 {
00125 record.Add( data );
00126 return record;
00127 }
00128
00129
00130
00131 std::ostream & operator<<( std::ostream & os, const HEXRecord & record )
00132 {
00133 record.Print( os );
00134 return os;
00135 }
00136
00137
00138
00139 void HEXFile::Print( std::ostream & os ) const
00140 {
00141 for( size_t idx = 0; idx < m_records.size(); ++idx ) {
00142 os << m_records.at( idx );
00143 }
00144 os << ":00000001ff" << std::endl;
00145 }
00146
00147
00148
00149 HEXFile & operator<<( HEXFile & file, const HEXRecord & record )
00150 {
00151 file.Add( record );
00152 return file;
00153 }
00154
00155
00156
00157 std::ostream & operator<<( std::ostream & os, const HEXFile & file )
00158 {
00159 file.Print( os );
00160 return os;
00161 }
00162