input_linux.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package door
  2. import (
  3. "bufio"
  4. "bytes"
  5. "io"
  6. "log"
  7. "strings"
  8. "syscall"
  9. "time"
  10. "unicode"
  11. )
  12. var ReaderInterval = time.Duration(200) * time.Millisecond
  13. var ReaderTimeval syscall.Timeval = syscall.NsecToTimeval(int64(ReaderInterval))
  14. // Output a nice string representation of the rune buffer.
  15. func extended_output(buffer []rune) string {
  16. var output string = string(buffer)
  17. output = strings.Replace(output, "\x1b", "^[", -1)
  18. return output
  19. }
  20. // syscall.FdSet clear all
  21. func clearAll(fdSetPtr *syscall.FdSet) {
  22. for index := range (*fdSetPtr).Bits {
  23. (*fdSetPtr).Bits[index] = 0
  24. }
  25. }
  26. // syscall.FdSet set fd
  27. func set(fdSetPtr *syscall.FdSet, fd int) {
  28. (*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
  29. }
  30. func RuneToInt8(r rune) int8 {
  31. return int8(r)
  32. }
  33. const READ_SIZE = 16 // Size of read buffer
  34. // go routine Reader for input
  35. // This "times out" every ReaderTimeval
  36. func Reader(d *Door) {
  37. // I need non-blocking reads here.
  38. /*
  39. ReaderTimeval = syscall.Timeval{Sec: int64(ReaderInterval.Seconds()),
  40. Usec: ReaderInterval.Microseconds() % time.Second.Microseconds()}
  41. */
  42. log.Println(ReaderInterval, ReaderTimeval)
  43. readerBuffer = make([]rune, 0, READ_SIZE*2)
  44. defer func() {
  45. log.Printf("~Reader\n")
  46. if d.ReaderCanClose {
  47. d.wg.Done()
  48. }
  49. }()
  50. defer func() {
  51. if err := recover(); err != nil {
  52. log.Printf("Reader: %#v\n", err)
  53. }
  54. }()
  55. var fdset syscall.FdSet
  56. var readbuffer [READ_SIZE]byte
  57. var runebuffer bytes.Buffer
  58. var runeread = bufio.NewReaderSize(&runebuffer, 1)
  59. var selectTimeval syscall.Timeval
  60. for {
  61. clearAll(&fdset)
  62. set(&fdset, d.READFD)
  63. selectTimeval = ReaderTimeval
  64. v, err := syscall.Select(d.READFD+1, &fdset, nil, nil, &selectTimeval)
  65. if err == syscall.EINTR {
  66. continue
  67. }
  68. // log.Printf("Select: %#v / %#v\n", v, err)
  69. if v == -1 {
  70. log.Printf("Reader ERR: %#v\n", err)
  71. d.readerMutex.Lock()
  72. if !d.ReaderClosed {
  73. d.ReaderClosed = true
  74. close(d.readerChannel)
  75. }
  76. return
  77. }
  78. if v == 0 {
  79. // timeout
  80. process(d, false)
  81. continue
  82. }
  83. // The buffer used here must have len & cap to size you want to read.
  84. // use [BUFF_SIZE]byte for readone
  85. r, err := syscall.Read(d.READFD, readbuffer[:])
  86. if r == -1 {
  87. log.Println("syscall.Read -1 (closed)")
  88. d.readerMutex.Lock()
  89. defer d.readerMutex.Unlock()
  90. if !d.ReaderClosed {
  91. d.ReaderClosed = true
  92. d.Disconnected = true
  93. close(d.readerChannel)
  94. }
  95. return
  96. }
  97. if r == 0 {
  98. log.Printf("Select said ready, but: %#v %#v\n", r, err)
  99. d.readerMutex.Lock()
  100. defer d.readerMutex.Unlock()
  101. if !d.ReaderClosed {
  102. d.ReaderClosed = true
  103. d.Disconnected = true
  104. close(d.readerChannel)
  105. }
  106. return
  107. }
  108. if DEBUG_INPUT {
  109. log.Printf("Reader << %d, %#v\n", r, readbuffer[:r])
  110. }
  111. runebuffer.Write(readbuffer[:r])
  112. var input rune
  113. // Is this unicode?
  114. err = nil
  115. for err == nil {
  116. //RuneRead:
  117. input, _, err = runeread.ReadRune()
  118. if err == io.EOF {
  119. break // continue
  120. }
  121. if err != nil {
  122. if DEBUG_INPUT {
  123. log.Printf("ReadRune: %#v\n", err)
  124. }
  125. // errors EOF
  126. break // continue // break for loop
  127. }
  128. if input == unicode.ReplacementChar {
  129. runeread.UnreadRune()
  130. b, _ := runeread.ReadByte()
  131. if DEBUG_INPUT {
  132. log.Printf("Reader (byte) >> %x\n", b)
  133. }
  134. readerBuffer = append(readerBuffer, rune(b))
  135. // d.readerChannel <- rune(b)
  136. } else {
  137. if DEBUG_INPUT {
  138. log.Printf("Reader >> %x\n", input)
  139. }
  140. readerBuffer = append(readerBuffer, input)
  141. // d.readerChannel <- input
  142. }
  143. // process(d, true)
  144. } // goto RuneRead
  145. process(d, true)
  146. // buffer = append(buffer, readone[0])
  147. /*
  148. Take2:
  149. input, size = utf8.DecodeRune(buffer)
  150. if input != utf8.RuneError {
  151. d.readerChannel <- input
  152. for size > 0 {
  153. ArrayDelete(&buffer, 0)
  154. size--
  155. }
  156. if len(buffer) > 0 {
  157. goto Take2
  158. }
  159. timeoutCount = 0
  160. } else {
  161. // Not a valid rune
  162. continue
  163. }
  164. */
  165. // d.readerChannel <- rune(buffer[0])
  166. }
  167. }