This function formats raw buffer output in manner as Wireshark and many others does:
0x00: 68 65 6C 6C 6F 20 77 6F 72 6C 64 02 6B 68 67 61 |hello world.khga|
0x10: 76 73 64 20 0B 20 0A 05 58 61 73 6A 68 6C 61 73 |vsd . ..Xasjhlas|
0x20: 62 64 61 73 20 6A 61 6C 73 6A 64 6E 13 20 20 30 |bdas jalsjdn. 0|
0x30: 31 32 33 34 35 36 37 38 39 |123456789 |
Please review and assess code quality.
std::string format_hex_payload(const char* payload, size_t payload_len)
{
const char line_placeholder[] = "0x00: | |";
size_t number_of_lines = payload_len / 16 + (payload_len%16 > 0);
size_t sizeof_output = sizeof line_placeholder * number_of_lines;
char *output = (char*)alloca(sizeof_output); //POSSIBLE REIMPL USE C++RVO std::string out; out.reserve(sizeof_output);
char *pout = output; //POSSIBLE REIMPL char *pout = out.data();
const char *p = payload;
const char *const end = payload + payload_len;
size_t ascii_offset = strchr(line_placeholder,'|') - line_placeholder + 1; //could be calculated at compile time
unsigned short offset = 0;
for(unsigned l=0; l < number_of_lines; l++, offset+=16)
{
char* pline_begin = pout;
char* pline = pout;
strcpy(pline,line_placeholder);
pline += sprintf(pline, "0x%02X: ", offset);
for(unsigned i=0; i<16 && p < end; ++i, ++p){
pline += sprintf(pline, "%02X ", *p);
*(pline_begin+ascii_offset+i) = isprint(*p) ? *p : '.';
}
*pline=' ';
pout += sizeof line_placeholder; // move pointer to next line
pout[-1] = '\n';
}
pout[-1] = '\0';
assert(pout == output + sizeof_output); // sanity check
return output; //POSSIBLE REIMPL return out;
}