brotli 0.4.0 → 0.6.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +6 -3
  3. data/.github/workflows/publish.yml +7 -17
  4. data/.gitmodules +1 -1
  5. data/README.md +2 -2
  6. data/ext/brotli/brotli.c +8 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +14 -1
  10. data/test/test_helper.rb +1 -0
  11. data/vendor/brotli/c/common/constants.c +1 -1
  12. data/vendor/brotli/c/common/constants.h +2 -1
  13. data/vendor/brotli/c/common/context.c +1 -1
  14. data/vendor/brotli/c/common/dictionary.c +5 -3
  15. data/vendor/brotli/c/common/platform.c +2 -1
  16. data/vendor/brotli/c/common/platform.h +60 -113
  17. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  18. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  19. data/vendor/brotli/c/common/transform.c +1 -1
  20. data/vendor/brotli/c/common/version.h +31 -6
  21. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  22. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  23. data/vendor/brotli/c/dec/decode.c +467 -200
  24. data/vendor/brotli/c/dec/huffman.c +7 -4
  25. data/vendor/brotli/c/dec/huffman.h +2 -1
  26. data/vendor/brotli/c/dec/prefix.h +2 -1
  27. data/vendor/brotli/c/dec/state.c +33 -9
  28. data/vendor/brotli/c/dec/state.h +70 -35
  29. data/vendor/brotli/c/enc/backward_references.c +81 -19
  30. data/vendor/brotli/c/enc/backward_references.h +5 -4
  31. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  32. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  33. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  34. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  35. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  36. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  37. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  38. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  39. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  40. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  41. data/vendor/brotli/c/enc/cluster.c +10 -9
  42. data/vendor/brotli/c/enc/cluster.h +7 -6
  43. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  44. data/vendor/brotli/c/enc/command.c +1 -1
  45. data/vendor/brotli/c/enc/command.h +5 -4
  46. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  47. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  48. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  49. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  51. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  52. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  53. data/vendor/brotli/c/enc/encode.c +473 -404
  54. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  55. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  56. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  57. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  58. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  59. data/vendor/brotli/c/enc/fast_log.c +1 -1
  60. data/vendor/brotli/c/enc/fast_log.h +2 -1
  61. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  62. data/vendor/brotli/c/enc/hash.h +285 -45
  63. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  64. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  65. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  66. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  67. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  69. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  70. data/vendor/brotli/c/enc/histogram.c +4 -4
  71. data/vendor/brotli/c/enc/histogram.h +7 -6
  72. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  73. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  74. data/vendor/brotli/c/enc/memory.c +29 -5
  75. data/vendor/brotli/c/enc/memory.h +19 -2
  76. data/vendor/brotli/c/enc/metablock.c +72 -58
  77. data/vendor/brotli/c/enc/metablock.h +9 -8
  78. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  79. data/vendor/brotli/c/enc/params.h +4 -3
  80. data/vendor/brotli/c/enc/prefix.h +3 -2
  81. data/vendor/brotli/c/enc/quality.h +40 -3
  82. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  83. data/vendor/brotli/c/enc/state.h +104 -0
  84. data/vendor/brotli/c/enc/static_dict.c +60 -4
  85. data/vendor/brotli/c/enc/static_dict.h +3 -2
  86. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  87. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  88. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  89. data/vendor/brotli/c/enc/write_bits.h +2 -1
  90. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  91. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  92. data/vendor/brotli/c/include/brotli/port.h +28 -11
  93. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  94. metadata +9 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 410f0b599c6bf42f90cb7fa83c6710304ad0fb018b1f4b5560bfadadaef165d9
4
- data.tar.gz: 03fbcca525c9705b99935ab2ea4db0bb80e4c6a960d3010450a173c5b305eb43
3
+ metadata.gz: bfcc8a08b7351d54f9472ca2b549733eac9d4be139c3ba9f1ebfe41c3f8fb057
4
+ data.tar.gz: 98764c09827125ba6304a6910a84e1674f4dcd6a3e13793b4438ea5c9a96f815
5
5
  SHA512:
