v3: gstack-code-gen 生成
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import struct
|
||||
from pathlib import Path
|
||||
from data.field_tree import FieldTree
|
||||
|
||||
|
||||
class CobolBinaryReader:
|
||||
def read(self, path: str, tree: FieldTree) -> list[dict]:
|
||||
d = Path(path).read_bytes()
|
||||
rs = self._record_size(tree)
|
||||
if rs == 0 or len(d) == 0:
|
||||
return []
|
||||
return [self._parse(d[o:o + rs], tree) for o in range(0, len(d), rs) if len(d[o:o + rs]) >= rs]
|
||||
|
||||
def _record_size(self, tree):
|
||||
return max((f.offset + f.length for f in tree.fields), default=0)
|
||||
|
||||
def _parse(self, r, tree):
|
||||
out = {}
|
||||
for n, f in tree.flatten().items():
|
||||
if f.length == 0 or f.offset + f.length > len(r):
|
||||
continue
|
||||
raw = r[f.offset:f.offset + f.length]
|
||||
if f.usage == "COMP-3":
|
||||
out[n] = self._comp3(raw, f.signed, f.decimal)
|
||||
elif f.usage in ("COMP", "COMP-5"):
|
||||
out[n] = int.from_bytes(raw, "big", signed=f.signed)
|
||||
else:
|
||||
out[n] = raw.decode("ascii", errors="replace").strip()
|
||||
return out
|
||||
|
||||
def _comp3(self, raw, signed, dec):
|
||||
if not raw:
|
||||
return "0"
|
||||
nib = []
|
||||
for b in raw:
|
||||
nib.append((b >> 4) & 0xF)
|
||||
nib.append(b & 0xF)
|
||||
s = nib.pop()
|
||||
v = sum(n * (10 ** (len(nib) - i)) for i, n in zip(range(len(nib)), nib))
|
||||
if signed and s in (0xD, 0xB):
|
||||
v = -v
|
||||
d = 10 ** dec
|
||||
return f"{float(v) / d:.{dec}f}" if dec else str(v)
|
||||
Reference in New Issue
Block a user