input_linux.go 4.3 KB

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