-
-
Save lioncash/d0e1fd8f8390f2462ba4361ed0236f16 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import io | |
import ntpath | |
import os | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-ns", "--namespace", type=str, help="An optional namespace to enclose the data within.") | |
parser.add_argument("--std_array", action="store_true", help="Use std::array as the array type enclosing the output data.") | |
parser.add_argument("files", nargs="+", help="List of files to create output files for.") | |
args = parser.parse_args() | |
# Takes a sequence and subdivides it into n-sized tuples | |
# if the last tuple doesn't have n elements to fit within it | |
# then it is not an n-sized tuple. | |
# | |
# e.g. Given seq = [0, 1, 2, 3, 4, 5, 6, 7] | |
# group(seq, 4) will be a generator that returns: | |
# (0, 1, 2, 3) and (4, 5, 6, 7) | |
# | |
# but group(seq, 5) will be a generator that returns: | |
# (0, 1, 2, 3, 4) and (5, 6, 7) | |
# | |
def group(lst, n): | |
for i in range(0, len(lst), n): | |
val = lst[i:i+n] | |
if len(val) <= n: | |
yield tuple(val) | |
def make_header_string(file_name: str, file_size: int): | |
header = "#pragma once\n\n" | |
if args.std_array: | |
header += "#include <array>\n\n" | |
if args.namespace is not None: | |
header += f"namespace {args.namespace} {{\n\n" | |
name, ext = os.path.splitext(ntpath.basename(file_name)) | |
if args.std_array: | |
header += f"extern const std::array<unsigned char, {file_size}> {name};\n\n" | |
else: | |
header += f"extern const unsigned char {name}[{file_size}];\n\n" | |
if args.namespace is not None: | |
header += f"}} // namespace {args.namespace}\n" | |
return header | |
def make_and_write_source_file_string(source: io.IOBase, file_name: str, file_size: int): | |
source.write(f"#include \"{file_name}.h\"\n\n") | |
if args.namespace is not None: | |
source.write(f"namespace {args.namespace} {{\n\n") | |
name, ext = os.path.splitext(ntpath.basename(file_name)) | |
if args.std_array: | |
source.write(f"const std::array<unsigned char, {file_size}> {name}{{{{\n") | |
else: | |
source.write(f"const unsigned char {name}[{file_size}] = {{\n") | |
with open(file_name, mode="rb", buffering=8192) as binary: | |
data = binary.read() | |
while data: | |
gr = group(data, 12) | |
for entry in gr: | |
source.write(" ") | |
for e in entry: | |
source.write(f"0x{e:02x},") | |
source.write("\n") | |
data = binary.read() | |
if args.std_array: | |
source.write("}};\n\n") | |
else: | |
source.write("};\n\n") | |
if args.namespace is not None: | |
source.write(f"}} // namespace {args.namespace}\n") | |
def write_header_file(file_name: str, file_size: int): | |
with open("{}.h".format(file_name), "w") as header: | |
header.write(make_header_string(file_name, file_size)) | |
def write_source_file(file_name: str, file_size: int): | |
ext = ".cpp" if args.std_array else ".c" | |
with open(f"{file_name}{ext}", "w") as source: | |
make_and_write_source_file_string(source, file_name, file_size) | |
def convert_file(file_name: str): | |
file_size = os.stat(file_name).st_size | |
write_header_file(file_name, file_size) | |
write_source_file(file_name, file_size) | |
for file_name in args.files: | |
try: | |
convert_file(file_name) | |
except IOError as e: | |
print(f"Unable to open file \"{file}\": {e.strerror}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Examples of running the script:
will produce cpp and h files for all of the files passed to it.