libzstd-rs-sys 0.0.1-prerelease.1

a rust implementation of zstd compression and decompression
Documentation
use std::ffi::CStr;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::sync::{Mutex, OnceLock};

use libzstd_rs_sys::lib::common::zstd_trace::{ZSTD_Trace, ZSTD_TraceCtx};
use libzstd_rs_sys::lib::compress::zstd_compress::{
    ZSTD_CCtxParams_getParameter, ZSTD_CCtx_params_s, ZSTD_CCtx_s,
};
use libzstd_rs_sys::lib::decompress::ZSTD_DCtx;
use libzstd_rs_sys::lib::zstd::ZSTD_cParameter;

use crate::timefn::{PTime, UTIL_clockSpanNano, UTIL_getTime, UTIL_time_t};
use crate::util::UTIL_isRegularFile;

pub type ZSTD_CCtx = ZSTD_CCtx_s;
pub type ZSTD_CCtx_params = ZSTD_CCtx_params_s;
static g_traceFile: Mutex<Option<File>> = Mutex::new(None);
static g_enableTime: OnceLock<UTIL_time_t> = OnceLock::new();

pub unsafe fn TRACE_enable(filename: *const core::ffi::c_char) {
    let writeHeader = (UTIL_isRegularFile(filename) == 0) as core::ffi::c_int;
    let mut traceFile = g_traceFile.lock().unwrap();
    assert!(traceFile.is_none());
    let traceFile = traceFile.insert(
        OpenOptions::new()
            .append(true)
            .open(CStr::from_ptr(filename).to_str().unwrap())
            .unwrap(),
    );
    if writeHeader != 0 {
        writeln!(
            traceFile,
            "Algorithm, Version, Method, Mode, Level, Workers, Dictionary Size, Uncompressed Size, Compressed Size, Duration Nanos, Compression Ratio, Speed MB/s"
        ).unwrap();
    }
    g_enableTime.set(UTIL_getTime()).map_err(|_| ()).unwrap();
}
pub unsafe fn TRACE_finish() {
    let _ = g_traceFile.lock().unwrap().take();
}
unsafe fn TRACE_log(method: &str, duration: PTime, trace: &ZSTD_Trace) {
    let mut level = 0;
    let mut workers = 0;
    let ratio =
        trace.uncompressedSize as core::ffi::c_double / trace.compressedSize as core::ffi::c_double;
    let speed =
        trace.uncompressedSize as core::ffi::c_double * 1000.0 / duration as core::ffi::c_double;
    if !(trace.params).is_null() {
        ZSTD_CCtxParams_getParameter(
            trace.params,
            ZSTD_cParameter::ZSTD_c_compressionLevel,
            &mut level,
        );
        ZSTD_CCtxParams_getParameter(
            trace.params,
            ZSTD_cParameter::ZSTD_c_nbWorkers,
            &mut workers,
        );
    }
    writeln!(
        g_traceFile.lock().unwrap().as_mut().unwrap(),
        "zstd, {}, {}, {}, {}, {}, {}, {}, {}, {}, {:.2}, {:.2}",
        trace.version,
        method,
        if trace.streaming != 0 {
            "streaming"
        } else {
            "single-pass"
        },
        level,
        workers,
        trace.dictionarySize as core::ffi::c_ulonglong,
        trace.uncompressedSize as core::ffi::c_ulonglong,
        trace.compressedSize as core::ffi::c_ulonglong,
        duration as core::ffi::c_ulonglong,
        ratio,
        speed,
    )
    .unwrap();
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_trace_compress_begin(_cctx: *const ZSTD_CCtx) -> ZSTD_TraceCtx {
    g_enableTime
        .get()
        .map_or(0, |&time| UTIL_clockSpanNano(time) as ZSTD_TraceCtx)
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_trace_compress_end(ctx: ZSTD_TraceCtx, trace: *const ZSTD_Trace) {
    let beginNanos = ctx as PTime;
    let endNanos = UTIL_clockSpanNano(*g_enableTime.get().unwrap());
    let durationNanos = if endNanos > beginNanos {
        endNanos.wrapping_sub(beginNanos)
    } else {
        0
    };
    TRACE_log("compress", durationNanos, &*trace);
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_trace_decompress_begin(_dctx: *const ZSTD_DCtx) -> ZSTD_TraceCtx {
    g_enableTime
        .get()
        .map_or(0, |&time| UTIL_clockSpanNano(time) as ZSTD_TraceCtx)
}
#[no_mangle]
pub unsafe extern "C" fn ZSTD_trace_decompress_end(ctx: ZSTD_TraceCtx, trace: *const ZSTD_Trace) {
    let beginNanos = ctx as PTime;
    let endNanos = UTIL_clockSpanNano(*g_enableTime.get().unwrap());
    let durationNanos = if endNanos > beginNanos {
        endNanos.wrapping_sub(beginNanos)
    } else {
        0
    };
    TRACE_log("decompress", durationNanos, &*trace);
}