zstd-ruby 1.5.1.1 → 1.5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +78 -5
  4. data/Rakefile +8 -2
  5. data/ext/zstdruby/common.h +15 -0
  6. data/ext/zstdruby/extconf.rb +1 -1
  7. data/ext/zstdruby/libzstd/common/allocations.h +55 -0
  8. data/ext/zstdruby/libzstd/common/bits.h +200 -0
  9. data/ext/zstdruby/libzstd/common/bitstream.h +19 -60
  10. data/ext/zstdruby/libzstd/common/compiler.h +26 -3
  11. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  12. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  13. data/ext/zstdruby/libzstd/common/debug.h +1 -1
  14. data/ext/zstdruby/libzstd/common/entropy_common.c +12 -40
  15. data/ext/zstdruby/libzstd/common/error_private.c +9 -2
  16. data/ext/zstdruby/libzstd/common/error_private.h +1 -1
  17. data/ext/zstdruby/libzstd/common/fse.h +5 -83
  18. data/ext/zstdruby/libzstd/common/fse_decompress.c +7 -99
  19. data/ext/zstdruby/libzstd/common/huf.h +65 -156
  20. data/ext/zstdruby/libzstd/common/mem.h +39 -46
  21. data/ext/zstdruby/libzstd/common/pool.c +37 -16
  22. data/ext/zstdruby/libzstd/common/pool.h +9 -3
  23. data/ext/zstdruby/libzstd/common/portability_macros.h +28 -3
  24. data/ext/zstdruby/libzstd/common/threading.c +68 -14
  25. data/ext/zstdruby/libzstd/common/threading.h +5 -10
  26. data/ext/zstdruby/libzstd/common/xxhash.c +2 -2
  27. data/ext/zstdruby/libzstd/common/xxhash.h +8 -8
  28. data/ext/zstdruby/libzstd/common/zstd_common.c +1 -36
  29. data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
  30. data/ext/zstdruby/libzstd/common/zstd_internal.h +20 -122
  31. data/ext/zstdruby/libzstd/common/zstd_trace.h +3 -3
  32. data/ext/zstdruby/libzstd/compress/clevels.h +1 -1
  33. data/ext/zstdruby/libzstd/compress/fse_compress.c +7 -124
  34. data/ext/zstdruby/libzstd/compress/hist.c +1 -1
  35. data/ext/zstdruby/libzstd/compress/hist.h +1 -1
  36. data/ext/zstdruby/libzstd/compress/huf_compress.c +234 -169
  37. data/ext/zstdruby/libzstd/compress/zstd_compress.c +1317 -594
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +272 -165
  39. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +115 -39
  40. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -8
  41. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +13 -13
  42. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  43. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +25 -21
  44. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  45. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +162 -82
  46. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +95 -33
  47. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
  48. data/ext/zstdruby/libzstd/compress/zstd_fast.c +434 -149
  49. data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
  50. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +405 -348
  51. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +4 -2
  52. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +9 -7
  53. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -1
  54. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
  55. data/ext/zstdruby/libzstd/compress/zstd_opt.c +149 -100
  56. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  57. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +32 -16
  58. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -2
  59. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +434 -441
  60. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +42 -37
  61. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +4 -4
  62. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
  63. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +205 -80
  64. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +201 -81
  65. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +6 -1
  66. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +4 -2
  67. data/ext/zstdruby/libzstd/dictBuilder/cover.c +19 -15
  68. data/ext/zstdruby/libzstd/dictBuilder/cover.h +1 -1
  69. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
  70. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +13 -91
  71. data/ext/zstdruby/libzstd/zdict.h +53 -31
  72. data/ext/zstdruby/libzstd/zstd.h +580 -135
  73. data/ext/zstdruby/libzstd/zstd_errors.h +27 -8
  74. data/ext/zstdruby/main.c +20 -0
  75. data/ext/zstdruby/skippable_frame.c +63 -0
  76. data/ext/zstdruby/streaming_compress.c +177 -0
  77. data/ext/zstdruby/streaming_compress.h +5 -0
  78. data/ext/zstdruby/streaming_decompress.c +123 -0
  79. data/ext/zstdruby/zstdruby.c +113 -31
  80. data/lib/zstd-ruby/version.rb +1 -1
  81. data/lib/zstd-ruby.rb +0 -1
  82. data/zstd-ruby.gemspec +1 -1
  83. metadata +11 -37
  84. data/.github/dependabot.yml +0 -8
  85. data/.github/workflows/ruby.yml +0 -35
  86. data/ext/zstdruby/libzstd/.gitignore +0 -3
  87. data/ext/zstdruby/libzstd/BUCK +0 -232
  88. data/ext/zstdruby/libzstd/Makefile +0 -357
  89. data/ext/zstdruby/libzstd/README.md +0 -217
  90. data/ext/zstdruby/libzstd/deprecated/zbuff.h +0 -214
  91. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +0 -26
  92. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +0 -167
  93. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +0 -75
  94. data/ext/zstdruby/libzstd/dll/example/Makefile +0 -48
  95. data/ext/zstdruby/libzstd/dll/example/README.md +0 -63
  96. data/ext/zstdruby/libzstd/dll/example/build_package.bat +0 -20
  97. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.sln +0 -25
  98. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.vcxproj +0 -181
  99. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +0 -415
  100. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +0 -2158
  101. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
  102. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3518
  103. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
  104. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3160
  105. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
  106. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3647
  107. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
  108. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4050
  109. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
  110. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4154
  111. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
  112. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4541
  113. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +0 -187
  114. data/ext/zstdruby/libzstd/libzstd.mk +0 -185
  115. data/ext/zstdruby/libzstd/libzstd.pc.in +0 -16
  116. data/ext/zstdruby/libzstd/modulemap/module.modulemap +0 -4
  117. data/ext/zstdruby/zstdruby.h +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f544352cc9afa92507052f7c925db620b01307d15a3d6b1c4fedbf5de020a456
