Repository navigation
Expand file tree
/
Copy pathfile2cpp.py
More file actions
99 lines (80 loc) · 3.28 KB
/
Copy pathfile2cpp.py
File metadata and controls
99 lines (80 loc) · 3.28 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import argparse
import os
import re
import sys
def generate_array_name(file_path):
base = os.path.basename(file_path)
name = base.replace(".", "_")
name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
return name
def write_bytes(buf, data, per_line=20):
for i, b in enumerate(data):
if i % per_line == 0:
buf.append(" ")
buf.append(f"0x{b:02X}, ")
if (i + 1) % per_line == 0:
buf.append("\n")
if len(data) % per_line != 0:
buf.append("\n")
def file_to_cpp_array(input_path, output_path, array_name, chunk_size=0):
with open(input_path, "rb") as f:
data = f.read()
buf = []
buf.append("#pragma once\n#include <vector>\n#include <cstring>\n\n")
buf.append(f"size_t {array_name}Len = {len(data)};\n\n")
chunk_count = 1
if chunk_size > 0:
chunk_count = (len(data) + chunk_size - 1) // chunk_size
chunks = []
for i in range(chunk_count):
start = i * chunk_size
end = start + chunk_size
if end > len(data) or chunk_size <= 0:
end = len(data)
chunks.append(data[start:end])
arr_name = array_name
if chunk_count > 1:
arr_name = f"{array_name}_{i}"
buf.append(f"unsigned char {arr_name}[] = {{\n")
write_bytes(buf, data[start:end])
buf.append("};\n\n")
buf.append(f"inline std::vector<unsigned char> get{array_name}Vector() {{\n")
buf.append(" std::vector<unsigned char> result;\n")
for i in range(chunk_count):
arr_name = array_name if chunk_count == 1 else f"{array_name}_{i}"
buf.append(f" result.insert(result.end(), {arr_name}, {arr_name} + sizeof({arr_name}));\n")
buf.append(" return result;\n")
buf.append("}\n\n")
if chunk_count > 1:
buf.append(f"inline unsigned char* get{array_name}Bytes() {{\n")
buf.append(f" static unsigned char combined[{len(data)}];\n")
buf.append(" size_t offset = 0;\n")
for i in range(chunk_count):
buf.append(f" memcpy(combined + offset, {array_name}_{i}, sizeof({array_name}_{i})); offset += sizeof({array_name}_{i});\n")
buf.append(" return combined;\n")
buf.append("}\n")
with open(output_path, "w") as f:
f.write("".join(buf))
def main():
parser = argparse.ArgumentParser(description="Convert a file to a C++ array header")
parser.add_argument("-i", "--input", required=True, help="Input file path")
parser.add_argument("-o", "--output", default="output.h", help="Output header file")
parser.add_argument("-n", "--name", default="", help="Array name (generated from file if empty)")
parser.add_argument("-chunk", type=int, default=0, help="Chunk size in bytes; 0 = no chunking")
args = parser.parse_args()
if not args.name:
args.name = generate_array_name(args.input)
abs_input = os.path.abspath(args.input)
print("Reading:", abs_input)
print("Writing:", args.output)
print("Array name:", args.name)
if args.chunk > 0:
print(f"Chunk size: {args.chunk} bytes")
try:
file_to_cpp_array(args.input, args.output, args.name, args.chunk)
except Exception as e:
print("Error:", e)
sys.exit(1)
print("Done! Saved to", args.output)
if __name__ == "__main__":
main()