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() { file.Read(b[0:1]) if bitmatch(b[0], 0b00000000, 1) { channel <- b[0:1] } else if bitmatch(b[0], 0b11000000, 3) { file.Read(b[1:2]) channel <- b[0:2] } else if bitmatch(b[0], 0b11100000, 4) { file.Read(b[1:3]) channel <- b[0:3] } else if bitmatch(b[0], 0b11110000, 5) { file.Read(b[1:4]) channel <- b[0:4] } } } // 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 }