Skip to content

Instantly share code, notes, and snippets.

@carlos-jenkins
Created September 29, 2016 01:37
Show Gist options
  • Save carlos-jenkins/e257e87b5cdc5910470629b4af78241a to your computer and use it in GitHub Desktop.
Save carlos-jenkins/e257e87b5cdc5910470629b4af78241a to your computer and use it in GitHub Desktop.
pybin2h is a tool for converting binary data to a C-style uchar array for compiling straight into C/C++ code written in Python 3.
#!/usr/bin/env python3
"""
pybin2h is a tool for converting binary data to a C-style uchar array for
compiling straight into C/C++ code written in Python 3.
"""
from itertools import islice
__version__ = '0.1.0'
def chunk(it, size):
"""
Group elements of an iterable in chunk of given size.
::
>>> list(chunk([1, 2, 3, 4, 5, 6, 7, 8], 3))
[(1, 2, 3), (4, 5, 6), (7, 8)]
:param iter it: Iterable to iterate on.
:param int size: Size of the chunks to group the elements of the iterable.
:rtype: A generator that will create the list of chunks.
"""
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())
def parse_args(argv=None):
"""
Argument parsing routine.
:param list argv: A list of argument strings.
:return: A parsed and verified arguments namespace.
:rtype: :py:class:`argparse.Namespace`
"""
from argparse import ArgumentParser
parser = ArgumentParser(
description=(
'Interprets any file as plain binary data and dumps to a '
'raw C/C++ array.'
)
)
parser.add_argument(
'--version',
action='version',
version='pybin2h v{}'.format(__version__)
)
parser.add_argument(
'--indent',
default=4, type=int,
help='Number of spaces to ident the output'
)
parser.add_argument(
'--split',
default=80, type=int,
help='Split at column'
)
parser.add_argument(
'--identifier',
default='uint8_t bindata[]',
help='Identifier of the array'
)
parser.add_argument(
'binary',
help='Binary file to convert'
)
args = parser.parse_args(argv)
# Assert that at least one column of bytes can go in
assert args.indent < (args.split - 5)
return args
def main():
# Read binary file and build list of hex strings
args = parse_args()
with open(args.binary, 'rb') as fd:
hex_bytes = ['0x{:02X}'.format(byte) for byte in fd.read()]
# Determine line formatting and groups
line_format = ' ' * args.indent + '{},'
groups = (args.split - args.indent + 1) // 6
lines = [
line_format.format(', '.join(line))
for line in chunk(hex_bytes, groups)
]
# Print output
if args.identifier:
print('{} = {{'.format(args.identifier))
print('\n'.join(lines))
if args.identifier:
print('};')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment