123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package door
- import (
- "bufio"
- "bytes"
- "log"
- "strings"
- "syscall"
- "time"
- )
- var ReaderInterval = time.Duration(200) * time.Millisecond
- var ReaderTimeval syscall.Timeval = syscall.NsecToTimeval(int64(ReaderInterval))
- // Output a nice string representation of the rune buffer.
- func extended_output(buffer []rune) string {
- var output string = string(buffer)
- output = strings.Replace(output, "\x1b", "^[", -1)
- return output
- }
- // syscall.FdSet clear all
- func clearAll(fdSetPtr *syscall.FdSet) {
- for index := range (*fdSetPtr).Bits {
- (*fdSetPtr).Bits[index] = 0
- }
- }
- // syscall.FdSet set fd
- func set(fdSetPtr *syscall.FdSet, fd int) {
- (*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
- }
- // go routine Reader for input
- // This "times out" every ReaderTimeval
- func Reader(d *Door) {
- // I need non-blocking reads here.
- /*
- ReaderTimeval = syscall.Timeval{Sec: int64(ReaderInterval.Seconds()),
- Usec: ReaderInterval.Microseconds() % time.Second.Microseconds()}
- */
- log.Println(ReaderInterval, ReaderTimeval)
- readerBuffer = make([]rune, 0, READ_SIZE*2)
- defer func() {
- log.Printf("~Reader\n")
- //if d.ReaderCanClose {
- d.wg.Done()
- //}
- }()
- defer func() {
- if err := recover(); err != nil {
- log.Printf("Reader: %#v\n", err)
- }
- }()
- var fdset syscall.FdSet
- var readbuffer [READ_SIZE]byte
- var runebuffer bytes.Buffer
- var runeread = bufio.NewReaderSize(&runebuffer, 1)
- var selectTimeval syscall.Timeval
- for {
- clearAll(&fdset)
- set(&fdset, d.READFD)
- selectTimeval = ReaderTimeval
- v, err := syscall.Select(d.READFD+1, &fdset, nil, nil, &selectTimeval)
- if err == syscall.EINTR {
- continue
- }
- // log.Printf("Select: %#v / %#v\n", v, err)
- if v == -1 {
- log.Printf("Reader ERR: %#v\n", err)
- d.readerMutex.Lock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- close(d.readerChannel)
- }
- return
- }
- if v == 0 {
- // timeout
- ReadRune(d, runeread, true)
- // process(d, false)
- d.readerMutex.Lock()
- if d.ReaderEnd {
- if !d.ReaderClosed {
- d.ReaderClosed = true
- close(d.readerChannel)
- }
- d.readerMutex.Unlock()
- return
- }
- d.readerMutex.Unlock()
- continue
- }
- // The buffer used here must have len & cap to size you want to read.
- // use [BUFF_SIZE]byte for readone
- r, err := syscall.Read(d.READFD, readbuffer[:])
- if r == -1 {
- log.Println("syscall.Read -1 (closed)")
- d.readerMutex.Lock()
- defer d.readerMutex.Unlock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- d.Disconnected = true
- close(d.readerChannel)
- }
- return
- }
- if r == 0 {
- log.Printf("Select said ready, but: %#v %#v\n", r, err)
- d.readerMutex.Lock()
- defer d.readerMutex.Unlock()
- if !d.ReaderClosed {
- d.ReaderClosed = true
- d.Disconnected = true
- close(d.readerChannel)
- }
- return
- }
- if DEBUG_INPUT {
- log.Printf("Reader << %d, %#v\n", r, readbuffer[:r])
- }
- // write the received bytes into runebuffer.
- runebuffer.Write(readbuffer[:r])
- ReadRune(d, runeread, false)
- // process(d, true)
- // buffer = append(buffer, readone[0])
- /*
- Take2:
- input, size = utf8.DecodeRune(buffer)
- if input != utf8.RuneError {
- d.readerChannel <- input
- for size > 0 {
- ArrayDelete(&buffer, 0)
- size--
- }
- if len(buffer) > 0 {
- goto Take2
- }
- timeoutCount = 0
- } else {
- // Not a valid rune
- continue
- }
- */
- // d.readerChannel <- rune(buffer[0])
- }
- }
|