v1: executing-plans 模式生成,54 文件 1320 行 Python

This commit is contained in:
hangshuo652
2026-05-24 10:02:52 +08:00
commit 06b295f780
55 changed files with 1749 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
import struct
from pathlib import Path
from data.field_tree import FieldTree
class CobolBinaryReader:
def read(self, binary_path: str, tree: FieldTree) -> list[dict]:
data = Path(binary_path).read_bytes()
record_size = self._compute_record_size(tree)
if record_size == 0 or len(data) == 0:
return []
records = []
for offset in range(0, len(data), record_size):
record = data[offset:offset + record_size]
if len(record) >= record_size:
records.append(self._parse_record(record, tree))
return records
def _compute_record_size(self, tree: FieldTree) -> int:
max_end = 0
for f in tree.fields:
end = f.offset + f.length
if end > max_end:
max_end = end
return max_end
def _parse_record(self, record: bytes, tree: FieldTree) -> dict:
result = {}
for name, field in tree.flatten().items():
if field.length == 0 or field.offset + field.length > len(record):
continue
raw = record[field.offset:field.offset + field.length]
if field.usage == "COMP-3":
result[name] = self._parse_comp3(raw, field.signed, field.decimal)
elif field.usage == "COMP" or field.usage == "COMP-5":
result[name] = int.from_bytes(raw, "big", signed=field.signed)
else:
result[name] = raw.decode("ascii", errors="replace").strip()
return result
def _parse_comp3(self, raw: bytes, signed: bool, decimal: int) -> str:
if not raw:
return "0"
nibbles = []
for b in raw:
nibbles.append((b >> 4) & 0x0F)
nibbles.append(b & 0x0F)
sign = nibbles.pop()
value = 0
for n in nibbles:
value = value * 10 + n
if signed and sign in (0x0D, 0x0B):
value = -value
divisor = 10 ** decimal
result = float(value) / divisor
return f"{result:.{decimal}f}" if decimal else str(value)