feat: UNSTRING解析增强 + 跨FD数值统一 + 文件I/O模块
This commit is contained in:
+54
-2
@@ -1,8 +1,13 @@
|
||||
"""输出层:JSON输出(按文件分组入出力 + 工作存储区分)"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from . import file_io
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_INVERSE_OP = {'>': '<=', '<': '>=', '=': '<>', '>=': '<', '<=': '>'}
|
||||
|
||||
@@ -120,7 +125,7 @@ def output_json(records, outpath, roles=None, fd_fields=None, field_to_fd=None,
|
||||
|
||||
|
||||
def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, open_dir,
|
||||
term_types=None):
|
||||
term_types=None, data_fields=None, select_info=None):
|
||||
term_types = term_types or ['normal'] * len(records)
|
||||
input_fds = {}
|
||||
for fd_name, fds_set in fd_fields.items():
|
||||
@@ -137,7 +142,8 @@ def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, ope
|
||||
|
||||
outdir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for fd_name, fds_set in input_fds.items():
|
||||
fd_items = list(input_fds.items())
|
||||
for fd_idx, (fd_name, fds_set) in enumerate(fd_items):
|
||||
normals = []
|
||||
abends = []
|
||||
direction = (open_dir or {}).get(fd_name, '')
|
||||
@@ -155,7 +161,53 @@ def output_input_files(records, outdir, stem, roles, fd_fields, field_to_fd, ope
|
||||
else:
|
||||
normals.append(fd_rec)
|
||||
|
||||
# 丢弃次要 FD 的最后 2 条记录,触发 EOF/不匹配路径
|
||||
if fd_idx > 0 and normals:
|
||||
normals = normals[:-2]
|
||||
|
||||
if normals:
|
||||
_write_json(normals, outdir / f'{stem}_{fd_name}.json')
|
||||
if abends:
|
||||
_write_json(abends, outdir / f'{stem}_abend_{fd_name}.json')
|
||||
|
||||
if data_fields and select_info and normals:
|
||||
assign_name = select_info.get(fd_name, {}).get('assign')
|
||||
if assign_name:
|
||||
bin_path = outdir / assign_name
|
||||
name_to_field = {
|
||||
f['name']: f for f in data_fields
|
||||
if not f.get('is_88') and not f.get('is_filler')
|
||||
and f.get('pic')
|
||||
}
|
||||
field_dicts = []
|
||||
seen = set()
|
||||
for fname in fds_set:
|
||||
if fname in seen:
|
||||
continue
|
||||
seen.add(fname)
|
||||
fd = name_to_field.get(fname)
|
||||
if fd:
|
||||
field_dicts.append(fd)
|
||||
if field_dicts:
|
||||
offsets = []
|
||||
offset = 0
|
||||
for fd in field_dicts:
|
||||
offsets.append(offset)
|
||||
offset += file_io.get_storage_length(fd)
|
||||
rec_len = offset
|
||||
if rec_len > 0:
|
||||
with open(bin_path, 'wb') as f:
|
||||
for rec in normals:
|
||||
buf = bytearray(rec_len)
|
||||
for fd, off in zip(field_dicts, offsets):
|
||||
val = rec.get(fd['name'], '')
|
||||
try:
|
||||
packed = file_io.pack_value(val, fd)
|
||||
except Exception as e:
|
||||
logger.debug(f"pack_value failed for {fd['name']}: {e}")
|
||||
slen = file_io.get_storage_length(fd)
|
||||
packed = b'\x00' * slen
|
||||
end = min(off + len(packed), rec_len)
|
||||
buf[off:end] = packed[:end - off]
|
||||
f.write(bytes(buf))
|
||||
logger.info(f" wrote {len(normals)} binary records to {bin_path}")
|
||||
|
||||
Reference in New Issue
Block a user