mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 04:00:37 +00:00
84 lines
3.8 KiB
Python
84 lines
3.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
import binascii
|
||
|
import sys
|
||
|
import os
|
||
|
import argparse
|
||
|
|
||
|
autogenerated_notice = """/*
|
||
|
* This file is autogenerated by bin2array.py
|
||
|
*/
|
||
|
"""
|
||
|
|
||
|
def make_sublist_group(lst: list, grp: int) -> list:
|
||
|
"""
|
||
|
Group list elements into sublists.
|
||
|
make_sublist_group([1, 2, 3, 4, 5, 6, 7], 3) = [[1, 2, 3], [4, 5, 6], 7]
|
||
|
"""
|
||
|
return [lst[i:i+grp] for i in range(0, len(lst), grp)]
|
||
|
|
||
|
def generate_c_array_data(bindata: bytes, element_prefix: str, element_size: int, element_suffix: str, newline_value: str, newline_after: int, element_separator: str):
|
||
|
"""
|
||
|
Generate the contents of a C array
|
||
|
"""
|
||
|
hexstr = binascii.hexlify(bindata).decode("UTF-8")
|
||
|
array = []
|
||
|
for i in range(0, len(hexstr), 2 * element_size):
|
||
|
array += [element_prefix + hexstr[i:i + 2 * element_size] + element_suffix]
|
||
|
|
||
|
if newline_after:
|
||
|
array = make_sublist_group(array, newline_after)
|
||
|
else:
|
||
|
array = [array,]
|
||
|
|
||
|
return newline_value.join([element_separator.join(e) + element_separator for e in array])
|
||
|
|
||
|
def decorate_c_array_data (hexdata: str, var_name: str, var_type: str, newline_value: str):
|
||
|
ret = var_type + " " + var_name + "[] = {" + newline_value
|
||
|
ret += hexdata + newline_value
|
||
|
ret += "};" + newline_value
|
||
|
return ret
|
||
|
|
||
|
def main(args):
|
||
|
parser = argparse.ArgumentParser(description='Convert binary file to C-style array initializer.')
|
||
|
parser.add_argument("-i", "--input", help="the file to be converted")
|
||
|
parser.add_argument("--output", help="c source file location")
|
||
|
parser.add_argument("--header-output", help="c header file location")
|
||
|
parser.add_argument("--linebreak", type=int, help="add linebreak after every N element")
|
||
|
parser.add_argument("--linebreak-value", default="\n", help="use what sequence to break lines, defaults to \"\\n\"")
|
||
|
parser.add_argument("--separator", default=", ", help="use what to separate elements, defaults to \", \"")
|
||
|
parser.add_argument("--array-name", default="array_data", help="name of the resulting array")
|
||
|
parser.add_argument("--element-type", default="char", help="C type for the array")
|
||
|
parser.add_argument("--element-size", type=int, default=1, help="how many bytes per element")
|
||
|
parser.add_argument("--element-prefix", default="0x", help="string to be added to the head of element, defaults to \"0x\"")
|
||
|
parser.add_argument("--element-suffix", default="", help="string to be added to the tail of element, defaults to none")
|
||
|
parser.add_argument("--c-include", help="header to include")
|
||
|
args = parser.parse_args(args)
|
||
|
|
||
|
with open(args.input, 'rb') as f:
|
||
|
file_content = f.read()
|
||
|
|
||
|
# don't deal with unaligned content
|
||
|
assert len(file_content) % args.element_size == 0
|
||
|
|
||
|
# get a relative path from the source file to the header to use in an #include
|
||
|
source_to_header = os.path.relpath (os.path.dirname(args.header_output), os.path.dirname (args.output))
|
||
|
|
||
|
ret = autogenerated_notice
|
||
|
ret += "#include \"" + os.path.join (source_to_header, os.path.basename (args.header_output)) + "\"" + args.linebreak_value
|
||
|
|
||
|
ret += decorate_c_array_data (generate_c_array_data (file_content, args.element_prefix, args.element_size, args.element_suffix, args.linebreak_value, args.linebreak, args.separator), args.array_name, args.element_type, args.linebreak_value)
|
||
|
|
||
|
with open (args.output, 'w') as f:
|
||
|
f.write (ret)
|
||
|
|
||
|
# write companion header
|
||
|
with open(args.header_output, 'w') as f:
|
||
|
f.write (autogenerated_notice)
|
||
|
if args.c_include:
|
||
|
f.write ("#include <" + args.c_include + ">" + args.linebreak_value)
|
||
|
f.write ("extern " + args.element_type + " " + args.array_name + "[];" + args.linebreak_value)
|
||
|
f.write ("#define " + args.array_name + "_size " + str(len(file_content) // args.element_size))
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
sys.exit(main(sys.argv[1:]))
|