6
- metadata.gz: fe26f6b7a9a2f3a0bf0ab5d1e79ff89ff8dc2a763e3b8beb073feb365f6ae222dcf277672bbbe2ac7aeaa71f2b024edd6ce49a6a7254452897fdbfef61f422a5
7
- data.tar.gz: c1952c3b820fa2ec0b5a1e1567acfe831fcc1a6131f07e12acf3b26595c3bda90c89182abfcc57730febe5311906632ea8c19a21e16e866a5e620a8b85cfa2d4
6
+ metadata.gz: d24c3f2595c9578a71e9d1a3208bcd74e95197e17f796ba3df72dd36818189a0838e79b9ae5ffcf668f258718a2c260142866e419993b4282bada394199d025b
7
+ data.tar.gz: 891d4714d76a902d38898e9287063e97e8161be0f4e7af3f91477af5a7412c25d73b881dbd0d1031457458a69b3c4f0b466ab953a519318664acd3332c057fb7
@@ -7,10 +7,10 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby: [2.5, 2.6, 2.7, 3.0]
10
+ ruby: [2.7, 3.1, 3.2, 3.3]
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v2
13
+ - uses: actions/checkout@v4
14
14
  with:
15
15
  submodules: true
16
16
  - name: Set up Ruby
@@ -20,7 +20,10 @@ jobs:
20
20
  bundler-cache: true
21
21
  - name: Run the default task
22
22
  run: |
23
- bundle exec rake clobber test build
23
+ bundle exec rake clobber
24
+ bundle exec rake compile -- --enable-vendor
25
+ bundle exec rake test
26
+ bundle exec rake build
24
27
  gem install --no-document "$(ls pkg/brotli-*.gem)"
25
28
  cat <<EOF | ruby
26
29
  require "brotli"
@@ -7,28 +7,18 @@ on:
7
7
 
8
8
  jobs:
9
9
  build:
10
- strategy:
11
- fail-fast: false
12
- matrix:
13
- ruby: [2.7]
10
+ if: github.repository == 'miyucy/brotli'
14
11
  runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: write
14
+ id-token: write
15
15
  steps:
16
- - uses: actions/checkout@v2
16
+ - uses: actions/checkout@v4
17
17
  with:
18
18
  submodules: true
19
19
  - name: Set up Ruby
20
20
  uses: ruby/setup-ruby@v1
21
21
  with:
22
- ruby-version: ${{ matrix.ruby }}
22
+ ruby-version: ruby
23
23
  bundler-cache: true
24
- - name: Run release task
25
- run: |
26
- mkdir -p ~/.gem
27
- cat << EOF > ~/.gem/credentials
28
- ---
29
- :github: Bearer ${{secrets.GITHUB_TOKEN}}
30
- :rubygems_api_key: ${{secrets.RUBYGEMS_API_KEY}}
31
- EOF
32
- chmod 600 ~/.gem/credentials
33
- bundle exec rake release[remote]
34
- rm -f ~/.gem/credentials
24
+ - uses: rubygems/release-gem@v1
data/.gitmodules CHANGED
@@ -1,3 +1,3 @@
1
1
  [submodule "vendor/brotli"]
2
2
  path = vendor/brotli
