23enum record_type_e { DATA, END_OF_FILE, EXTENDED_SEGMENT_ADDRESS, START_SEGMENT_ADDRESS, EXTENDED_LINEAR_ADDRESS, START_LINEAR_ADDRESS };
41bool ihex_parser::parse(std::istream& is, std::function<
bool(uint64_t, uint64_t,
const uint8_t*)> cb) {
45 uint16_t address_lo{0};
46 uint16_t address_hi{0};
47 std::array<uint8_t, IHEX_DATA_SIZE> data;
48 unsigned data_size_in_nibble{0};
49 uint8_t byte_count{0};
50 uint8_t record_type{DATA};
51 uint8_t calculated_cs{0};
52 uint8_t saved_high_nibble{0};
53 bool save_high_nibble{
true};
54 bool ex_segment_addr_mode{
false};
60 if((i = hex2dec(c)) == INVALID_HEX_CHAR)
62 if(state <= CHECKSUM_1_STATE) {
64 saved_high_nibble = i;
66 calculated_cs += (saved_high_nibble << 4) | i;
67 save_high_nibble = !save_high_nibble;
71 case START_CODE_STATE:
73 save_high_nibble =
true;
74 if(c ==
'\r' || c ==
'\n') {
80 memset(data.data(), 0, data.size());
81 data_size_in_nibble = 0;
87 case BYTE_COUNT_0_STATE:
88 case BYTE_COUNT_1_STATE:
89 byte_count = (byte_count << 4) | i;
96 address_lo = ((address_lo << 4) | i);
99 case RECORD_TYPE_0_STATE:
104 case RECORD_TYPE_1_STATE:
105 if(i > START_LINEAR_ADDRESS)
108 if(byte_count == 0) {
109 state = CHECKSUM_0_STATE;
110 }
else if(byte_count >
sizeof(data))
116 uint8_t b_index = data_size_in_nibble / 2;
117 data[b_index] = (data[b_index] << 4) | i;
119 ++data_size_in_nibble;
120 if((data_size_in_nibble / 2) >= byte_count)
124 case CHECKSUM_0_STATE:
127 case CHECKSUM_1_STATE:
128 if((byte_count << 1) != data_size_in_nibble)
130 if(calculated_cs != 0x00)
132 if(record_type == EXTENDED_SEGMENT_ADDRESS) {
133 address_hi = ((uint16_t)data[0] << 8) | (data[1]);
134 ex_segment_addr_mode =
true;
135 }
else if(record_type == EXTENDED_LINEAR_ADDRESS) {
136 address_hi = ((uint16_t)data[0] << 8) | (data[1]);
137 ex_segment_addr_mode =
false;
138 }
else if(record_type == DATA && cb) {
139 uint64_t address = ex_segment_addr_mode ? (
static_cast<uint32_t
>(address_hi) << 4) +
static_cast<uint32_t
>(address_lo)
140 : (
static_cast<uint32_t
>(address_hi) << 16) |
static_cast<uint32_t
>(address_lo);
141 if(!cb(address, data_size_in_nibble >> 1, data.data()))
144 state = START_CODE_STATE;
static bool parse(std::istream &, std::function< bool(uint64_t, uint64_t, const uint8_t *)>)
Parses an IHEX file from the given input stream and invokes a callback function for each data record ...