Как прочитать кодовые точки Unicode из небуферизованного файла в цикле событий mio?

Я хотел бы использовать mio-ящик для чтения нажатий клавиш, когда они поступают небуферизованным способом. У меня уже есть код для отмены буфера стандартного ввода, и я создал цикл обработки событий:

extern crate mio;
extern crate termios;

use termios::{Termios, TCSANOW, ICANON, ECHO, tcsetattr};
use mio::*;
use mio::unix::EventedFd;

fn unbuffer_stdin() {
    let termios = Termios::from_fd(0).unwrap();
    let mut new_termios = termios.clone();
    new_termios.c_lflag &= !(ICANON | ECHO);
    tcsetattr(0, TCSANOW, &mut new_termios).unwrap();
}

fn main() {
    let stdin = 0;
    unbuffer_stdin();

    let poll = Poll::new().unwrap();

    const STDIN: Token = Token(0);
    let ev_fd = EventedFd(&stdin);
    poll.register(&ev_fd, STDIN, Ready::readable(), PollOpt::edge()).unwrap();

    let mut events = Events::with_capacity(1024);
    loop {
        poll.poll(&mut events, None).unwrap();

        for event in events.iter() {
            match event.token() {
                STDIN => {
                    println!("keypress");
                    // XXX read in ready codepoints to a buffer
                }
                _ => unreachable!(),
            }
        }
    }
}

Как реализовать часть, отмеченную XXX? Есть несколько проблем:

  • Как узнать, сколько байтов нужно прочитать? Я не уверен, что Мио говорит мне это.
  • Как мне работать с частичными кодовыми точками, где чтение занимает многобайтовый символ.

Одним из решений, которое может работать, является использование oneshot события вместо edge события, а затем прочитать один байт на событие во временный буфер. Каждый раз, когда буфер имеет смысл в качестве полной кодовой точки, я мог бы затем преобразовать его в char и сохраните его, и очистите буфер.

Это кажется немного неэффективным, хотя. Какой самый лучший способ?

0 ответов

Другие вопросы по тегам