- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 nom 编写一个 HTTP2 解析器。我正在实现 HPACK header 压缩,但无法理解如何使用 nom 中的位字段。
例如,Indexed Header Field Representation以第一位为 1 开始。
fn indexed_header_field_tag(i: &[u8]) -> IResult<&[u8], ()> {
nom::bits::streaming::tag(1, 1)(i)
}
这给了我一个我不太明白的编译器警告(老实说,我对 nom 中的类型有一些问题):
error[E0308]: mismatched types
--> src/parser.rs:179:41
|
179 | nom::bits::streaming::tag(1, 1)(i)
| ^ expected tuple, found `&[u8]`
|
= note: expected tuple `(_, usize)`
found reference `&[u8]`
我应该在这里放什么?
另一个例子是:
fn take_2_bits(input: &[u8]) -> IResult<&[u8], u64> {
nom::bits::bits(nom::bits::streaming::take::<_, _, _, (_, _)>(2usize))(input)
}
在这里,我的问题是第一个字节的剩余位被丢弃,即使我想进一步处理它们。
我想我可以用按位与手动完成,但用 nom 会更好。
我尝试过以下方法,但这给了我很多编译器警告:
fn check_tag(input: &[u8]) -> IResult<&[u8], ()> {
use nom::bits::{bits, bytes, complete::take_bits, complete::tag};
let converted_bits = bits(take_bits(2usize))(2)?;
let something = tag(0x80, 2)(converted_bits);
nom::bits::bytes(something)
}
(灵感来自 https://docs.rs/nom/5.1.2/nom/bits/fn.bytes.html )。
它告诉我,没有 complete::take_bits
(我猜只有文档有点偏离那里),但它也告诉我:
368 | let converted_bits = bits(take_bits(2usize))(2)?;
| ^ the trait `nom::traits::Slice<std::ops::RangeFrom<usize>>` is not implemented for `{integer}`
和其他错误,但这只是由于第一个错误导致的。
最佳答案
面向位的接口(interface)(例如 take
)接受一个元组 (I, usize)
, representing (input, bit_offset)
, 所以你需要使用类似 bits
的函数将输入从 i
转换为 (i, 0)
,然后通过忽略当前字节中的任何剩余位将输出转换回字节。
第二个问题见How can I combine nom parsers to get a more bit-oriented interface to the data?的评论: 仅当需要在位和字节之间切换时才使用bits
,并使面向位的函数使用面向位的输入。
use nom::{IResult, bits::{bits, complete::{take, tag}}};
fn take_2_bits(i: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
take(2usize)(i)
}
fn check_tag(i: (&[u8], usize)) -> IResult<(&[u8], usize), u8> {
tag(0x01, 1usize)(i)
}
fn do_everything_bits(i: (&[u8], usize)) -> IResult<(&[u8], usize), (u8, u8)> {
let (i, a) = take_2_bits(i)?;
let (i, b) = check_tag(i)?;
Ok((i, (a, b)))
}
fn do_everything_bytes(i: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits(do_everything_bits)(i)
}
关于rust - 如何在 nom 中取 N 位字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62763705/
我是一名优秀的程序员,十分优秀!