github.com/jflude/taocp@v0.0.0-20240210234939-99f2a91af3c2/mix/reader.go (about)

     1  package mix
     2  
     3  import (
     4  	"bufio"
     5  	"errors"
     6  	"io"
     7  	"unicode/utf8"
     8  )
     9  
    10  type CardReader struct {
    11  	br *bufio.Reader
    12  }
    13  
    14  var ErrFormat = errors.New("mix: format error")
    15  
    16  // see https://en.wikipedia.org/wiki/IBM_2540
    17  func NewCardReader(r io.Reader) (*CardReader, error) {
    18  	return &CardReader{bufio.NewReader(r)}, nil
    19  }
    20  
    21  func (*CardReader) Name() string {
    22  	return "READER"
    23  }
    24  
    25  func (*CardReader) BlockSize() int {
    26  	return 16
    27  }
    28  
    29  func (r *CardReader) Read(block []Word) (int64, error) {
    30  	s, err := r.br.ReadString('\n')
    31  	if err != nil || s == "" {
    32  		return 0, err
    33  	}
    34  	if s[len(s)-1] != '\n' || utf8.RuneCountInString(s) > 81 {
    35  		return 0, ErrFormat
    36  	}
    37  	s = s[:len(s)-1]
    38  	if ch, ok := IsPunchable(s); !ok {
    39  		return 0, charError(ch)
    40  	}
    41  	m, err := ConvertToMIX(s)
    42  	if err != nil {
    43  		return 0, err
    44  	}
    45  	copy(block, m)
    46  	for i := len(m); i < len(block); i++ {
    47  		block[i] = 0
    48  	}
    49  	return 60000, nil
    50  }
    51  
    52  func (*CardReader) Write([]Word) (int64, error) {
    53  	return 0, ErrInvalidCommand
    54  }
    55  
    56  func (r *CardReader) Control(m int) (int64, error) {
    57  	return 0, ErrInvalidCommand
    58  }
    59  
    60  func (r *CardReader) Close() error {
    61  	return nil
    62  }