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 }