add java variant of byte_position

This commit is contained in:
Zack Buhman 2024-12-31 11:48:13 -06:00
parent fedb30394a
commit 48eb7c91dd
4 changed files with 128 additions and 58 deletions

View File

@ -92,5 +92,5 @@ gdrom/command_packet_format.hpp: regs/gdrom_command_packet_format.csv regs/gen/g
# ISO9660
iso9660/%.hpp: iso9660/%.csv iso9660/byte_position.py
python iso9660/byte_position.py $< > $@
iso9660/%.hpp: iso9660/%.csv iso9660/byte_position_cpp.py
python iso9660/byte_position_cpp.py $< > $@

View File

@ -2,11 +2,6 @@ import sys
from dataclasses import dataclass
from os import path
from csv_input import read_input
from generate import renderer
from pprint import pprint
def parse_bp(s):
if ' to ' in s:
start0, end0 = s.split(' to ')
@ -71,54 +66,3 @@ def parse(rows):
name=field_name,
content=content_name
)
type_dict = {
1: 'uint8_t',
2: 'uint16_t',
4: 'uint16_le_be',
8: 'uint32_le_be',
}
def header():
yield "#pragma once"
yield ""
yield "#include <cstdint>"
yield "#include <cstddef>"
yield ""
yield '#include "uint_le_be.hpp"'
yield ""
def render_fields(input_name, fields):
yield "namespace iso9660 {"
yield f"struct {input_name} {{"
for field in fields:
field_size = (field.end - field.start) + 1
if field.content == 'numerical_value':
assert field_size in type_dict, field
type = type_dict[field_size]
yield f"const {type} {field.name};"
else:
if field_size == 1:
yield f"const uint8_t {field.name};"
elif field_size == 0:
yield f"const uint8_t {field.name}[];"
else:
yield f"const uint8_t {field.name}[{field_size}];"
yield "};"
for field in fields:
yield f"static_assert((offsetof (struct {input_name}, {field.name})) == {field.start - 1});"
yield "}" # namespace
if __name__ == "__main__":
input_file = sys.argv[1]
input_name0, _ = path.splitext(input_file)
_, input_name = path.split(input_name0)
rows = read_input(input_file)
fields = list(parse(rows))
render, out = renderer()
render(header())
render(render_fields(input_name, fields))
sys.stdout.write(out.getvalue())

View File

@ -0,0 +1,58 @@
import sys
from os import path
from csv_input import read_input
from generate import renderer
from byte_position import parse
type_dict = {
1: 'uint8_t',
2: 'uint16_t',
4: 'uint16_le_be',
8: 'uint32_le_be',
}
def header():
yield "#pragma once"
yield ""
yield "#include <cstdint>"
yield "#include <cstddef>"
yield ""
yield '#include "uint_le_be.hpp"'
yield ""
def render_fields(input_name, fields):
yield "namespace iso9660 {"
yield f"struct {input_name} {{"
for field in fields:
field_size = (field.end - field.start) + 1
if field.content == 'numerical_value':
assert field_size in type_dict, field
type = type_dict[field_size]
yield f"const {type} {field.name};"
else:
if field_size == 1:
yield f"const uint8_t {field.name};"
elif field_size == 0:
yield f"const uint8_t {field.name}[];"
else:
yield f"const uint8_t {field.name}[{field_size}];"
yield "};"
for field in fields:
yield f"static_assert((offsetof (struct {input_name}, {field.name})) == {field.start - 1});"
yield "}" # namespace
if __name__ == "__main__":
input_file = sys.argv[1]
input_name0, _ = path.splitext(input_file)
_, input_name = path.split(input_name0)
rows = read_input(input_file)
fields = list(parse(rows))
render, out = renderer()
render(header())
render(render_fields(input_name, fields))
sys.stdout.write(out.getvalue())

View File

@ -0,0 +1,68 @@
import sys
from os import path
from csv_input import read_input
from generate import renderer
from byte_position import parse
size_to_accessor = {
1: "getByte",
4: "getShortLE",
8: "getIntLE",
}
def _camelcase(name, first_upper):
want_upper = first_upper
for c in name:
if c == '_':
want_upper = True
else:
yield c.upper() if want_upper else c
want_upper = False
def pascalcase(name):
return "".join(_camelcase(name, first_upper=True))
def camelcase(name):
return "".join(_camelcase(name, first_upper=False))
def render_fields(input_name, fields):
yield "package filesystem.iso9660;"
yield f"public class {pascalcase(input_name)} extends ByteParser {{"
for field in fields:
if "_res" in field.name.lower():
continue
yield f"public static final int {field.name.upper()}_START = {field.start - 1};"
yield f"public static final int {field.name.upper()}_END = {field.end - 1};"
yield f"{pascalcase(input_name)}(byte[] array, int offset) {{"
yield "super(array, offset);"
yield "}"
for field in fields:
if "_res" in field.name.lower():
continue
if field.content == 'numerical_value':
field_size = (field.end - field.start) + 1
accessor = size_to_accessor[field_size]
yield f"public int {camelcase(field.name)}() {{"
yield f"return {accessor}({field.name.upper()}_START);"
yield "}"
yield "}"
if __name__ == "__main__":
input_file = sys.argv[1]
input_name0, _ = path.splitext(input_file)
_, input_name = path.split(input_name0)
rows = read_input(input_file)
fields = list(parse(rows))
render, out = renderer()
render(render_fields(input_name, fields))
sys.stdout.write(out.getvalue())