Чтение записи фиксированного размера с обнаружением EOF - PullRequest
0 голосов
/ 07 февраля 2020

Мне нужно прочитать запись данных фиксированного размера. Если данные недоступны, это законное условие EOF (не ошибка). Если есть какие-то данные, но их недостаточно для заполнения буфера записи, функция должна вернуть ошибку UnexpectedEof. Функция будет неоднократно вызываться во входном потоке до тех пор, пока не встретится EOF.

Пример подписи (возвращаемое значение представляет EOF):

fn read_into(r: &mut impl Read, mut buff: &mut [u8])
    -> io::Result<bool>

Я ожидал, что это приведет к более или менее единичному вызов r.read_exact(buf), но это не работает, потому что результат ошибки UnexpectedEof не предоставляет информацию о том, сколько байтов было прочитано успешно. Я закончил со следующей реализацией ( детская площадка ):

use std::io::{self, Read};

fn read_into(r: &mut impl Read, mut buff: &mut [u8]) -> io::Result<bool> {
    let mut partial = false;
    while !buff.is_empty() {
        match r.read(buff)? {
            0 if partial => {
                return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Incomplete"));
            }
            0 => return Ok(true),
            len => {
                buff = &mut buff[len..];
                partial = true;
            }
        }
    }
    Ok(false)
}

Кажется, что много кода для обработки чтения записей фиксированного размера, поэтому мой вопрос: можно ли это сделать более элегантно?

Было бы вполне нормально потребовать BufRead, связанный с r, или даже иметь функцию, принимающую конкретную BufReader<R> struct.

...