Skip to content

Instantly share code, notes, and snippets.

@nitori
Last active September 5, 2023 19:29
Show Gist options
  • Select an option

  • Save nitori/6e7be6c9f00411c12aacc1ee964aee88 to your computer and use it in GitHub Desktop.

Select an option

Save nitori/6e7be6c9f00411c12aacc1ee964aee88 to your computer and use it in GitHub Desktop.
import struct
import os
import hashlib
def read_dsf(filename):
size = os.stat(filename).st_size
footer_start = size - 16 # 16 byte (128bit) for md5 hash
digest = hashlib.md5()
with open(filename, 'rb') as f:
# read 8s = 8 byte string, and "i" = 1 32 bit integer (total: 12 bytes)
raw_header = f.read(12)
header, version = struct.unpack('<8si', raw_header)
digest.update(raw_header)
if header != b'XPLNEDSF':
raise ValueError('Not a valid XPLNEDSF file')
if version != 1:
raise ValueError('Only version 1 supported')
while f.tell() < footer_start:
raw_atom_header = f.read(8)
digest.update(raw_atom_header)
# 32bit atom id + 32 bit atom_size.. total: 8 byte
atom_id, atom_size = struct.unpack('<ii', raw_atom_header)
#atom_id = struct.pack('>i', atom_id) 'DAEH' -> 'HEAD'
# data size is atom_size excluding the just read 8 byte id+size header
atom_data = f.read(atom_size - 8)
digest.update(atom_data)
yield atom_id, atom_size, atom_data
checksum = f.read()
if checksum != digest.digest():
raise ValueError('checksum mismatch!')
for atom_id, atom_size, atom_data in read_dsf('mesh.dsf'):
print((atom_id, atom_size, atom_data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment