-
Notifications
You must be signed in to change notification settings - Fork 2
/
hexdump_printf.c
75 lines (63 loc) · 1.39 KB
/
hexdump_printf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* print buffer as 'hexdump -C'
* qianfan Zhao
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#define HEXDUMP_PER_LINE 16
#define aligned_length(len, align) (((len) + (align) - 1) / (align) * (align))
void hexdump(const void *buf, size_t sz, unsigned long baseaddr)
{
uint8_t preline[HEXDUMP_PER_LINE];
const uint8_t *blk = buf;
int skip = 0;
for (size_t i = 0; i < sz; i += HEXDUMP_PER_LINE) {
int sz_buster = sz - i;
if (sz_buster > HEXDUMP_PER_LINE)
sz_buster = HEXDUMP_PER_LINE;
if (i != 0 && !memcmp(preline, &blk[i], sz_buster)) {
if (!skip) {
skip = 1;
printf("*\n");
}
continue;
} else {
skip = 0;
}
/* the block's address */
printf("%08lx ", baseaddr + i);
for (size_t n = 0; n < 2; n++) {
for (size_t j = 0; j < HEXDUMP_PER_LINE; j++) {
int overflow = 0;
if (i + j >= sz)
overflow = 1;
switch (n) {
case 0:
if (!overflow)
printf("%02x ", blk[i + j]);
else
printf(" ");
break;
case 1:
if (j == 0)
printf("|");
if (!overflow) {
printf("%c",
isprint(blk[i + j]) ?
blk[i + j] : '.');
} else {
printf(" ");
}
if (j == HEXDUMP_PER_LINE - 1)
printf("|");
break;
}
}
}
memcpy(preline, &blk[i], sz_buster);
printf("\n");
}
printf("%08lx\n", baseaddr + aligned_length(sz, HEXDUMP_PER_LINE));
}