diff --git a/programs/fileio.c b/programs/fileio.c index fe8165db6..c7b6936d5 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1386,6 +1386,17 @@ enum { FIO_RUST_GZIP_INVALID_PROJECTION = 5 }; +enum { + FIO_RUST_GZIP_DIAGNOSTIC_OK = 0, + FIO_RUST_GZIP_DIAGNOSTIC_INIT_ERROR = 1, + FIO_RUST_GZIP_DIAGNOSTIC_DEFLATE_ERROR = 2, + FIO_RUST_GZIP_DIAGNOSTIC_FINISH_ERROR = 3, + FIO_RUST_GZIP_DIAGNOSTIC_END_ERROR = 4, + FIO_RUST_GZIP_DIAGNOSTIC_INVALID_PROJECTION = 5, + FIO_RUST_GZIP_DIAGNOSTIC_UNKNOWN = 6 +}; +int FIO_rust_gzipCompressionDiagnostic(int status); + typedef void (*FIO_rust_gzip_read_fill_fn)( void* opaque, size_t requested, const unsigned char** buffer, size_t* loaded); typedef void (*FIO_rust_gzip_read_consume_fn)(void* opaque, size_t consumed); @@ -2844,6 +2855,7 @@ FIO_rust_compressGzipCallback(void* ress, const char* srcFileName, U64 compressedSize = 0; int zlibResult = Z_OK; int status; + int diagnostic; memset(&projection, 0, sizeof(projection)); projection.readOpaque = (void*)ressPtr->readCtx; @@ -2864,19 +2876,22 @@ FIO_rust_compressGzipCallback(void* ress, const char* srcFileName, status = FIO_rust_compressGzipFrame( &projection, srcFileName, srcFileSize, compressionLevel, readsize, &compressedSize, &zlibResult); - switch (status) { - case FIO_RUST_GZIP_OK: + diagnostic = FIO_rust_gzipCompressionDiagnostic(status); + switch (diagnostic) { + case FIO_RUST_GZIP_DIAGNOSTIC_OK: return compressedSize; - case FIO_RUST_GZIP_INIT_ERROR: + case FIO_RUST_GZIP_DIAGNOSTIC_INIT_ERROR: EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, zlibResult); - case FIO_RUST_GZIP_DEFLATE_ERROR: + case FIO_RUST_GZIP_DIAGNOSTIC_DEFLATE_ERROR: EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, zlibResult); - case FIO_RUST_GZIP_FINISH_ERROR: + case FIO_RUST_GZIP_DIAGNOSTIC_FINISH_ERROR: EXM_THROW(77, "zstd: %s: deflate error %d \n", srcFileName, zlibResult); - case FIO_RUST_GZIP_END_ERROR: + case FIO_RUST_GZIP_DIAGNOSTIC_END_ERROR: EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, zlibResult); + case FIO_RUST_GZIP_DIAGNOSTIC_INVALID_PROJECTION: + EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, zlibResult); default: - assert(status == FIO_RUST_GZIP_INVALID_PROJECTION); + assert(diagnostic == FIO_RUST_GZIP_DIAGNOSTIC_UNKNOWN); EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, zlibResult); } } diff --git a/rust/src/fileio_asyncio.rs b/rust/src/fileio_asyncio.rs index 6674b6672..b5830a50b 100644 --- a/rust/src/fileio_asyncio.rs +++ b/rust/src/fileio_asyncio.rs @@ -994,6 +994,29 @@ pub const FIO_RUST_GZIP_FINISH_ERROR: c_int = 3; pub const FIO_RUST_GZIP_END_ERROR: c_int = 4; pub const FIO_RUST_GZIP_INVALID_PROJECTION: c_int = 5; +pub const FIO_RUST_GZIP_DIAGNOSTIC_OK: c_int = 0; +pub const FIO_RUST_GZIP_DIAGNOSTIC_INIT_ERROR: c_int = 1; +pub const FIO_RUST_GZIP_DIAGNOSTIC_DEFLATE_ERROR: c_int = 2; +pub const FIO_RUST_GZIP_DIAGNOSTIC_FINISH_ERROR: c_int = 3; +pub const FIO_RUST_GZIP_DIAGNOSTIC_END_ERROR: c_int = 4; +pub const FIO_RUST_GZIP_DIAGNOSTIC_INVALID_PROJECTION: c_int = 5; +pub const FIO_RUST_GZIP_DIAGNOSTIC_UNKNOWN: c_int = 6; + +/// Classifies gzip compression results while leaving zlib error values and +/// the CLI exception text in the C callback. +#[no_mangle] +pub extern "C" fn FIO_rust_gzipCompressionDiagnostic(status: c_int) -> c_int { + match status { + FIO_RUST_GZIP_OK => FIO_RUST_GZIP_DIAGNOSTIC_OK, + FIO_RUST_GZIP_INIT_ERROR => FIO_RUST_GZIP_DIAGNOSTIC_INIT_ERROR, + FIO_RUST_GZIP_DEFLATE_ERROR => FIO_RUST_GZIP_DIAGNOSTIC_DEFLATE_ERROR, + FIO_RUST_GZIP_FINISH_ERROR => FIO_RUST_GZIP_DIAGNOSTIC_FINISH_ERROR, + FIO_RUST_GZIP_END_ERROR => FIO_RUST_GZIP_DIAGNOSTIC_END_ERROR, + FIO_RUST_GZIP_INVALID_PROJECTION => FIO_RUST_GZIP_DIAGNOSTIC_INVALID_PROJECTION, + _ => FIO_RUST_GZIP_DIAGNOSTIC_UNKNOWN, + } +} + const FIO_RUST_GZIP_Z_OK: c_int = 0; const FIO_RUST_GZIP_Z_STREAM_END: c_int = 1; const FIO_RUST_GZIP_Z_BUF_ERROR: c_int = -5; @@ -5271,6 +5294,39 @@ mod tests { } } + #[test] + fn gzip_compression_status_diagnostic_preserves_cli_mapping() { + for (status, diagnostic) in [ + (FIO_RUST_GZIP_OK, FIO_RUST_GZIP_DIAGNOSTIC_OK), + ( + FIO_RUST_GZIP_INIT_ERROR, + FIO_RUST_GZIP_DIAGNOSTIC_INIT_ERROR, + ), + ( + FIO_RUST_GZIP_DEFLATE_ERROR, + FIO_RUST_GZIP_DIAGNOSTIC_DEFLATE_ERROR, + ), + ( + FIO_RUST_GZIP_FINISH_ERROR, + FIO_RUST_GZIP_DIAGNOSTIC_FINISH_ERROR, + ), + (FIO_RUST_GZIP_END_ERROR, FIO_RUST_GZIP_DIAGNOSTIC_END_ERROR), + ( + FIO_RUST_GZIP_INVALID_PROJECTION, + FIO_RUST_GZIP_DIAGNOSTIC_INVALID_PROJECTION, + ), + ] { + assert_eq!(FIO_rust_gzipCompressionDiagnostic(status), diagnostic); + } + + for status in [-1, 99] { + assert_eq!( + FIO_rust_gzipCompressionDiagnostic(status), + FIO_RUST_GZIP_DIAGNOSTIC_UNKNOWN + ); + } + } + #[test] fn lzma_compression_status_diagnostic_preserves_cli_mapping() { for (status, diagnostic) in [