4
- data.tar.gz: 11f85a814595a6b1f367b119c65d4715da8bd09f73c9aaf87179a38d1c6dec2a
3
+ metadata.gz: 76dbffc6a0a13fccd92ea93abd90e33c4a26ab2ac2972877b7928a515e37033e
4
+ data.tar.gz: 21e3eba574ac94d9f34ac0d33732435ed3fd2373e9db921702a74d2a2c9d606a
5
5
  SHA512:
6
- metadata.gz: 9082bbafb9d1c7e405905425ca4dfa684e2eba152002673753748ba35769261a9430ae3ee9fb719b6906f71b3b40eae8f718c134d485e92b6783f015451ceb0c
7
- data.tar.gz: 0e02ae6727c942ea699835e383c0433729de3c2eaa8efdb4ec9c9d150b87b112c72be5251fe3818a4c8b9c4ca7f0b4518f75f14f9059159f93c19a53e6198678
6
+ metadata.gz: 4f8c40ad6eaa9b014467fc57651f857713767f7930b2e7e2060c50ff58d05262416d0e9cb1427f440298af577eeef5247daec1866a55003ca6d9b2e2ea6212de
7
+ data.tar.gz: 5836f8061f7588081df400bf0705fcc74003029ec9ef9225e43f5ba5a0b19ec747af71cf0e34f150212a5efd90b9e1ea5ebe49a7231297e3f2ab8080bbf8247d
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ vendor/
17
17
 
18
18
  # rspec failure tracking
19
19
  .rspec_status
