Source code for baudot.handlers.tape

"""
Handler for reading and writing to pretty tape-like formatted text

For example, the tape might look like:::

    ***.**
    * *.
       . *
    *  .*
    *  .*
    ** .
      *.
    *  .**
    ** .
     * .*
    *  .*
     * . *
    ** .**
     **. *

(Which reads 'HELLO WORLD!')
"""

from collections import namedtuple
from io import TextIOBase

from .core import BaudotReader, BaudotWriter
from ..exceptions import WriteError

TapeConfig = namedtuple('TapeConfig', ('punch', 'blank', 'sep'))
TapeConfig.__doc__ = """
Object for storing a tape representation format.
"""

DEFAULT_TAPE = TapeConfig('*', ' ', '.')

MSB_FIRST = [1 << (4-n) for n in range(5)]


[docs]class TapeReader(BaudotReader): """ Reader class for tape-like data. """ def __init__(self, stream: TextIOBase, config: TapeConfig = DEFAULT_TAPE): self.stream = stream self.config = config def __next__(self) -> int: line = next(self.stream) pairs = zip(line.replace(self.config.sep, ''), MSB_FIRST) return sum(n for c, n in pairs if c == self.config.punch)
[docs]class TapeWriter(BaudotWriter): """ Writer class for tape-like data. """ def __init__(self, stream: TextIOBase, config: TapeConfig = DEFAULT_TAPE): self.stream = stream self.config = config
[docs] def write(self, code: int): """Writes a code to tape""" if not 0 <= code < 32: raise WriteError('Invalid 5-bit character code') chars = ''.join(self.config.punch if c == '1' else self.config.blank for c in f'{code:05b}') self.stream.write(f"{chars[:3]}{self.config.sep}{chars[3:]}\n")