|
@@ -1,24 +1,58 @@
|
|
package door
|
|
package door
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "bufio"
|
|
|
|
+ "bytes"
|
|
"log"
|
|
"log"
|
|
"syscall"
|
|
"syscall"
|
|
"time"
|
|
"time"
|
|
|
|
+ "unicode"
|
|
)
|
|
)
|
|
|
|
|
|
var ReaderInterval = time.Duration(200) * time.Millisecond
|
|
var ReaderInterval = time.Duration(200) * time.Millisecond
|
|
var ReaderTimeval syscall.Timeval = syscall.Timeval{0, 200}
|
|
var ReaderTimeval syscall.Timeval = syscall.Timeval{0, 200}
|
|
|
|
|
|
|
|
+// syscall.FdSet clear all
|
|
func clearAll(fdSetPtr *syscall.FdSet) {
|
|
func clearAll(fdSetPtr *syscall.FdSet) {
|
|
for index := range (*fdSetPtr).Bits {
|
|
for index := range (*fdSetPtr).Bits {
|
|
(*fdSetPtr).Bits[index] = 0
|
|
(*fdSetPtr).Bits[index] = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// syscall.FdSet set fd
|
|
func set(fdSetPtr *syscall.FdSet, fd int) {
|
|
func set(fdSetPtr *syscall.FdSet, fd int) {
|
|
(*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
|
|
(*fdSetPtr).Bits[fd/64] |= 1 << uint64(fd%64)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ func main() {
|
|
|
|
+ var text string = "\x1b\u2415\xff"
|
|
|
|
+ var buffer []byte = []byte(text)
|
|
|
|
+ var readbuffer = bytes.NewBuffer(buffer)
|
|
|
|
+ // bytes.Buffer{}
|
|
|
|
+ // readbuffer.Write(buffer)
|
|
|
|
+
|
|
|
|
+ var runeread = bufio.NewReaderSize(readbuffer, 1)
|
|
|
|
+
|
|
|
|
+ //for readbuffer.Len() > 0 {
|
|
|
|
+ for {
|
|
|
|
+ r, _, err := runeread.ReadRune()
|
|
|
|
+ if err != nil {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ if r == unicode.ReplacementChar {
|
|
|
|
+ runeread.UnreadRune()
|
|
|
|
+ b, _ := runeread.ReadByte()
|
|
|
|
+ fmt.Printf("BYTE %#v\n", b)
|
|
|
|
+ } else {
|
|
|
|
+ fmt.Printf("%#v\n", r)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+*/
|
|
|
|
+const READ_SIZE = 16
|
|
|
|
+
|
|
|
|
+// go routine Reader for input
|
|
|
|
+// This "times out" every ReaderTimeval
|
|
func Reader(d *Door) {
|
|
func Reader(d *Door) {
|
|
// I need non-blocking reads here.
|
|
// I need non-blocking reads here.
|
|
|
|
|
|
@@ -40,6 +74,12 @@ func Reader(d *Door) {
|
|
}()
|
|
}()
|
|
|
|
|
|
var fdset syscall.FdSet
|
|
var fdset syscall.FdSet
|
|
|
|
+ var readone []byte = make([]byte, READ_SIZE) //make([]byte, 0, READ_SIZE)
|
|
|
|
+ // read 1 byte
|
|
|
|
+ var readbuffer bytes.Buffer // NewBuffer(readone)
|
|
|
|
+ var runeread = bufio.NewReaderSize(&readbuffer, 1)
|
|
|
|
+
|
|
|
|
+ // var buffer []byte = make([]byte, 0) // unicode read buffer
|
|
|
|
|
|
for {
|
|
for {
|
|
clearAll(&fdset)
|
|
clearAll(&fdset)
|
|
@@ -65,16 +105,34 @@ func Reader(d *Door) {
|
|
|
|
|
|
if v == 0 {
|
|
if v == 0 {
|
|
// timeout
|
|
// timeout
|
|
|
|
+ /*
|
|
|
|
+ if len(buffer) > 0 {
|
|
|
|
+ timeoutCount++
|
|
|
|
+
|
|
|
|
+ input, size = utf8.DecodeRune(buffer)
|
|
|
|
+ if input != utf8.RuneError {
|
|
|
|
+ d.readerChannel <- input
|
|
|
|
+ for size > 0 {
|
|
|
|
+ ArrayDelete(&buffer, 0)
|
|
|
|
+ size--
|
|
|
|
+ }
|
|
|
|
+ timeoutCount = 0
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ b, _ := ArrayDelete(&buffer, 0)
|
|
|
|
+ d.readerChannel <- rune(b)
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ timeoutCount = 0
|
|
|
|
+ }
|
|
|
|
+ */
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
|
|
- // d.readerFile.SetReadDeadline(time.Now().Add(ReaderInterval))
|
|
|
|
- // not on a os.File you won't. :P
|
|
|
|
-
|
|
|
|
- // r, _, err := d.runereader.ReadRune()
|
|
|
|
|
|
+ log.Println("syscall.Read:", len(readone), cap(readone))
|
|
|
|
+ // The buffer used here must have len & cap to size you want to read.
|
|
|
|
|
|
- buffer := make([]byte, 1)
|
|
|
|
- r, err := syscall.Read(d.READFD, buffer)
|
|
|
|
|
|
+ r, err := syscall.Read(d.READFD, readone)
|
|
if r == -1 {
|
|
if r == -1 {
|
|
log.Println("Read -1 (closed)")
|
|
log.Println("Read -1 (closed)")
|
|
d.readerMutex.Lock()
|
|
d.readerMutex.Lock()
|
|
@@ -86,7 +144,7 @@ func Reader(d *Door) {
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if r != 1 {
|
|
|
|
|
|
+ if r == 0 {
|
|
log.Printf("Select said ready, but: %#v %#v\n", r, err)
|
|
log.Printf("Select said ready, but: %#v %#v\n", r, err)
|
|
d.readerMutex.Lock()
|
|
d.readerMutex.Lock()
|
|
defer d.readerMutex.Unlock()
|
|
defer d.readerMutex.Unlock()
|
|
@@ -97,89 +155,63 @@ func Reader(d *Door) {
|
|
}
|
|
}
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+ // readone = readone[:r]
|
|
|
|
|
|
if DEBUG_INPUT {
|
|
if DEBUG_INPUT {
|
|
- log.Printf("Reader (byte): %#v\n", buffer[0])
|
|
|
|
|
|
+ log.Printf("Reader << %d, %#v\n", r, readone[:r])
|
|
}
|
|
}
|
|
|
|
|
|
- d.readerChannel <- rune(buffer[0])
|
|
|
|
|
|
+ // Is this unicode?
|
|
|
|
+ readbuffer.Write(readone[:r])
|
|
|
|
+ // reset
|
|
|
|
+ // readone = readone[0:0]
|
|
|
|
+ log.Println("readone:", len(readone), cap(readone))
|
|
|
|
+ var input rune
|
|
|
|
|
|
- /*
|
|
|
|
- if r == unicode.ReplacementChar {
|
|
|
|
- _ = d.runereader.UnreadRune()
|
|
|
|
- b, _ := d.runereader.ReadByte()
|
|
|
|
- if DEBUG_INPUT {
|
|
|
|
- log.Printf("Reader (byte): %#v\n", b)
|
|
|
|
- }
|
|
|
|
- d.readerChannel <- rune(b)
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
|
|
+ RuneRead:
|
|
|
|
|
|
- if err == nil {
|
|
|
|
- if DEBUG_INPUT {
|
|
|
|
- log.Printf("Reader (rune): %#v\n", r)
|
|
|
|
- }
|
|
|
|
- d.readerChannel <- r
|
|
|
|
- continue
|
|
|
|
|
|
+ input, _, err = runeread.ReadRune()
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Printf("ReadRune: %#v\n", err)
|
|
|
|
+ // errors EOF
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if input == unicode.ReplacementChar {
|
|
|
|
+ runeread.UnreadRune()
|
|
|
|
+ b, _ := runeread.ReadByte()
|
|
|
|
+ if DEBUG_INPUT {
|
|
|
|
+ log.Printf("Reader (byte) >> %x\n", b)
|
|
}
|
|
}
|
|
- */
|
|
|
|
-
|
|
|
|
- // I'm not sure I care what the error is we're getting here...
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- if e, ok := err.(net.Error); ok && e.Timeout() {
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
|
|
+ d.readerChannel <- rune(b)
|
|
|
|
+ } else {
|
|
|
|
+ if DEBUG_INPUT {
|
|
|
|
+ log.Printf("Reader >> %x\n", input)
|
|
}
|
|
}
|
|
- */
|
|
|
|
|
|
+ d.readerChannel <- input
|
|
|
|
+ }
|
|
|
|
+ goto RuneRead
|
|
|
|
+
|
|
|
|
+ // buffer = append(buffer, readone[0])
|
|
|
|
|
|
/*
|
|
/*
|
|
- log.Printf("Reader ERR: %#v\n", err)
|
|
|
|
- d.ReaderClosed = true
|
|
|
|
- close(d.readerChannel)
|
|
|
|
- return
|
|
|
|
|
|
+ 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
|
|
|
|
+ }
|
|
*/
|
|
*/
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
-func Reader(handle int, readerChannel *chan byte) {
|
|
|
|
- // I don't need the select anymore. Let the read block.
|
|
|
|
- defer func() {
|
|
|
|
- if err := recover(); err != nil {
|
|
|
|
- log.Printf("Reader: %#v\n", err)
|
|
|
|
- }
|
|
|
|
- }()
|
|
|
|
|
|
+ // d.readerChannel <- rune(buffer[0])
|
|
|
|
|
|
- buffer := make([]byte, 1)
|
|
|
|
- for {
|
|
|
|
- // blocking read in go routine
|
|
|
|
- // why doesn't this end when I close the handle?
|
|
|
|
- read, err := syscall.Read(handle, buffer)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Printf("Reader ERR: %#v\n", err)
|
|
|
|
- close(*readerChannel)
|
|
|
|
- break
|
|
|
|
- }
|
|
|
|
- if read == 1 {
|
|
|
|
- *readerChannel <- buffer[0]
|
|
|
|
- } else {
|
|
|
|
- log.Printf("READ FAILED %d\n", read)
|
|
|
|
- close(*readerChannel)
|
|
|
|
- break
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
-// This doesn't work. Closing the handle does not unblock the syscall.Read above.
|
|
|
|
-func CloseReader(handle int) {
|
|
|
|
- defer func() {
|
|
|
|
- if err := recover(); err != nil {
|
|
|
|
- log.Printf("CloseReader: %#v\n", err)
|
|
|
|
- }
|
|
|
|
- }()
|
|
|
|
-
|
|
|
|
- syscall.Close(handle)
|
|
|
|
-}
|
|
|
|
-*/
|
|
|