rustlol 0.1.1

A wad files lib
Documentation
use std::fs::File;
use std::io::Write;
use crate::lol::io::buffer::Buffer;

/// 测试zstd兼容性的函数
pub fn test_zstd_compatibility() {
    println!("=== ZSTD 兼容性测试 ===");
    
    // 测试数据
    let test_data = b"Hello, World! This is a test for zstd compression compatibility with pyzstd.";
    println!("原始数据长度: {}", test_data.len());
    println!("原始数据: {:?}", std::str::from_utf8(test_data).unwrap());
    
    // 测试不同的压缩级别
    let levels = [1, 3, 6, 9];
    
    for level in levels {
        println!("\n--- 测试压缩级别 {} ---", level);
        test_compression_level(test_data, level);
    }
    
    // 测试与pyzstd的兼容性
    test_pyzstd_compatibility(test_data);
}

fn test_compression_level(data: &[u8], level: i32) {
    let mut buffer = Buffer::default();
    
    // 压缩数据
    match buffer.write_compress_zstd(0, data, data.len(), level) {
        Ok(()) => {
            let compressed = &buffer.impl_.vec;
            println!("压缩成功 - 级别: {}, 原始: {} bytes, 压缩后: {} bytes, 压缩比: {:.2}%", 
                level, data.len(), compressed.len(), 
                (compressed.len() as f64 / data.len() as f64) * 100.0);
            
            // 检查zstd魔数
            if compressed.len() >= 4 {
                let magic = &compressed[0..4];
                println!("魔数: {:02X} {:02X} {:02X} {:02X}", magic[0], magic[1], magic[2], magic[3]);
                
                if magic == [0x28, 0xB5, 0x2F, 0xFD] {
                    println!("✓ 魔数正确");
                } else {
                    println!("✗ 魔数错误");
                }
            }
            
            // 保存到文件供pyzstd测试
            let filename = format!("test_level_{}.zst", level);
            if let Ok(mut file) = File::create(&filename) {
                if file.write_all(compressed).is_ok() {
                    println!("已保存到文件: {}", filename);
                }
            }
            
            // 测试解压缩
            test_decompression(compressed, data);
            
        },
        Err(e) => {
            println!("压缩失败 - 级别: {}, 错误: {}", level, e);
        }
    }
}

fn test_decompression(compressed: &[u8], original: &[u8]) {
    let mut buffer = Buffer::default();
    
    match buffer.write_decompress_zstd(0, original.len(), compressed, compressed.len()) {
        Ok(()) => {
            let decompressed = &buffer.impl_.vec[0..original.len()];
            if decompressed == original {
                println!("✓ 解压缩成功,数据一致");
            } else {
                println!("✗ 解压缩失败,数据不一致");
                println!("期望: {:?}", std::str::from_utf8(original).unwrap_or("无效UTF-8"));
                println!("实际: {:?}", std::str::from_utf8(decompressed).unwrap_or("无效UTF-8"));
            }
        },
        Err(e) => {
            println!("✗ 解压缩失败: {}", e);
        }
    }
}

fn test_pyzstd_compatibility(data: &[u8]) {
    println!("\n=== PYZSTD 兼容性测试 ===");
    
    // 使用与pyzstd相同的默认设置
    let mut buffer = Buffer::default();
    
    // pyzstd默认使用压缩级别3
    match buffer.write_compress_zstd(0, data, data.len(), 3) {
        Ok(()) => {
            let compressed = &buffer.impl_.vec;
            
            // 保存为pyzstd兼容格式
            if let Ok(mut file) = File::create("pyzstd_compatible.zst") {
                if file.write_all(compressed).is_ok() {
                    println!("已生成pyzstd兼容文件: pyzstd_compatible.zst");
                    println!("请使用以下Python代码测试:");
                    println!("```python");
                    println!("import pyzstd");
                    println!("with open('pyzstd_compatible.zst', 'rb') as f:");
                    println!("    compressed_data = f.read()");
                    println!("try:");
                    println!("    decompressed = pyzstd.decompress(compressed_data)");
                    println!("    print('解压缩成功:', decompressed.decode('utf-8'))");
                    println!("except Exception as e:");
                    println!("    print('解压缩失败:', e)");
                    println!("```");
                }
            }
            
            // 分析压缩数据的结构
            analyze_zstd_structure(compressed);
        },
        Err(e) => {
            println!("生成pyzstd兼容数据失败: {}", e);
        }
    }
}

fn analyze_zstd_structure(data: &[u8]) {
    println!("\n--- ZSTD 数据结构分析 ---");
    
    if data.len() < 4 {
        println!("数据太短,无法分析");
        return;
    }
    
    // 魔数
    let magic = &data[0..4];
    println!("魔数: {:02X} {:02X} {:02X} {:02X}", magic[0], magic[1], magic[2], magic[3]);
    
    if magic == [0x28, 0xB5, 0x2F, 0xFD] {
        println!("✓ 标准zstd魔数");
        
        if data.len() >= 6 {
            // 帧头描述符
            let frame_header_descriptor = data[4];
            println!("帧头描述符: 0x{:02X}", frame_header_descriptor);
            
            let fcs_flag = (frame_header_descriptor >> 6) & 0x01;
            let single_segment = (frame_header_descriptor >> 5) & 0x01;
            let content_checksum = (frame_header_descriptor >> 2) & 0x01;
            let dict_id_flag = frame_header_descriptor & 0x03;
            
            println!("  - 帧内容大小标志: {}", fcs_flag);
            println!("  - 单段标志: {}", single_segment);
            println!("  - 内容校验和: {}", content_checksum);
            println!("  - 字典ID标志: {}", dict_id_flag);
        }
    } else {
        println!("✗ 非标准zstd魔数");
    }
    
    // 显示前16个字节的十六进制
    let display_len = data.len().min(16);
    print!("{}字节: ", display_len);
    for i in 0..display_len {
        print!("{:02X} ", data[i]);
    }
    println!();
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn run_compatibility_test() {
        test_zstd_compatibility();
    }
}
/// 测试不同的压缩方法
 pub fn test_different_compression_methods() {
    println!("\n=== 测试不同压缩方法 ===");
    
    let test_data = b"Hello, World! This is a test for zstd compression compatibility.";
    
    // 方法1: 标准压缩
    test_compression_method("标准压缩", test_data, |buffer, data| {
        buffer.write_compress_zstd(0, data, data.len(), 3)
    });
    
    // 方法2: 兼容压缩
    test_compression_method("兼容压缩", test_data, |buffer, data| {
        buffer.write_compress_zstd_compatible(0, data, data.len(), 3)
    });
    
    // 方法3: 简单压缩
    test_compression_method("简单压缩", test_data, |buffer, data| {
        buffer.write_compress_zstd_no_dict(0, data, data.len(), 3)
    });
}

fn test_compression_method<F>(name: &str, data: &[u8], compress_fn: F) 
where 
    F: Fn(&mut Buffer, &[u8]) -> Result<(), std::io::Error>
{
    println!("\n--- {} ---", name);
    let mut buffer = Buffer::default();
    
    match compress_fn(&mut buffer, data) {
        Ok(()) => {
            let compressed = &buffer.impl_.vec;
            println!("压缩成功: {} -> {} bytes", data.len(), compressed.len());
            
            // 保存文件
            let filename = format!("{}.zst", name.replace(" ", "_"));
            if let Ok(mut file) = std::fs::File::create(&filename) {
                use std::io::Write;
                if file.write_all(compressed).is_ok() {
                    println!("已保存: {}", filename);
                }
            }
        },
        Err(e) => {
            println!("压缩失败: {}", e);
        }
    }
}