#!/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