如何从mio事件循环中的无缓冲文件中读取Unicode代码点?

时间:2016-12-19 14:33:23

标签: unicode rust event-loop mio

我想用mio crate读取按键,因为它们以无缓冲的方式到达。我已经有了unbuffer stdin的代码,并且我已经搭建了事件循环:

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的部分?有几个挑战:

  • 我怎么知道要读取多少字节?我不确定mio告诉我这个。
  • 如何处理部分代码点,其中read跨越多字节字符。

可能有效的一种解决方案是使用oneshot事件而不是edge事件,然后将每个事件的一个字节读入临时缓冲区。每次缓冲区作为完整的代码点都有意义时,我可以将其转换为char并将其存储起来,并清除暂存缓冲区。

但这似乎有点低效。什么是最好的方式?

0 个答案:

没有答案