/* * Link and run through the installed-style static archive, rather than the * direct C-object-plus-Rust-archive test path used by the other test tools. */ #include #include #include #include "zstd.h" static int checkError(size_t result, const char* operation) { if (!ZSTD_isError(result)) return 0; fprintf(stderr, "%s: %s\n", operation, ZSTD_getErrorName(result)); return 1; } int main(void) { enum { sourceSize = 64 * 1024 }; unsigned char source[sourceSize]; size_t const compressedCapacity = ZSTD_compressBound(sourceSize); void* compressed = malloc(compressedCapacity); void* restored = malloc(sourceSize); size_t compressedSize; size_t restoredSize; ZSTD_CCtx* cctx = NULL; ZSTD_DDict* ddict; size_t index; if (compressed == NULL || restored == NULL) { fputs("allocation failed\n", stderr); free(restored); free(compressed); return 1; } for (index = 0; index < sourceSize; ++index) { source[index] = (unsigned char)((index * 13 + index / 97) & 0x1F); } compressedSize = ZSTD_compress(compressed, compressedCapacity, source, sourceSize, 3); if (checkError(compressedSize, "ZSTD_compress")) goto cleanup; restoredSize = ZSTD_decompress(restored, sourceSize, compressed, compressedSize); if (checkError(restoredSize, "ZSTD_decompress")) goto cleanup; if (restoredSize != sourceSize || memcmp(source, restored, sourceSize) != 0) { fputs("round trip mismatch\n", stderr); goto cleanup; } cctx = ZSTD_createCCtx(); if (cctx == NULL) { fputs("CCtx creation failed\n", stderr); goto cleanup; } { ZSTD_inBuffer input = { source, sourceSize, 0 }; ZSTD_outBuffer output = { compressed, compressedCapacity, 0 }; size_t const remaining = ZSTD_compressStream2( cctx, &output, &input, ZSTD_e_end); if (checkError(remaining, "ZSTD_compressStream2") || remaining != 0 || input.pos != input.size) { fputs("streaming end call did not complete\n", stderr); goto cleanup; } restoredSize = ZSTD_decompress( restored, sourceSize, compressed, output.pos); if (checkError(restoredSize, "ZSTD_decompress(stream)") || restoredSize != sourceSize || memcmp(source, restored, sourceSize) != 0) { fputs("streaming round trip mismatch\n", stderr); goto cleanup; } } /* The Rust end path resets the C-owned session before returning. */ { ZSTD_inBuffer input = { source, sourceSize, 0 }; ZSTD_outBuffer output = { compressed, compressedCapacity, 0 }; size_t const remaining = ZSTD_compressStream2( cctx, &output, &input, ZSTD_e_end); if (checkError(remaining, "ZSTD_compressStream2(reuse)") || remaining != 0 || input.pos != input.size) { fputs("streaming context reuse failed\n", stderr); goto cleanup; } } if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1))) { fputs("advanced parameter setup failed\n", stderr); goto cleanup; } { ZSTD_inBuffer input = { source, sourceSize, 0 }; ZSTD_outBuffer output = { compressed, compressedCapacity, 0 }; size_t const remaining = ZSTD_compressStream2( cctx, &output, &input, ZSTD_e_end); if (checkError(remaining, "ZSTD_compressStream2(checksum)") || remaining != 0 || input.pos != input.size) { fputs("advanced stream fallback did not complete\n", stderr); goto cleanup; } restoredSize = ZSTD_decompress( restored, sourceSize, compressed, output.pos); if (checkError(restoredSize, "ZSTD_decompress(checksum)") || restoredSize != sourceSize || memcmp(source, restored, sourceSize) != 0) { fputs("advanced stream fallback mismatch\n", stderr); goto cleanup; } } if (ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters) != 0) { fputs("CCtx parameter reset failed\n", stderr); goto cleanup; } if (ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters) != 0) { fputs("CCtx parameter reset failed\n", stderr); goto cleanup; } { ZSTD_inBuffer input = { source, sourceSize, 0 }; ZSTD_outBuffer output = { compressed, compressedCapacity - 1, 0 }; size_t const remaining = ZSTD_compressStream2( cctx, &output, &input, ZSTD_e_end); if (checkError(remaining, "ZSTD_compressStream2(short output)") || remaining != 0 || input.pos != input.size) { fputs("short-output stream fallback did not complete\n", stderr); goto cleanup; } restoredSize = ZSTD_decompress( restored, sourceSize, compressed, output.pos); if (checkError(restoredSize, "ZSTD_decompress(short output)") || restoredSize != sourceSize || memcmp(source, restored, sourceSize) != 0) { fputs("short-output stream fallback mismatch\n", stderr); goto cleanup; } } if (ZSTD_freeCCtx(cctx) != 0) { fputs("CCtx cleanup failed\n", stderr); cctx = NULL; goto cleanup; } cctx = NULL; /* This must pull the Rust DDict object and resolve its C helper cycle. */ ddict = ZSTD_createDDict(NULL, 0); if (ddict == NULL || ZSTD_freeDDict(ddict) != 0) { fputs("DDict lifecycle failed\n", stderr); goto cleanup; } free(restored); free(compressed); return 0; cleanup: ZSTD_freeCCtx(cctx); free(restored); free(compressed); return 1; }