15 个不稳定版本 (4 个破坏性更新)

0.5.0 2022年3月21日
0.4.0 2022年3月21日
0.3.1 2021年12月30日
0.3.0 2021年10月9日
0.1.3 2020年10月30日

#449 in 解析器实现

Download history 2207/week @ 2024-03-14 2248/week @ 2024-03-21 2027/week @ 2024-03-28 2231/week @ 2024-04-04 2890/week @ 2024-04-11 3135/week @ 2024-04-18 2369/week @ 2024-04-25 2083/week @ 2024-05-02 2593/week @ 2024-05-09 2578/week @ 2024-05-16 2260/week @ 2024-05-23 2148/week @ 2024-05-30 2191/week @ 2024-06-06 2029/week @ 2024-06-13 2238/week @ 2024-06-20 1410/week @ 2024-06-27

每月8,273次下载
用于 7 个crate (6 个直接)

Apache-2.0

48KB
394

fixed-buffer

crates.io version license: Apache 2.0 unsafe forbidden pipeline status

这是一个 Rust 库,具有固定大小的缓冲区,适用于网络协议解析器和文件解析器。

特性

  • 禁止(不安全代码)
  • 仅依赖 std
  • 将字节写入缓冲区并读取它们
  • 位于栈上
  • 不分配
  • 使用它读取流,搜索分隔符,并将剩余字节保存用于下一次读取。
  • 无宏
  • 良好的测试覆盖率(99%)
  • 通过启用 cargo 功能 async-std-featurefutures-iosmol-featuretokio 支持异步。

限制

  • 不是一个循环缓冲区。您可以定期调用 shift() 将未读取的字节移动到缓冲区的开头。

示例

读取并处理来自远程客户端的请求

use fixed_buffer::{deframe_line, FixedBuf};
use std::io::Error;
use std::net::TcpStream;

fn handle_conn(mut tcp_stream: TcpStream) -> Result<(), Error> {
    let mut buf: FixedBuf<4096> = FixedBuf::new();
    loop {
        // Read a line
        // and leave leftover bytes in `buf`.
        let line_bytes = match buf.read_frame(
            &mut tcp_stream, deframe_line)? {
                Some(line_bytes) => line_bytes,
                None => return Ok(()),
            };
        let request = Request::parse(line_bytes)?;
        handle_request(request)?;
    }
}

完整的示例,请参阅 tests/server.rs.

读取并处理记录

use fixed_buffer::FixedBuf;
use std::io::{Error, ErrorKind, Read};
use std::net::TcpStream;

fn try_process_record(b: &[u8]) -> Result<usize, Error> {
    if b.len() < 2 {
        return Ok(0);
    }
    if b.starts_with("ab".as_bytes()) {
        println!("found record");
        Ok(2)
    } else {
        Err(Error::new(ErrorKind::InvalidData, "bad record"))
    }
}

fn read_and_process<R: Read>(mut input: R) -> Result<(), Error> {
    let mut buf: FixedBuf<1024> = FixedBuf::new();
    loop {
        // Read a chunk into the buffer.
        if buf.copy_once_from(&mut input)? == 0 {
            return if buf.len() == 0 {
                // EOF at record boundary
                Ok(())
            } else {
                // EOF in the middle of a record
                Err(Error::from(
                    ErrorKind::UnexpectedEof))
            };
        }
        // Process records in the buffer.
        loop {
            let num_to_consume =
                try_process_record(buf.readable())?;
            if num_to_consume == 0 {
                break;
            }
            buf.try_read_exact(num_to_consume).unwrap();
        }
        // Shift data in the buffer to free up
        // space at the end for writing.
        buf.shift();
    }
}
#

From<[u8; SIZE]> 的实现对测试很有用。示例

use core::convert::From;
assert_eq!(3, FixedBuf::from(*b"abc").len());

替代方案

变更日志

  • v0.5.0 - 将 ReadWriteChainReadWriteTake 移动到新的 read-write-ext 包。
  • v0.4.0
    • <&[u8]>
    • write_bytes 修改为 AsRef<[u8]>
    • try_read_exact 修改为 read_and_copy_exact
    • try_read_bytes 修改为 try_read_exact
    • 移除 emptyfilledread_byteread_bytestry_parsewrite_str
    • deframe 允许在不返回框架的情况下消耗字节
    • write_bytes 尽可能写入字节,并在无法写入任何字节时返回新的 NoWritableSpace 错误。移除 NotEnoughSpaceError。现在该方法的行为类似于 std::io::Write::write
  • v0.3.1 - 实现 From<NotEnoughSpaceError>From<MalformedInputError>String
更早的变更日志条目
  • v0.3.0 - 破坏性 API 变更
    • 将类型参数更改为常量缓冲区大小。例如:FixedBuf<1024>
    • 移除 new 参数。
    • 移除 capacity
    • 移除 Copy 实现。
    • writable 返回类型更改为 &mut [u8]
  • v0.2.3
  • v0.2.2 - 在 README 中添加徽章
  • v0.2.1 - 添加 deframemem,这是 AsyncFixedBuf::read_frame 所必需的。
  • v0.2.0
  • v0.1.7 - 添加 FixedBuf::escape_ascii
  • v0.1.6 - 添加 filled 构造函数。
  • v0.1.5 - 将 read_delimited 修改为返回 Option<&[u8]>,以实现干净的 EOF 处理。
  • v0.1.4 - 添加 clear()
  • v0.1.3
    • 感谢 freax13 对这些更改
      • 支持任何缓冲区大小。现在您可以使用 FixedBuf<[u8; 42]>
      • 支持任何 AsRef<[u8]> + AsMut<[u8]> 内部内存值
        • [u8;N]
        • Box<[u8; N]>
        • &mut [u8]
        • Vec<u8>
    • new_with_mem 重命名为 new。使用 FixedBuf::default() 来构造任何 FixedBuf<T: Default>,这包括 大小最多为 32 的数组
  • v0.1.2 - 更新文档。
  • v0.1.1 - 首次发布版本

待办事项

发布流程

  1. 编辑Cargo.toml并提升版本号。
  2. 运行../release.sh

许可证:Apache-2.0

依赖项

~0–1.2MB
~19K SLoC