2024-04-23 22:10:40 -06:00
|
|
|
package ncurses
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"sync/atomic"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bitmatch(b byte, pattern byte, length int) bool {
|
|
|
|
mask := ^(byte(1 << (8 - length)) - 1)
|
|
|
|
return (b ^ pattern) & mask == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func UTF8Listen(file *os.File, channel chan []byte, active *atomic.Bool) {
|
|
|
|
b := [4]byte{}
|
|
|
|
for active.Load() {
|
2024-04-23 22:24:38 -06:00
|
|
|
out := make([]byte, 4)
|
2024-04-23 22:10:40 -06:00
|
|
|
file.Read(b[0:1])
|
|
|
|
if bitmatch(b[0], 0b00000000, 1) {
|
2024-04-23 22:24:38 -06:00
|
|
|
copy(out, b[0:1])
|
|
|
|
channel <- out[0:1]
|
2024-04-23 22:10:40 -06:00
|
|
|
} else if bitmatch(b[0], 0b11000000, 3) {
|
|
|
|
file.Read(b[1:2])
|
2024-04-23 22:24:38 -06:00
|
|
|
copy(out, b[0:2])
|
|
|
|
channel <- out[0:2]
|
2024-04-23 22:10:40 -06:00
|
|
|
} else if bitmatch(b[0], 0b11100000, 4) {
|
|
|
|
file.Read(b[1:3])
|
2024-04-23 22:24:38 -06:00
|
|
|
copy(out, b[0:3])
|
|
|
|
channel <- out[0:3]
|
2024-04-23 22:10:40 -06:00
|
|
|
} else if bitmatch(b[0], 0b11110000, 5) {
|
|
|
|
file.Read(b[1:4])
|
2024-04-23 22:24:38 -06:00
|
|
|
copy(out, b[0:4])
|
|
|
|
channel <- out[0:4]
|
2024-04-23 22:10:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// To cleanup, set active to false then close the channel
|
|
|
|
func UTF8Listener(buffer int, file *os.File) (chan []byte, *atomic.Bool) {
|
|
|
|
channel := make(chan []byte, buffer)
|
|
|
|
active := new(atomic.Bool)
|
|
|
|
active.Store(true)
|
|
|
|
|
|
|
|
go UTF8Listen(file, channel, active)
|
|
|
|
|
|
|
|
return channel, active
|
|
|
|
}
|