longmatch.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) Yann Collet, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. * You may select, at your option, one of the above-listed licenses.
  9. */
  10. #include <stdio.h>
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <stdint.h>
  14. #include "mem.h"
  15. #define ZSTD_STATIC_LINKING_ONLY
  16. #include "zstd.h"
  17. static int
  18. compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size)
  19. {
  20. ZSTD_inBuffer in = { data, size, 0 };
  21. while (in.pos < in.size) {
  22. ZSTD_outBuffer tmp = out;
  23. const size_t rc = ZSTD_compressStream(ctx, &tmp, &in);
  24. if (ZSTD_isError(rc)) return 1;
  25. }
  26. { ZSTD_outBuffer tmp = out;
  27. const size_t rc = ZSTD_flushStream(ctx, &tmp);
  28. if (rc != 0) { return 1; }
  29. }
  30. return 0;
  31. }
  32. int main(int argc, const char** argv)
  33. {
  34. ZSTD_CStream* ctx;
  35. ZSTD_parameters params;
  36. size_t rc;
  37. unsigned windowLog;
  38. (void)argc;
  39. (void)argv;
  40. /* Create stream */
  41. ctx = ZSTD_createCStream();
  42. if (!ctx) { return 1; }
  43. /* Set parameters */
  44. memset(&params, 0, sizeof(params));
  45. params.cParams.windowLog = 18;
  46. params.cParams.chainLog = 13;
  47. params.cParams.hashLog = 14;
  48. params.cParams.searchLog = 1;
  49. params.cParams.minMatch = 7;
  50. params.cParams.targetLength = 16;
  51. params.cParams.strategy = ZSTD_fast;
  52. windowLog = params.cParams.windowLog;
  53. /* Initialize stream */
  54. rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0);
  55. if (ZSTD_isError(rc)) { return 2; }
  56. {
  57. U64 compressed = 0;
  58. const U64 toCompress = ((U64)1) << 33;
  59. const size_t size = 1 << windowLog;
  60. size_t pos = 0;
  61. char *srcBuffer = (char*) malloc(1 << windowLog);
  62. char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog));
  63. ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 };
  64. const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  65. const size_t randomData = (1 << windowLog) - 2*sizeof(match);
  66. size_t i;
  67. printf("\n === Long Match Test === \n");
  68. printf("Creating random data to produce long matches \n");
  69. for (i = 0; i < sizeof(match); ++i) {
  70. srcBuffer[i] = match[i];
  71. }
  72. for (i = 0; i < randomData; ++i) {
  73. srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF);
  74. }
  75. for (i = 0; i < sizeof(match); ++i) {
  76. srcBuffer[sizeof(match) + randomData + i] = match[i];
  77. }
  78. printf("Compressing, trying to generate a segfault \n");
  79. if (compress(ctx, out, srcBuffer, size)) {
  80. return 1;
  81. }
  82. compressed += size;
  83. while (compressed < toCompress) {
  84. const size_t block = rand() % (size - pos + 1);
  85. if (pos == size) { pos = 0; }
  86. if (compress(ctx, out, srcBuffer + pos, block)) {
  87. return 1;
  88. }
  89. pos += block;
  90. compressed += block;
  91. }
  92. printf("Compression completed successfully (no error triggered)\n");
  93. free(srcBuffer);
  94. free(dstBuffer);
  95. }
  96. return 0;
  97. }