#!/usr/bin/python3 import subprocess import os import collections import re import sys def readline_toc(f): buf = f.read(4096) m = re.match(b'^#fields:[ ]*[^\0x00\n\r]+([\x00\r\n]+)', buf) if not m: raise Exception("Not a valid TOC file '%s'" % f) terminator = m.group(1) while True: pos = buf.find(terminator) if pos == -1: tmp = f.read(4096) if len(tmp) == 0: raise EOFError() buf += tmp continue yield buf[0:pos] buf = buf[pos+len(terminator):] class HashTOC: def __init__(self, stream, rename={}): def readtoc(f): for l in readline_toc(f): if not l.startswith(b'#'): data = l.split(b':', N-1) yield tocEntry(*data) continue tmp = [ s.strip().decode('utf8') for s in l.split(b':') ] if tmp[0].startswith('#fields'): fields = [ rename.get(f) or f for f in tmp[1:] ] tocEntry = collections.namedtuple('TOCEntry', fields) N = len(tmp) - 1 pass elif tmp[0].startswith('#endTOC'): while True: yield tocEntry(*[ None for e in tocEntry._fields ]) else: #print('X',tmp, file=sys.stderr) pass pass raise Exception("Incorrect termination of TOC file '%s'" % f) self.reader = readtoc(stream) self.next() def next(self): data = self.reader.__next__() self.fields = data._fields for k,v in zip(data._fields, data): setattr(self, k, v) pass pass