Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <stddef.h> |
| 3 | #include <stdlib.h> |
Nick Terrell | 5cc85cf | 2016-12-10 19:31:55 -0800 | [diff] [blame] | 4 | #include <stdint.h> |
Yann Collet | c261f71 | 2016-12-12 00:25:07 +0100 | [diff] [blame] | 5 | #include "mem.h" |
| 6 | #define ZSTD_STATIC_LINKING_ONLY |
| 7 | #include "zstd.h" |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 8 | |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 9 | int compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) { |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 10 | ZSTD_inBuffer in = { data, size, 0 }; |
| 11 | while (in.pos < in.size) { |
| 12 | ZSTD_outBuffer tmp = out; |
| 13 | const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); |
| 14 | if (ZSTD_isError(rc)) { |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 15 | return 1; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 16 | } |
| 17 | } |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 18 | { |
| 19 | ZSTD_outBuffer tmp = out; |
| 20 | const size_t rc = ZSTD_flushStream(ctx, &tmp); |
| 21 | if (rc != 0) { return 1; } |
| 22 | } |
| 23 | return 0; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 24 | } |
| 25 | |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 26 | int main(int argc, const char** argv) { |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 27 | ZSTD_CStream *ctx; |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 28 | ZSTD_parameters params; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 29 | size_t rc; |
| 30 | unsigned windowLog; |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 31 | (void)argc; |
| 32 | (void)argv; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 33 | /* Create stream */ |
| 34 | ctx = ZSTD_createCStream(); |
| 35 | if (!ctx) { return 1; } |
| 36 | /* Set parameters */ |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 37 | memset(¶ms, 0, sizeof(params)); |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 38 | params.cParams.windowLog = 18; |
| 39 | params.cParams.chainLog = 13; |
| 40 | params.cParams.hashLog = 14; |
| 41 | params.cParams.searchLog = 1; |
| 42 | params.cParams.searchLength = 7; |
| 43 | params.cParams.targetLength = 16; |
| 44 | params.cParams.strategy = ZSTD_fast; |
| 45 | windowLog = params.cParams.windowLog; |
| 46 | /* Initialize stream */ |
| 47 | rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); |
| 48 | if (ZSTD_isError(rc)) { return 2; } |
| 49 | { |
Nick Terrell | 5cc85cf | 2016-12-10 19:31:55 -0800 | [diff] [blame] | 50 | U64 compressed = 0; |
| 51 | const U64 toCompress = ((U64)1) << 33; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 52 | const size_t size = 1 << windowLog; |
| 53 | size_t pos = 0; |
| 54 | char *srcBuffer = (char*) malloc(1 << windowLog); |
| 55 | char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog)); |
| 56 | ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 }; |
| 57 | const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
| 58 | const size_t randomData = (1 << windowLog) - 2*sizeof(match); |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 59 | size_t i; |
Yann Collet | c261f71 | 2016-12-12 00:25:07 +0100 | [diff] [blame] | 60 | printf("\n === Long Match Test === \n"); |
| 61 | printf("Creating random data to produce long matches \n"); |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 62 | for (i = 0; i < sizeof(match); ++i) { |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 63 | srcBuffer[i] = match[i]; |
| 64 | } |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 65 | for (i = 0; i < randomData; ++i) { |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 66 | srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF); |
| 67 | } |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 68 | for (i = 0; i < sizeof(match); ++i) { |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 69 | srcBuffer[sizeof(match) + randomData + i] = match[i]; |
| 70 | } |
Yann Collet | c261f71 | 2016-12-12 00:25:07 +0100 | [diff] [blame] | 71 | printf("Compressing, trying to generate a segfault \n"); |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 72 | if (compress(ctx, out, srcBuffer, size)) { |
| 73 | return 1; |
| 74 | } |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 75 | compressed += size; |
| 76 | while (compressed < toCompress) { |
| 77 | const size_t block = rand() % (size - pos + 1); |
| 78 | if (pos == size) { pos = 0; } |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 79 | if (compress(ctx, out, srcBuffer + pos, block)) { |
| 80 | return 1; |
| 81 | } |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 82 | pos += block; |
| 83 | compressed += block; |
| 84 | } |
Yann Collet | c261f71 | 2016-12-12 00:25:07 +0100 | [diff] [blame] | 85 | printf("Compression completed successfully (no error triggered)\n"); |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 86 | free(srcBuffer); |
| 87 | free(dstBuffer); |
| 88 | } |
Nick Terrell | b547d21 | 2016-12-10 23:17:36 -0800 | [diff] [blame] | 89 | return 0; |
Nick Terrell | 0acae73 | 2016-12-10 19:12:13 -0800 | [diff] [blame] | 90 | } |