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