-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbytes_to_cstring.py
54 lines (52 loc) · 1.42 KB
/
bytes_to_cstring.py
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
# Convert python byte array into a C string literal.
# Useful for baking data directly into C executable.
#
# The generated C string is NOT 0 terminated by default.
# If you want 0 termination, append b'\0' at the end of the input.
#
# The generated string literal is close to optimal in terms of
# source code length. It's possible to get it slightly shorter,
# but not in a way that's portable or doesn't produce compiler warnings.
def bytes_to_cstring(name: str, data: bytes, maxwidth: int) -> str:
lines = []
line = ''
prevoct = False
ESCAPE = {
ord('\a'): '\\a',
ord('\a'): '\\a',
ord('\b'): '\\b',
ord('\f'): '\\f',
ord('\n'): '\\n',
ord('\r'): '\\r',
ord('\t'): '\\t',
ord('\v'): '\\v',
ord('\\'): '\\\\',
ord('\"'): '\\"',
}
for byte in data:
if len(line) > maxwidth:
lines.append('\t"'+line+'"')
line = ''
prevoct = False
if byte in ESCAPE:
line += ESCAPE[byte]
prevoct = False
elif ord('0') <= byte <= ord('9'):
if prevoct:
line += '\\%o' % byte
else:
line += chr(byte)
elif ord(' ') <= byte <= ord('~'):
line += chr(byte)
prevoct = False
else:
line += '\\%o' % byte
prevoct = True
if len(line) > 0:
lines.append('\t"'+line+'"')
result = ''
result += 'static const unsigned char '+name+'['+str(len(data))+'] =\n'
result += '\n'.join(lines)+';\n'
return result
TEST = bytes([55, 138, 87, 147, 13, 123, 230, 172, 237, 133])
print(bytes_to_cstring('TEST', TEST, 80))