Files
chimera-gfx-Public/tools/phase10ds_metadata_protocol.py
T
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

29 lines
1.6 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
import struct
MAGIC=b"CHM10DS1";FRAME=struct.Struct("<8sIIiiIIQ24s");NAMES=("app.pbm","app.json","app.xml","app.crc");MAX_FILE=4096;MAX_WIRE=16768
class ProtocolError(ValueError):pass
def frame(raw):
if len(raw)!=64:raise ProtocolError("frame size")
v=FRAME.unpack(raw)
if v[0]!=MAGIC or v[1]!=1 or v[8]!=bytes(24):raise ProtocolError("frame identity")
return v
def parse_stream(raw:bytes)->dict[str,bytes]:
if not isinstance(raw,bytes) or not 128<=len(raw)<=MAX_WIRE:raise ProtocolError("stream length")
first=frame(raw[:64]);kind,status,saved,index,length,total=first[2:8]
if kind==4:raise ProtocolError(f"target error {status}:{saved}")
if (kind,status,saved,index,length,total)!=(1,0,0,4,0,0):raise ProtocolError("header invalid")
offset=64;files={};transferred=0
for expected,name in enumerate(NAMES):
if offset+64>len(raw):raise ProtocolError("file frame truncated")
value=frame(raw[offset:offset+64]);offset+=64;kind,status,saved,index,length,total=value[2:8]
if kind==4:raise ProtocolError(f"target error {status}:{saved}")
if kind!=2 or status or saved or index!=expected or length>MAX_FILE or total!=transferred:raise ProtocolError("file frame invalid")
if offset+length>len(raw):raise ProtocolError("file truncated")
files[name]=raw[offset:offset+length];offset+=length;transferred+=length
if offset+64!=len(raw):raise ProtocolError("terminal position")
value=frame(raw[offset:]);kind,status,saved,index,length,total=value[2:8]
if (kind,status,saved,index,length,total)!=(3,0,0,4,0,transferred):raise ProtocolError("terminal invalid")
return files