3
- url = git://github.com/google/brotli.git
3
+ url = https://github.com/google/brotli.git
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Brotli [![](https://travis-ci.org/miyucy/brotli.svg)](https://travis-ci.org/miyucy/brotli)
1
+ # Brotli
2
2
 
3
3
  Brotli is a Ruby implementation of the Brotli generic-purpose lossless
4
4
  compression algorithm that compresses data using a combination of a modern
@@ -31,7 +31,7 @@ compressed = Brotli.deflate(string)
31
31
  decompressed = Brotli.inflate(compressed)
32
32
  ```
33
33
 
34
- See spec/brotli_spec.rb
34
+ See test/brotli_test.rb
35
35
 
36
36
  ## Development
37
37
 
data/ext/brotli/brotli.c CHANGED
@@ -68,12 +68,18 @@ brotli_inflate_no_gvl(void *arg)
68
68
  return arg;
69
69
  }
70
70
 
71
+ static ID id_read;
72
+
71
73
  static VALUE
72
74
  brotli_inflate(VALUE self, VALUE str)
73
75
  {
74
76
  VALUE value = Qnil;
75
77
  brotli_inflate_args_t args;
76
78
 
79
+ if (rb_respond_to(str, id_read)) {
80
+ str = rb_funcall(str, id_read, 0, 0);
81
+ }
82
+
77
83
  StringValue(str);
78
84
 
79
85
  args.str = (uint8_t*)RSTRING_PTR(str);
@@ -183,6 +189,7 @@ static BrotliEncoderState*
183
189
  brotli_deflate_parse_options(BrotliEncoderState* s, VALUE opts)
184
190
  {
185
191
  if (!NIL_P(opts)) {
192
+ Check_Type(opts, T_HASH);
186
193
  brotli_deflate_set_mode(s, rb_hash_aref(opts, CSTR2SYM("mode")));
187
194
  brotli_deflate_set_quality(s, rb_hash_aref(opts, CSTR2SYM("quality")));
188
195
  brotli_deflate_set_lgwin(s, rb_hash_aref(opts, CSTR2SYM("lgwin")));
@@ -471,6 +478,7 @@ Init_brotli(void)
471
478
  rb_define_singleton_method(rb_mBrotli, "deflate", RUBY_METHOD_FUNC(brotli_deflate), -1);
472
479
  rb_define_singleton_method(rb_mBrotli, "inflate", RUBY_METHOD_FUNC(brotli_inflate), 1);
473
480
  rb_define_singleton_method(rb_mBrotli, "version", RUBY_METHOD_FUNC(brotli_version), 0);
481
+ id_read = rb_intern("read");
474
482
  // Brotli::Writer
475
483
  id_write = rb_intern("write");
476
484
  id_flush = rb_intern("flush");
@@ -13,6 +13,11 @@ have_dev_pkg = [
13
13
  pkg_config("libbrotlienc")
14
14
  ].all? { |e| e }
15
15
 
16
+ if enable_config("vendor")
17
+ have_dev_pkg = false
18
+ Logging::message "Use vendor brotli\n"
19
+ end
20
+
16
21
  $CPPFLAGS << " -DOS_MACOSX" if RbConfig::CONFIG["host_os"] =~ /darwin|mac os/
17
22
  $INCFLAGS << " -I$(srcdir)/enc -I$(srcdir)/dec -I$(srcdir)/common -I$(srcdir)/include" unless have_dev_pkg
18
23
 
@@ -22,6 +27,7 @@ unless have_dev_pkg
22
27
  __DIR__ = File.expand_path(File.dirname(__FILE__))
23
28
 
24
29
  %w[enc dec common include].each do |dirname|
30
+ FileUtils.rm_rf dirname
25
31
  FileUtils.mkdir_p dirname
26
32
  FileUtils.cp_r(
27
33
  File.expand_path(File.join(__DIR__, "..", "..", "vendor", "brotli", "c", dirname), __DIR__),
@@ -1,3 +1,3 @@
1
1
  module Brotli
2
- VERSION = '0.4.0'
2
+ VERSION = '0.6.0'
3
3
  end
data/test/brotli_test.rb CHANGED
@@ -23,7 +23,7 @@ class BrotliTest < Test::Unit::TestCase
23
23
 
24
24
  sub_test_case ".version" do
25
25
  test "returns string" do
26
- assert_equal "1.0.9", Brotli.version
26
+ assert_equal "1.1.0", Brotli.version
27
27
  end
28
28
  end
29
29
 
@@ -60,6 +60,9 @@ class BrotliTest < Test::Unit::TestCase
60
60
  assert_raise ArgumentError do
61
61
  Brotli.deflate(testdata, lgblock: 25)
62
62
  end
63
+ assert_raise TypeError do
64
+ Brotli.deflate(testdata, 42)
65
+ end
63
66
  end
64
67
  end
65
68
 
@@ -74,6 +77,16 @@ class BrotliTest < Test::Unit::TestCase
74
77
  assert_equal testdata, Brotli.inflate(testdata2)
75
78
  end
76
79
 
80
+ test "works with StringIO" do
81
+ testdata3 = StringIO.new testdata2
82
+ assert_equal testdata, Brotli.inflate(testdata3)
83
+ end
84
+
85
+ test "works with File" do
86
+ f = File.open(File.expand_path(File.join("..", "vendor", "brotli", "tests", "testdata", "alice29.txt.compressed"), __dir__))
87
+ assert_equal testdata, Brotli.inflate(f)
88
+ end
89
+
77
90
  test "raise error when pass insufficient data" do
78
91
  assert_raise Brotli::Error do
79
92
  Brotli.inflate(testdata2[0, 64])
data/test/test_helper.rb CHANGED
@@ -6,3 +6,4 @@ require "brotli"
6
6
  require "test-unit"
7
7
  require "test/unit/rr"
8
8
  require "rantly/testunit_extensions"
9
+ require "stringio"
@@ -4,7 +4,7 @@
4
4
  See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
5
  */
6
6
 
7
- #include "./constants.h"
7
+ #include "constants.h"
8
8
 
9
9
  const BrotliPrefixCodeRange
10
10
  _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = {
@@ -12,10 +12,11 @@
12
12
  #ifndef BROTLI_COMMON_CONSTANTS_H_
13
13
  #define BROTLI_COMMON_CONSTANTS_H_
14
14
 
15
- #include "./platform.h"
16
15
  #include <brotli/port.h>
17
16
  #include <brotli/types.h>
18
17
 
18
+ #include "platform.h"
19
+
19
20
  /* Specification: 7.3. Encoding of the context map */
20
21
  #define BROTLI_CONTEXT_MAP_MAX_RLE 16
21
22
 
@@ -1,4 +1,4 @@
1
- #include "./context.h"
1
+ #include "context.h"
2
2
 
3
3
  #include <brotli/types.h>
4
4
 
@@ -4,8 +4,8 @@
4
4
  See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
5
  */
6
6
 
7
- #include "./dictionary.h"
8
- #include "./platform.h"
7
+ #include "dictionary.h"
8
+ #include "platform.h"
9
9
 
10
10
  #if defined(__cplusplus) || defined(c_plusplus)
11
11
  extern "C" {
@@ -13,6 +13,7 @@ extern "C" {
13
13
 
14
14
  #if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA)
15
15
  static const uint8_t kBrotliDictionaryData[] =
16
+ /* GENERATED CODE START */
16
17
  {
17
18
  116,105,109,101,100,111,119,110,108,105,102,101,108,101,102,116,98,97,99,107,99,
18
19
  111,100,101,100,97,116,97,115,104,111,119,111,110,108,121,115,105,116,101,99,105
@@ -5860,6 +5861,7 @@ static const uint8_t kBrotliDictionaryData[] =
5860
5861
  ,164,181,224,164,190,224,164,136,224,164,184,224,164,149,224,165,141,224,164,176
5861
5862
  ,224,164,191,224,164,175,224,164,164,224,164,190
5862
5863
  }
5864
+ /* GENERATED CODE END */
5863
5865
  ;
5864
5866
  #endif /* !BROTLI_EXTERNAL_DICTIONARY_DATA */
5865
5867
 
@@ -5895,7 +5897,7 @@ static BrotliDictionary kBrotliDictionary = {
5895
5897
  #endif
5896
5898
  };
5897
5899
 
5898
- const BrotliDictionary* BrotliGetDictionary() {
5900
+ const BrotliDictionary* BrotliGetDictionary(void) {
5899
5901
  return &kBrotliDictionary;
5900
5902
  }
5901
5903
 
@@ -6,9 +6,10 @@
6
6
 
7
7
  #include <stdlib.h>
8
8
 
9
- #include "./platform.h"
10
9
  #include <brotli/types.h>
11
10
 
11
+ #include "platform.h"
12
+
12
13
  /* Default brotli_alloc_func */
13
14
  void* BrotliDefaultAllocFunc(void* opaque, size_t size) {
14
15
  BROTLI_UNUSED(opaque);
@@ -12,12 +12,13 @@
12
12
  * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
13
13
  * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
14
14
  * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
15
- * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
16
- read and overlapping memcpy; this reduces decompression speed by 5%
17
15
  * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
16
+ * BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read
17
+ optimizations (mainly for testing purposes)
18
18
  * BROTLI_DEBUG dumps file name and line number when decoder detects stream
19
19
  or memory error
20
20
  * BROTLI_ENABLE_LOG enables asserts and dumps various state information
21
+ * BROTLI_ENABLE_DUMP overrides default "dump" behaviour
21
22
  */
22
23
 
23
24
  #ifndef BROTLI_COMMON_PLATFORM_H_
@@ -40,7 +41,7 @@
40
41
  #define BROTLI_X_BIG_ENDIAN BIG_ENDIAN
41
42
  #endif
42
43
 
43
- #if BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
44
+ #if BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
44
45
  #include <intrin.h>
45
46
  #endif
46
47
 
@@ -156,24 +157,6 @@ OR:
156
157
  #define BROTLI_NOINLINE
157
158
  #endif
158
159
 
159
- /* BROTLI_INTERNAL could be defined to override visibility, e.g. for tests. */
160
- #if !defined(BROTLI_INTERNAL)
161
- #if defined(_WIN32) || defined(__CYGWIN__)
162
- #define BROTLI_INTERNAL
163
- #elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \
164
- BROTLI_TI_VERSION_CHECK(8, 0, 0) || \
165
- BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \
166
- BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \
167
- BROTLI_IBM_VERSION_CHECK(13, 1, 0) || \
168
- BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \
169
- (BROTLI_TI_VERSION_CHECK(7, 3, 0) && \
170
- defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__))
171
- #define BROTLI_INTERNAL __attribute__ ((visibility ("hidden")))
172
- #else
173
- #define BROTLI_INTERNAL
174
- #endif
175
- #endif
176
-
177
160
  /* <<< <<< <<< end of hedley macros. */
178
161
 
179
162
  #if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \
@@ -226,15 +209,24 @@ OR:
226
209
  #define BROTLI_TARGET_RISCV64
227
210
  #endif
228
211
 
212
+ #if defined(__loongarch_lp64)
213
+ #define BROTLI_TARGET_LOONGARCH64
214
+ #endif
215
+
216
+ #if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
217
+ defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \
218
+ defined(BROTLI_TARGET_LOONGARCH64)
219
+ #define BROTLI_TARGET_64_BITS 1
220
+ #else
221
+ #define BROTLI_TARGET_64_BITS 0
222
+ #endif
223
+
229
224
  #if defined(BROTLI_BUILD_64_BIT)
230
225
  #define BROTLI_64_BITS 1
231
226
  #elif defined(BROTLI_BUILD_32_BIT)
232
227
  #define BROTLI_64_BITS 0
233
- #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
234
- defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64)
235
- #define BROTLI_64_BITS 1
236
228
  #else
237
- #define BROTLI_64_BITS 0
229
+ #define BROTLI_64_BITS BROTLI_TARGET_64_BITS
238
230
  #endif
239
231
 
240
232
  #if (BROTLI_64_BITS)
@@ -278,18 +270,19 @@ OR:
278
270
  #undef BROTLI_X_BIG_ENDIAN
279
271
  #endif
280
272
 
281
- #if defined(BROTLI_BUILD_PORTABLE)
282
- #define BROTLI_ALIGNED_READ (!!1)
283
- #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
273
+ #if defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST)
274
+ #define BROTLI_UNALIGNED_READ_FAST (!!0)
275
+ #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
284
276
  defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
285
- defined(BROTLI_TARGET_RISCV64)
286
- /* Allow unaligned read only for white-listed CPUs. */
287
- #define BROTLI_ALIGNED_READ (!!0)
277
+ defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64)
278
+ /* These targets are known to generate efficient code for unaligned reads
279
+ * (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
280
+ * together). */
281
+ #define BROTLI_UNALIGNED_READ_FAST (!!1)
288
282
  #else
289
- #define BROTLI_ALIGNED_READ (!!1)
283
+ #define BROTLI_UNALIGNED_READ_FAST (!!0)
290
284
  #endif
291
285
 
292
- #if BROTLI_ALIGNED_READ
293
286
  /* Portable unaligned memory access: read / write values via memcpy. */
294
287
  static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
295
288
  uint16_t t;
@@ -309,75 +302,6 @@ static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
309
302
  static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
310
303
  memcpy(p, &v, sizeof v);
311
304
  }
312
- #else /* BROTLI_ALIGNED_READ */
313
- /* Unaligned memory access is allowed: just cast pointer to requested type. */
314
- #if BROTLI_SANITIZED
315
- /* Consider we have an unaligned load/store of 4 bytes from address 0x...05.
316
- AddressSanitizer will treat it as a 3-byte access to the range 05:07 and
317
- will miss a bug if 08 is the first unaddressable byte.
318
- ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will
319
- miss a race between this access and some other accesses to 08.
320
- MemorySanitizer will correctly propagate the shadow on unaligned stores
321
- and correctly report bugs on unaligned loads, but it may not properly
322
- update and report the origin of the uninitialized memory.
323
- For all three tools, replacing an unaligned access with a tool-specific
324
- callback solves the problem. */
325
- #if defined(__cplusplus)
326
- extern "C" {
327
- #endif /* __cplusplus */
328
- uint16_t __sanitizer_unaligned_load16(const void* p);
329
- uint32_t __sanitizer_unaligned_load32(const void* p);
330
- uint64_t __sanitizer_unaligned_load64(const void* p);
331
- void __sanitizer_unaligned_store64(void* p, uint64_t v);
332
- #if defined(__cplusplus)
333
- } /* extern "C" */
334
- #endif /* __cplusplus */
335
- #define BrotliUnalignedRead16 __sanitizer_unaligned_load16
336
- #define BrotliUnalignedRead32 __sanitizer_unaligned_load32
337
- #define BrotliUnalignedRead64 __sanitizer_unaligned_load64
338
- #define BrotliUnalignedWrite64 __sanitizer_unaligned_store64
339
- #else /* BROTLI_SANITIZED */
340
- static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) {
341
- return *(const uint16_t*)p;
342
- }
343
- static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) {
344
- return *(const uint32_t*)p;
345
- }
346
- #if (BROTLI_64_BITS)
347
- static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
348
- return *(const uint64_t*)p;
349
- }
350
- static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
351
- *(uint64_t*)p = v;
352
- }
353
- #else /* BROTLI_64_BITS */
354
- /* Avoid emitting LDRD / STRD, which require properly aligned address. */
355
- /* If __attribute__(aligned) is available, use that. Otherwise, memcpy. */
356
-
357
- #if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)
358
- typedef BROTLI_ALIGNED(1) uint64_t brotli_unaligned_uint64_t;
359
-
360
- static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
361
- return (uint64_t) ((const brotli_unaligned_uint64_t*) p)[0];
362
- }
363
- static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
364
- brotli_unaligned_uint64_t* dwords = (brotli_unaligned_uint64_t*) p;
365
- dwords[0] = (brotli_unaligned_uint64_t) v;
366
- }
367
- #else /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
368
- static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) {
369
- uint64_t v;
370
- memcpy(&v, p, sizeof(uint64_t));
371
- return v;
372
- }
373
-
374
- static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) {
375
- memcpy(p, &v, sizeof(uint64_t));
376
- }
377
- #endif /* BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) */
378
- #endif /* BROTLI_64_BITS */
379
- #endif /* BROTLI_SANITIZED */
380
- #endif /* BROTLI_ALIGNED_READ */
381
305
 
382
306
  #if BROTLI_LITTLE_ENDIAN
383
307
  /* Straight endianness. Just read / write values. */
@@ -453,6 +377,16 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
453
377
  }
454
378
  #endif /* BROTLI_LITTLE_ENDIAN */
455
379
 
380
+ static BROTLI_INLINE void* BROTLI_UNALIGNED_LOAD_PTR(const void* p) {
381
+ void* v;
382
+ memcpy(&v, p, sizeof(void*));
383
+ return v;
384
+ }
385
+
386
+ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) {
387
+ memcpy(p, &v, sizeof(void*));
388
+ }
389
+
456
390
  /* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */
457
391
  #if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \
458
392
  BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
@@ -474,22 +408,34 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) {
474
408
  #endif
475
409
 
476
410
  #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
411
+ #define BROTLI_ENABLE_DUMP_DEFAULT 1
477
412
  #define BROTLI_DCHECK(x) assert(x)
413
+ #else
414
+ #define BROTLI_ENABLE_DUMP_DEFAULT 0
415
+ #define BROTLI_DCHECK(x)
416
+ #endif
417
+
418
+ #if !defined(BROTLI_ENABLE_DUMP)
419
+ #define BROTLI_ENABLE_DUMP BROTLI_ENABLE_DUMP_DEFAULT
420
+ #endif
421
+
422
+ #if BROTLI_ENABLE_DUMP
478
423
  static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
479
424
  fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
480
425
  fflush(stderr);
481
426
  }
482
427
  #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
483
428
  #else
484
- #define BROTLI_DCHECK(x)
485
429
  #define BROTLI_DUMP() (void)(0)
486
430
  #endif
487
431
 
488
- /* TODO: add appropriate icc/sunpro/arm/ibm/ti checks. */
432
+ /* BrotliRBit assumes brotli_reg_t fits native CPU register type. */
433
+ #if (BROTLI_64_BITS == BROTLI_TARGET_64_BITS)
434
+ /* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */
489
435
  #if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \
490
436
  !defined(BROTLI_BUILD_NO_RBIT)
491
437
  #if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY)
492
- /* TODO: detect ARMv6T2 and enable this code for it. */
438
+ /* TODO(eustas): detect ARMv6T2 and enable this code for it. */
493
439
  static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
494
440
  brotli_reg_t output;
495
441
  __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
@@ -498,15 +444,14 @@ static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) {
498
444
  #define BROTLI_RBIT(x) BrotliRBit(x)
499
445
  #endif /* armv7 / armv8 */
500
446
  #endif /* gcc || clang */
447
+ #endif /* brotli_reg_t is native */
501
448
  #if !defined(BROTLI_RBIT)
502
449
  static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ }
503
450
  #endif /* BROTLI_RBIT */
504
451
 
505
- #define BROTLI_REPEAT(N, X) { \
506
- if ((N & 1) != 0) {X;} \
507
- if ((N & 2) != 0) {X; X;} \
508
- if ((N & 4) != 0) {X; X; X; X;} \
509
- }
452
+ #define BROTLI_REPEAT_4(X) {X; X; X; X;}
453
+ #define BROTLI_REPEAT_5(X) {X; X; X; X; X;}
454
+ #define BROTLI_REPEAT_6(X) {X; X; X; X; X; X;}
510
455
 
511
456
  #define BROTLI_UNUSED(X) (void)(X)
512
457
 
@@ -529,7 +474,7 @@ BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t)
529
474
  #if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \
530
475
  BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
531
476
  #define BROTLI_TZCNT64 __builtin_ctzll
532
- #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
477
+ #elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
533
478
  #if defined(BROTLI_TARGET_X64)
534
479
  #define BROTLI_TZCNT64 _tzcnt_u64
535
480
  #else /* BROTLI_TARGET_X64 */
@@ -546,7 +491,7 @@ static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) {
546
491
  #if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \
547
492
  BROTLI_INTEL_VERSION_CHECK(16, 0, 0)
548
493
  #define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x))
549
- #elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0)
494
+ #elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0)
550
495
  static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) {
551
496
  unsigned long msb;
552
497
  _BitScanReverse(&msb, x);
@@ -571,6 +516,8 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
571
516
  BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE);
572
517
  BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE);
573
518
  BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE);
519
+ BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD_PTR);
520
+ BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE_PTR);
574
521
  BROTLI_UNUSED(&BrotliRBit);
575
522
  BROTLI_UNUSED(&brotli_min_double);
576
523
  BROTLI_UNUSED(&brotli_max_double);
@@ -586,7 +533,7 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
586
533
  BROTLI_UNUSED(&brotli_max_uint8_t);
587
534
  BROTLI_UNUSED(&BrotliDefaultAllocFunc);
588
535
  BROTLI_UNUSED(&BrotliDefaultFreeFunc);
589
- #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
536
+ #if BROTLI_ENABLE_DUMP
590
537
  BROTLI_UNUSED(&BrotliDump);
591
538
  #endif
592
539
  }