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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
"""Conversion utility from flatbuffer JSON files to binary and the reverse."""
# Copyright (c) 2021-2023, ARM Limited.
# SPDX-License-Identifier: Apache-2.0
import re
from pathlib import Path
from typing import Optional
from runner.run_command import run_sh_command
from runner.run_command import RunShCommandError
MAX_LINE_LEN = 120
MAX_INDENT_LEN = 20
def json_squeeze(json_path: Path):
"""File compression for JSONs, reducing spaces used for number lists."""
# Move existing file to a new name
temp_path = json_path.with_suffix(".json_unsqueezed")
json_path.rename(temp_path)
# Now read the original file and write a smaller output with less new lines/spaces
with temp_path.open("r") as tfd:
with json_path.open("w") as jfd:
found = False
for line in tfd:
# Find lines that are part of number lists
match = re.match(r"(\s+)(-?[0-9]+),?", line)
if match:
# Found a line with just a number on it (and optional comma)
if not found:
# New list of numbers
numbers = []
# Save indent (upto maximum)
indent = match.group(1)[0:MAX_INDENT_LEN]
found = True
numbers.append(match.group(2))
else:
# Found a line without just a number
if found:
# Format the list of numbers recorded into a concise output
# with multiple numbers on a single line, rather than one per line
numbers_str = indent
for num in numbers:
nums = f"{num},"
if len(numbers_str) + len(nums) > MAX_LINE_LEN:
print(numbers_str, file=jfd)
numbers_str = indent
numbers_str += nums
# print all but the last comma
print(numbers_str[:-1], file=jfd)
found = False
# print the line we just read (that wasn't just a number)
print(line, file=jfd, end="")
# Remove the uncompressed version
temp_path.unlink()
def fbbin_to_json(
flatc: Path,
fbs: Path,
t_path: Path,
o_path: Optional[Path] = None,
squeeze: Optional[bool] = True,
):
"""Convert the binary flatbuffer to JSON.
flatc: the Path to the flatc compiler program
fbs: the Path to the fbs (flatbuffer schema) file
t_path: the Path to the binary flatbuffer file
o_path: the output Path where JSON file will be put, if None, it is same as t_path
"""
if o_path is None:
o_path = t_path.parent
cmd = [
str(flatc.absolute()),
"-o",
str(o_path.absolute()),
"--json",
"--strict-json",
"--defaults-json",
"--raw-binary",
str(fbs.absolute()),
"--",
str(t_path.absolute()),
]
run_sh_command(verbose=False, full_cmd=cmd)
if squeeze:
json_path = (o_path / t_path.name).with_suffix(".json")
json_squeeze(json_path)
def json_to_fbbin(flatc: Path, fbs: Path, j_path: Path, o_path: Optional[Path] = None):
"""Convert JSON flatbuffer to binary.
flatc: the Path to the flatc compiler program
fbs: the Path to the fbs (flatbuffer schema) file
j_path: the Path to the JSON flatbuffer file
o_path: the output Path where JSON file will be put, if None, it is same as j_path
"""
if o_path is None:
o_path = j_path.parent
cmd = [
str(flatc.absolute()),
"-o",
str(o_path.absolute()),
"--binary",
str(fbs.absolute()),
str(j_path.absolute()),
]
run_sh_command(verbose=False, full_cmd=cmd)
# ------------------------------------------------------------------------------
def main(argv=None):
"""Load and convert supplied file based on file suffix."""
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"--no-squeeze", action="store_true", help="no compression of json output"
)
parser.add_argument(
"--flatc",
type=Path,
default=(
"reference_model/build/thirdparty/serialization_lib/"
"third_party/flatbuffers/flatc"
),
help="the path to the flatc compiler program",
)
parser.add_argument(
"--fbs",
type=Path,
default="conformance_tests/third_party/serialization_lib/schema/tosa.fbs",
help="the path to the flatbuffer schema",
)
parser.add_argument("path", type=Path, help="the path to the file to convert")
args = parser.parse_args(argv)
path = args.path
if not path.is_file():
print(f"Invalid file to convert - {path}")
return 2
if not args.flatc.is_file():
print(f"Invalid flatc compiler - {args.flatc}")
return 2
if not args.fbs.is_file():
print(f"Invalid flatbuffer schema - {args.fbs}")
return 2
try:
if path.suffix == ".json":
json_to_fbbin(args.flatc, args.fbs, path)
else:
# Have to assume this is a binary flatbuffer file as could have any suffix
fbbin_to_json(args.flatc, args.fbs, path, squeeze=(not args.no_squeeze))
except RunShCommandError as e:
print(e)
return 1
return 0
if __name__ == "__main__":
exit(main())
|