20
+
21
+ .ruby-version
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/zstd-ruby.svg)](https://badge.fury.io/rb/zstd-ruby)
2
- ![Build Status](https://github.com/SpringMT/zstd-ruby/actions/workflows/ruby.yml/badge.svg?branch=master)
2
+ ![Build Status](https://github.com/SpringMT/zstd-ruby/actions/workflows/ruby.yml/badge.svg?branch=main)
3
3
 
4
4
  # zstd-ruby
5
5
 
@@ -10,7 +10,7 @@ See https://github.com/facebook/zstd
10
10
  Fork from https://github.com/jarredholman/ruby-zstd.
11
11
 
12
12
  ## Zstd version
13
- v1.5.1 (https://github.com/facebook/zstd/tree/v1.5.1)
13
+ v1.5.5 (https://github.com/facebook/zstd/tree/v1.5.5)
14
14
 
15
15
  ## Installation
16
16
 
@@ -34,20 +34,93 @@ Or install it yourself as:
34
34
  require 'zstd-ruby'
35
35
  ```
36
36
 
37
- ### compression
37
+ ### Simple Compression
38
38
 
39
39
  ```ruby
40
40
  compressed_data = Zstd.compress(data)
41
41
  compressed_data = Zstd.compress(data, complession_level) # default compression_level is 0
42
42
  ```
43
43
 
44
+ ### Compression using Dictionary
45
+ ```ruby
46
+ # dictionary is supposed to have been created using `zstd --train`
47
+ compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
48
+ ```
49
+
50
+ ### Streaming Compression
51
+ ```ruby
52
+ stream = Zstd::StreamingCompress.new
53
+ stream << "abc" << "def"
54
+ res = stream.flush
55
+ stream << "ghi"
56
+ res << stream.finish
57
+ ```
44
58
 
45
- ### decompression
59
+ or
60
+
61
+ ```ruby
62
+ stream = Zstd::StreamingCompress.new
63
+ res = stream.compress("abc")
64
+ res << stream.flush
65
+ res << stream.compress("def")
66
+ res << stream.finish
67
+ ```
68
+
69
+ ### Simple Decompression
46
70
 
47
71
  ```ruby
48
72
  data = Zstd.decompress(compressed_data)
49
73
  ```
50
74
 
75
+ ### Decomporession using Dictionary
76
+ ```ruby
77
+ # dictionary is supposed to have been created using `zstd --train`
78
+ Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
79
+ ```
80
+
81
+ ### Streaming Decompression
82
+ ```ruby
83
+ cstr = "" # Compressed data
84
+ stream = Zstd::StreamingDecompress.new
85
+ result = ''
86
+ result << stream.decompress(cstr[0, 10])
87
+ result << stream.decompress(cstr[10..-1])
88
+ ```
89
+
90
+ ### Skippable flame
91
+
92
+ ```ruby
93
+ compressed_data_with_skippable_frame = Zstd.write_skippable_frame(compressed_data, "sample data")
94
+
95
+ Zstd.read_skippable_frame(compressed_data_with_skippable_frame)
96
+ # => "sample data"
97
+ ```
98
+
99
+ ## JRuby
100
+ This gem does not support JRuby.
101
+
102
+ Please consider using https://github.com/luben/zstd-jni.
103
+
104
+ Sample code is below.
105
+
106
+ ```
107
+ require 'java'
108
+ require_relative './zstd-jni-1.5.2-3.jar'
109
+
110
+ str = "testtest"
111
+ compressed = com.github.luben.zstd.Zstd.compress(str.to_java_bytes)
112
+ puts com.github.luben.zstd.Zstd.decompress(compressed, str.length)
113
+ ```
114
+
115
+ ```
116
+ % ls
117
+ test.rb zstd-jni-1.5.2-3.jar
118
+ % ruby -v
119
+ jruby 9.3.2.0 (2.6.8) 2021-12-01 0b8223f905 OpenJDK 64-Bit Server VM 11.0.12+0 on 11.0.12+0 +jit [darwin-x86_64]
120
+ % ruby test.rb
121
+ testtest
122
+ ```
123
+
51
124
  ## Development
52
125
 
53
126
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -56,7 +129,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
56
129
 
57
130
  ## Contributing
58
131
 
59
- Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
132
+ Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
60
133
 
61
134
 
62
135
  ## License
data/Rakefile CHANGED
@@ -17,6 +17,12 @@ task :default => [:clobber, :compile, :spec]
17
17
 
18
18
  desc 'Sync zstd libs dirs to ext/zstdruby/libzstd'
19
19
  task :zstd_update do
20
- FileUtils.rm_r('ext/zstdruby/libzstd')
21
- FileUtils.cp_r('zstd/lib', 'ext/zstdruby/libzstd')
20
+ FileUtils.rm_r("ext/zstdruby/libzstd")
21
+ FileUtils.mkdir_p("ext/zstdruby/libzstd")
22
+ ["common", "compress", "decompress", "dictBuilder"].each do |dir|
23
+ FileUtils.cp_r("zstd/lib/#{dir}", "ext/zstdruby/libzstd/#{dir}")
24
+ end
25
+ FileUtils.cp_r('zstd/lib/zdict.h', 'ext/zstdruby/libzstd')
26
+ FileUtils.cp_r('zstd/lib/zstd.h', 'ext/zstdruby/libzstd')
27
+ FileUtils.cp_r('zstd/lib/zstd_errors.h', 'ext/zstdruby/libzstd')
22
28
  end
@@ -0,0 +1,15 @@
1
+ #ifndef ZSTD_RUBY_H
2
+ #define ZSTD_RUBY_H 1
3
+
4
+ #include "ruby.h"
5
+ #include "./libzstd/zstd.h"
6
+
7
+ static int convert_compression_level(VALUE compression_level_value)
8
+ {
9
+ if (NIL_P(compression_level_value)) {
10
+ return ZSTD_CLEVEL_DEFAULT;
11
+ }
12
+ return NUM2INT(compression_level_value);
13
+ }
14
+
15
+ #endif /* ZSTD_RUBY_H */
@@ -1,6 +1,6 @@
1
1
  require "mkmf"
2
2
 
3
- $CFLAGS = '-I. -O3 -std=c99'
3
+ $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY'
4
4
  $CPPFLAGS += " -fdeclspec" if CONFIG['CXX'] =~ /clang/
5
5
 
6
6
  Dir.chdir File.expand_path('..', __FILE__) do
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+
11
+ /* This file provides custom allocation primitives
12
+ */
13
+
14
+ #define ZSTD_DEPS_NEED_MALLOC
15
+ #include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */
16
+
17
+ #include "mem.h" /* MEM_STATIC */
18
+ #define ZSTD_STATIC_LINKING_ONLY
19
+ #include "../zstd.h" /* ZSTD_customMem */
20
+
21
+ #ifndef ZSTD_ALLOCATIONS_H
22
+ #define ZSTD_ALLOCATIONS_H
23
+
24
+ /* custom memory allocation functions */
25
+
26
+ MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
27
+ {
28
+ if (customMem.customAlloc)
29
+ return customMem.customAlloc(customMem.opaque, size);
30
+ return ZSTD_malloc(size);
31
+ }
32
+
33
+ MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
34
+ {
35
+ if (customMem.customAlloc) {
36
+ /* calloc implemented as malloc+memset;
37
+ * not as efficient as calloc, but next best guess for custom malloc */
38
+ void* const ptr = customMem.customAlloc(customMem.opaque, size);
39
+ ZSTD_memset(ptr, 0, size);
40
+ return ptr;
41
+ }
42
+ return ZSTD_calloc(1, size);
43
+ }
44
+
45
+ MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem)
46
+ {
47
+ if (ptr!=NULL) {
48
+ if (customMem.customFree)
49
+ customMem.customFree(customMem.opaque, ptr);
50
+ else
51
+ ZSTD_free(ptr);
52
+ }
53
+ }
54
+
55
+ #endif /* ZSTD_ALLOCATIONS_H */
@@ -0,0 +1,200 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
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
+
11
+ #ifndef ZSTD_BITS_H
12
+ #define ZSTD_BITS_H
13
+
14
+ #include "mem.h"
15
+
16
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
17
+ {
18
+ assert(val != 0);
19
+ {
20
+ static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3,
21
+ 30, 22, 20, 15, 25, 17, 4, 8,
22
+ 31, 27, 13, 23, 21, 19, 16, 7,
23
+ 26, 12, 18, 6, 11, 5, 10, 9};
24
+ return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
25
+ }
26
+ }
27
+
28
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
29
+ {
30
+ assert(val != 0);
31
+ # if defined(_MSC_VER)
32
+ # if STATIC_BMI2 == 1
33
+ return (unsigned)_tzcnt_u32(val);
34
+ # else
35
+ if (val != 0) {
36
+ unsigned long r;
37
+ _BitScanForward(&r, val);
38
+ return (unsigned)r;
39
+ } else {
40
+ /* Should not reach this code path */
41
+ __assume(0);
42
+ }
43
+ # endif
44
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
45
+ return (unsigned)__builtin_ctz(val);
46
+ # else
47
+ return ZSTD_countTrailingZeros32_fallback(val);
48
+ # endif
49
+ }
50
+
51
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) {
52
+ assert(val != 0);
53
+ {
54
+ static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
55
+ 11, 14, 16, 18, 22, 25, 3, 30,
56
+ 8, 12, 20, 28, 15, 17, 24, 7,
57
+ 19, 27, 23, 6, 26, 5, 4, 31};
58
+ val |= val >> 1;
59
+ val |= val >> 2;
60
+ val |= val >> 4;
61
+ val |= val >> 8;
62
+ val |= val >> 16;
63
+ return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
64
+ }
65
+ }
66
+
67
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
68
+ {
69
+ assert(val != 0);
70
+ # if defined(_MSC_VER)
71
+ # if STATIC_BMI2 == 1
72
+ return (unsigned)_lzcnt_u32(val);
73
+ # else
74
+ if (val != 0) {
75
+ unsigned long r;
76
+ _BitScanReverse(&r, val);
77
+ return (unsigned)(31 - r);
78
+ } else {
79
+ /* Should not reach this code path */
80
+ __assume(0);
81
+ }
82
+ # endif
83
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
84
+ return (unsigned)__builtin_clz(val);
85
+ # else
86
+ return ZSTD_countLeadingZeros32_fallback(val);
87
+ # endif
88
+ }
89
+
90
+ MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
91
+ {
92
+ assert(val != 0);
93
+ # if defined(_MSC_VER) && defined(_WIN64)
94
+ # if STATIC_BMI2 == 1
95
+ return (unsigned)_tzcnt_u64(val);
96
+ # else
97
+ if (val != 0) {
98
+ unsigned long r;
99
+ _BitScanForward64(&r, val);
100
+ return (unsigned)r;
101
+ } else {
102
+ /* Should not reach this code path */
103
+ __assume(0);
104
+ }
105
+ # endif
106
+ # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
107
+ return (unsigned)__builtin_ctzll(val);
108
+ # else
109
+ {
110
+ U32 mostSignificantWord = (U32)(val >> 32);
111
+ U32 leastSignificantWord = (U32)val;
112
+ if (leastSignificantWord == 0) {
113
+ return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
114
+ } else {
115
+ return ZSTD_countTrailingZeros32(leastSignificantWord);
116
+ }
117
+ }
118
+ # endif
119
+ }
120
+
121
+ MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
122
+ {
123
+ assert(val != 0);
124
+ # if defined(_MSC_VER) && defined(_WIN64)
125
+ # if STATIC_BMI2 == 1
126
+ return (unsigned)_lzcnt_u64(val);
127
+ # else
128
+ if (val != 0) {
129
+ unsigned long r;
130
+ _BitScanReverse64(&r, val);
131
+ return (unsigned)(63 - r);
132
+ } else {
133
+ /* Should not reach this code path */
134
+ __assume(0);
135
+ }
136
+ # endif
137
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
138
+ return (unsigned)(__builtin_clzll(val));
139
+ # else
140
+ {
141
+ U32 mostSignificantWord = (U32)(val >> 32);
142
+ U32 leastSignificantWord = (U32)val;
143
+ if (mostSignificantWord == 0) {
144
+ return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
145
+ } else {
146
+ return ZSTD_countLeadingZeros32(mostSignificantWord);
147
+ }
148
+ }
149
+ # endif
150
+ }
151
+
152
+ MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
153
+ {
154
+ if (MEM_isLittleEndian()) {
155
+ if (MEM_64bits()) {
156
+ return ZSTD_countTrailingZeros64((U64)val) >> 3;
157
+ } else {
158
+ return ZSTD_countTrailingZeros32((U32)val) >> 3;
159
+ }
160
+ } else { /* Big Endian CPU */
161
+ if (MEM_64bits()) {
162
+ return ZSTD_countLeadingZeros64((U64)val) >> 3;
163
+ } else {
164
+ return ZSTD_countLeadingZeros32((U32)val) >> 3;
165
+ }
166
+ }
167
+ }
168
+
169
+ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
170
+ {
171
+ assert(val != 0);
172
+ return 31 - ZSTD_countLeadingZeros32(val);
173
+ }
174
+
175
+ /* ZSTD_rotateRight_*():
176
+ * Rotates a bitfield to the right by "count" bits.
177
+ * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
178
+ */
179
+ MEM_STATIC
180
+ U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
181
+ assert(count < 64);
182
+ count &= 0x3F; /* for fickle pattern recognition */
183
+ return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
184
+ }
185
+
186
+ MEM_STATIC
187
+ U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
188
+ assert(count < 32);
189
+ count &= 0x1F; /* for fickle pattern recognition */
190
+ return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
191
+ }
192
+
193
+ MEM_STATIC
194
+ U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
195
+ assert(count < 16);
196
+ count &= 0x0F; /* for fickle pattern recognition */
197
+ return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
198
+ }
199
+
200
+ #endif /* ZSTD_BITS_H */
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * bitstream
3
3
  * Part of FSE library
4
- * Copyright (c) Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -30,14 +30,15 @@ extern "C" {
30
30
  #include "compiler.h" /* UNLIKELY() */
31
31
  #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
32
32
  #include "error_private.h" /* error codes and messages */
33
+ #include "bits.h" /* ZSTD_highbit32 */
33
34
 
34
35
 
35
36
  /*=========================================
36
37
  * Target specific
37
38
  =========================================*/
38
39
  #ifndef ZSTD_NO_INTRINSICS
39
- # if defined(__BMI__) && defined(__GNUC__)
40
- # include <immintrin.h> /* support for bextr (experimental) */
40
+ # if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__)
41
+ # include <immintrin.h> /* support for bextr (experimental)/bzhi */
41
42
  # elif defined(__ICCARM__)
42
43
  # include <intrinsics.h>
43
44
  # endif
@@ -132,48 +133,6 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
132
133
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
133
134
  /* faster, but works only if nbBits >= 1 */
134
135
 
135
-
136
-
137
- /*-**************************************************************
138
- * Internal functions
139
- ****************************************************************/
140
- MEM_STATIC unsigned BIT_highbit32 (U32 val)
141
- {
142
- assert(val != 0);
143
- {
144
- # if defined(_MSC_VER) /* Visual */
145
- # if STATIC_BMI2 == 1
146
- return _lzcnt_u32(val) ^ 31;
147
- # else
148
- if (val != 0) {
149
- unsigned long r;
150
- _BitScanReverse(&r, val);
151
- return (unsigned)r;
152
- } else {
153
- /* Should not reach this code path */
154
- __assume(0);
155
- }
156
- # endif
157
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
158
- return __builtin_clz (val) ^ 31;
159
- # elif defined(__ICCARM__) /* IAR Intrinsic */
160
- return 31 - __CLZ(val);
161
- # else /* Software version */
162
- static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
163
- 11, 14, 16, 18, 22, 25, 3, 30,
164
- 8, 12, 20, 28, 15, 17, 24, 7,
165
- 19, 27, 23, 6, 26, 5, 4, 31 };
166
- U32 v = val;
167
- v |= v >> 1;
168
- v |= v >> 2;
169
- v |= v >> 4;
170
- v |= v >> 8;
171
- v |= v >> 16;
172
- return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
173
- # endif
174
- }
175
- }
176
-
177
136
  /*===== Local Constants =====*/
178
137
  static const unsigned BIT_mask[] = {
179
138
  0, 1, 3, 7, 0xF, 0x1F,
@@ -203,6 +162,16 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
203
162
  return 0;
204
163
  }
205
164
 
165
+ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
166
+ {
167
+ #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
168
+ return _bzhi_u64(bitContainer, nbBits);
169
+ #else
170
+ assert(nbBits < BIT_MASK_SIZE);
171
+ return bitContainer & BIT_mask[nbBits];
172
+ #endif
173
+ }
174
+
206
175
  /*! BIT_addBits() :
207
176
  * can add up to 31 bits into `bitC`.
208
177
  * Note : does not check for register overflow ! */
@@ -212,7 +181,7 @@ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
212
181
  DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
213
182
  assert(nbBits < BIT_MASK_SIZE);
214
183
  assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
215
- bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
184
+ bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;
216
185
  bitC->bitPos += nbBits;
217
186
  }
218
187
 
@@ -291,7 +260,7 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
291
260
  bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
292
261
  bitD->bitContainer = MEM_readLEST(bitD->ptr);
293
262
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
294
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
263
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
295
264
  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
296
265
  } else {
297
266
  bitD->ptr = bitD->start;
@@ -319,7 +288,7 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
319
288
  default: break;
320
289
  }
321
290
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
322
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
291
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
323
292
  if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
324
293
  }
325
294
  bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
@@ -350,16 +319,6 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c
350
319
  #endif
351
320
  }
352
321
 
353
- MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
354
- {
355
- #if defined(STATIC_BMI2) && STATIC_BMI2 == 1
356
- return _bzhi_u64(bitContainer, nbBits);
357
- #else
358
- assert(nbBits < BIT_MASK_SIZE);
359
- return bitContainer & BIT_mask[nbBits];
360
- #endif
361
- }
362
-
363
322
  /*! BIT_lookBits() :
364
323
  * Provides next n bits from local register.
365
324
  * local register is not modified.
@@ -406,7 +365,7 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned n
406
365
  }
407
366
 
408
367
  /*! BIT_readBitsFast() :
409
- * unsafe version; only works only if nbBits >= 1 */
368
+ * unsafe version; only works if nbBits >= 1 */
410
369
  MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
411
370
  {
412
371
  size_t const value = BIT_lookBitsFast(bitD, nbBits);
@@ -437,7 +396,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
437
396
  * This function is safe, it guarantees it will not read beyond src buffer.
438
397
  * @return : status of `BIT_DStream_t` internal register.
439
398
  * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
440
- MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
399
+ MEM_STATIC FORCE_INLINE_ATTR BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
441
400
  {
442
401
  if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
443
402
  return BIT_DStream_overflow;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -165,6 +165,12 @@
165
165
  #define UNLIKELY(x) (x)
166
166
  #endif
167
167
 
168
+ #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
169
+ # define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
170
+ #else
171
+ # define ZSTD_UNREACHABLE { assert(0); }
172
+ #endif
173
+
168
174
  /* disable warnings */
169
175
  #ifdef _MSC_VER /* Visual Studio */
170
176
  # include <intrin.h> /* For Visual 2005 */
@@ -181,6 +187,8 @@
181
187
  # ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
182
188
  # define STATIC_BMI2 1
183
189
  # endif
190
+ # elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
191
+ # define STATIC_BMI2 1
184
192
  # endif
185
193
  #endif
186
194
 
@@ -273,7 +281,18 @@
273
281
  * Sanitizer
274
282
  *****************************************************************/
275
283
 
276
- #if ZSTD_MEMORY_SANITIZER
284
+ /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
285
+ * abundance of caution, disable our custom poisoning on mingw. */
286
+ #ifdef __MINGW32__
287
+ #ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE
288
+ #define ZSTD_ASAN_DONT_POISON_WORKSPACE 1
289
+ #endif
290
+ #ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE
291
+ #define ZSTD_MSAN_DONT_POISON_WORKSPACE 1
292
+ #endif
293
+ #endif
294
+
295
+ #if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE)
277
296
  /* Not all platforms that support msan provide sanitizers/msan_interface.h.
278
297
  * We therefore declare the functions we need ourselves, rather than trying to
279
298
  * include the header file... */
@@ -292,9 +311,13 @@ void __msan_poison(const volatile void *a, size_t size);
292
311
  /* Returns the offset of the first (at least partially) poisoned byte in the
293
312
  memory range, or -1 if the whole range is good. */
294
313
  intptr_t __msan_test_shadow(const volatile void *x, size_t size);
314
+
315
+ /* Print shadow and origin for the memory range to stderr in a human-readable
316
+ format. */
317
+ void __msan_print_shadow(const volatile void *x, size_t size);
295
318
  #endif
296
319
 
297
- #if ZSTD_ADDRESS_SANITIZER
320
+ #if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE)
298
321
  /* Not all platforms that support asan provide sanitizers/asan_interface.h.
299
322
  * We therefore declare the functions we need ourselves, rather than trying to
300
323
  * include the header file... */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy