我正在编写一个关于Google Brotli解压缩算法的Rust实现,该算法在流的末尾使用固定数量的“隐式零”来启用某些优化。
Google C实现使用各种计数器的意大利面条代码执行此操作,但我想在Rust std :: io库中使用适配器。类似的东西:
pub struct StreamBitReader<R> {
reader: Chain<R,Take<Repeat>>,
...
}
其中'R'是位读取器结构包装的基础Read
。但是,在许多情况下,解压缩算法会检查它是否“溢出”了流,它通过检查读取的隐式零字节数来实现。这在安全的Rust中似乎是不可能的,因为除非我遗漏了某些东西,否则无法获得Chain
的组件的引用。
构造Chain
时,它将获取(移动)基础Read
结构的所有权,然后隐藏在私有成员中。
有没有办法构建Take<Repeat>
部分,即使在limit()
适配器获得所有权后,我也可以访问Take
Chain
的fn。
答案 0 :(得分:1)
我知道一种方式,但我认为它不适合你的目标。
use std::io::{self, Read};
fn main() {
let file = io::empty();
let zeroes = io::repeat(0);
let mut ten_zeroes = zeroes.take(10);
{
let mut with_zeroes = file.chain(ten_zeroes.by_ref());
let mut buf = [0; 5];
with_zeroes.read(&mut buf);
}
println!("{}", ten_zeroes.limit());
}
密钥为Read::by_ref
,返回可变引用。 Read
是针对实现Read
的类型的任何可变引用而实现的,因此您可以将引用的所有权提供给Chain
。
诀窍是你必须先破坏Chain
才能再次使用内部对象。将它存储在结构中也是非常痛苦/不可能的。
您最好的选择可能是编写自己的ZeroPadded
适配器,其中包含Chain
,Repeat
和Take
并提供limit
方法。
如果没有其他人提供更好的答案,我还可以看到在适配器上添加方法的功能请求。使用into_inner
方法消耗适配器并返回包装的项目并不罕见,但您也可以使用as_inner
返回对包装对象的引用。