#zip-archive #zip #parser #file-format #data-file #no-std

no-std zip_parser

一个支持 no_std 环境、流解析和查找的 zip 文件格式解析器

9 个不稳定版本 (3 个重大更改)

0.4.3 2023年2月20日
0.4.2 2023年1月6日
0.4.1 2022年11月10日
0.3.0 2022年11月5日
0.1.1 2022年1月25日

#878解析器实现

每月 39 次下载

MIT 许可证

89KB
952

包含 (Zip 文件, 43KB) test.zip

zip_parser

由 Rust 实现的 zip 文件格式解析器,支持流解析和 no_std 环境。

Parser 会在 zip 文件末尾搜索中心目录,如果可用 Seek。同时,它在不支持 Seek 的情况下支持顺序读取解析。所有在 std 环境中实现的类型都自动实现 Read,并且 Seek 也是一个特质。 PassiveParser 可以用于某些数据由其他任务接收的情况。

流解析

#[derive(Debug)]
struct DataBuffer {
    index: usize,
    pub buffer: Vec<u8>,
}

fn file_stream_parsing(mut file: File) {
    println!("*** get stream from file ***");
    let mut buffer = DataBuffer {
        index: 0,
        buffer: Vec::new(),
    };
    let file_size = file.read_to_end(&mut buffer.buffer).unwrap_or(0);
    println!("zip size: {} bytes", file_size);

    println!("SequentialParser:");
    parse(SequentialParser::<DataBuffer>::new(&mut buffer));

    println!("\n\nPassiveParser:");
    let mut parser = PassiveParser::<128>::new();
    parser.feed_data(
        &buffer.buffer,
        |evt| {
            match evt {
                ParserEvent::LocalFileHeader(file_index, file) => {
                    println!("#{}: {}({}/{} bytes)",
                    file_index, file.file_name().unwrap_or("Utf8EncodeErr"),
                        file.compressed_size, file.uncompressed_size);
                    true
                },
                ParserEvent::ParsingError(_file_index, e) => {
                    println!("error: {e}");
                    false
                },
                _ => {
                    // println!("unprocessed event: {evt:?}");
                    true
                },
            }
        }
    );
    println!(r#"zip file comment: "{}""#, parser.file_comment().unwrap())
}

fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() >= 2 {
        let file = File::open(args[1].as_str()).unwrap();
        file_stream_parsing(file);
    }
}

您只需将实现 Read 的流传递给 Parser::new(),然后您可以迭代它。有关更多详细信息,请参阅示例 stream_parsing

示例

Stream_parsing

  1. 来自 stdin
    cat test.zip | cargo run --features="std" --example stream_parsing
    
    或者您甚至可以 cat 多个 zip 文件
    cat test.zip test.zip | cargo run --features="std" --example stream_parsing
    
  2. 从文件中流解析(读取和 PassiveParser)
    cargo run --features="std" --example stream_parsing -- test.zip
    

被动解析

在示例 stream_parsing 中,有一个被动解析的例子:从文件中读取数据并将其 PassiveParser::feed_data 到解析器。

依赖关系

~645KB
~12K SLoC