# An iolist is one of # - None # - a list of iolists # - a CountedIOList # - a bytes # - a number i, 0 <= i < 256 class CountedIOList: def __init__(self, i): self.value = i self.length = len(i) def counted(i): if isinstance(i, CountedIOList): return i return CountedIOList(i) def withbyte(i, b): if i is None: return b elif isinstance(i, list): i.append(b) return i else: return [i, b] _len = len def join(*iolists): if _len(iolists) == 0: return None if _len(iolists) == 1: return iolists[0] return list(iolists) def len(i): if i is None: return 0 if isinstance(i, int): return 1 if isinstance(i, _bytes): return _len(i) if isinstance(i, list): acc = 0 for j in i: acc = acc + len(j) return acc if isinstance(i, CountedIOList): return i.length raise ValueError('invalid iolist: ' + repr(i) + ' ' + repr(type(i))) _bytes = bytes def bytes(i): buffer = bytearray(len(i)) def fill(i, offset): while isinstance(i, CountedIOList): i = i.value if i is None: return offset if isinstance(i, int): buffer[offset] = i return offset + 1 if isinstance(i, _bytes): buffer[offset:offset+_len(i)] = i return offset + _len(i) if isinstance(i, list): for j in i: offset = fill(j, offset) return offset raise ValueError('invalid iolist') fill(i, 0) return _bytes(buffer)