ruby-brs 1.2.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7c98f5678a0545688d9a0bb7537d2eb55507559c2f6d61855796983e4b8a763
4
- data.tar.gz: 19bbed82c75ecf25c17a7848b97890dfad5387a3d9244b16db2447bb21425c1b
3
+ metadata.gz: 614baececc4a64311bdd172a962cb5f9bc721b2ade99ed84216ab79908f5a0ca
4
+ data.tar.gz: 88899da83cd343c1217652b7558a6770e43bd7722f3db7e1e3023ad54888bb54
5
5
  SHA512:
6
- metadata.gz: c7a82e47ac99a515794cc5e56153d10993b5b87fdb9f091dd04a685689dadcee2aec961b2cefbd1fd9531c457cd45af5d0d05af87178642b5bb545fa2f9f9246
7
- data.tar.gz: 481e233bfd17fe958a384787b2dd0f469b9017d7005cb9c1b88bdf48cad578767c5003e52b53ce6fcda35635a57339115a6cd21f0768281626df99995ee308ee
6
+ metadata.gz: efb6e0ec7ee97e4d4c6977b6843ee81ae6ec334af2985674634ea31a24ff00373753cc828bbc250ec137700fa721f84e1071fd6486cbbc2db869e4e6850e7255
7
+ data.tar.gz: 0ad07a2ebbbbbd27ff47a4e2780e90f297f4d02b36107f2877d45863f538b3f9b32b6aab18451a6376f620c6eee50118b6023b405cdb1f7c8079f1b8a295fd82
data/AUTHORS CHANGED
@@ -1 +1,2 @@
1
1
  Andrew Aladjev
2
+ Jenner La Fave
data/README.md CHANGED
@@ -8,7 +8,17 @@ See [brotli library](https://github.com/google/brotli).
8
8
 
9
9
  ## Installation
10
10
 
11
- Please install brotli library first, use latest 1.0.0+ version.
11
+ Operating systems: GNU/Linux, FreeBSD, OSX, Windows (MinGW).
12
+
13
+ Dependencies: [brotli](https://github.com/google/brotli) 1.0.0+ version.
14
+
15
+ | Popular OS | Dependencies |
16
+ |------------|---------------------------|
17
+ | Ubuntu | `libbrotli-dev` |
18
+ | CentOS | `brotli-devel` |
19
+ | ArchLinux | `brotli` |
20
+ | OSX | `brotli` |
21
+ | Windows | `mingw-w64-x86_64-brotli` |
12
22
 
13
23
  ```sh
14
24
  gem install ruby-brs
@@ -23,6 +33,22 @@ gem install pkg/ruby-brs-*.gem
23
33
 
24
34
  You can also use [overlay](https://github.com/andrew-aladev/overlay) for gentoo.
25
35
 
36
+ ### Installation in macOS on Apple Silicon
37
+
38
+ On M1 Macs, Homebrew installs to /opt/homebrew, so you'll need to specify its
39
+ include and lib paths when building the native extension for brotli.
40
+
41
+ ```sh
42
+ brew install brotli
43
+ gem install ruby-brs -- --with-opt-include=/opt/homebrew/include --with-opt-lib=/opt/homebrew/lib
44
+ ```
45
+
46
+ You can also configure Bundler to use those options when installing:
47
+
48
+ ```sh
49
+ bundle config set build.ruby-brs "--with-opt-include=/opt/homebrew/include --with-opt-lib=/opt/homebrew/lib"
50
+ ```
51
+
26
52
  ## Usage
27
53
 
28
54
  There are simple APIs: `String` and `File`. Also you can use generic streaming API: `Stream::Writer` and `Stream::Reader`.
@@ -118,6 +144,8 @@ end
118
144
  | `quality` | 0 - 11 | 11 | compression level |
119
145
  | `lgwin` | 10 - 24 | 22 | compressor window size |
120
146
  | `lgblock` | 16 - 24 | nil (auto) | compressor input block size |
147
+ | `npostfix` | 0 - 3 | nil (auto) | Recommended number of postfix bits |
148
+ | `ndirect` | 0 - 120 | nil (auto) | Recommended number of direct distance codes (step 1 << npostfix, max 15 << npostfix) |
121
149
  | `disable_literal_context_modeling` | true/false | false | disables literal context modeling format |
122
150
  | `disable_ring_buffer_reallocation` | true/false | false | disables ring buffer reallocation |
123
151
  | `size_hint` | 0 - inf | 0 (auto) | size of input (if known) |
@@ -135,12 +163,14 @@ If `gvl` is enabled ruby won't waste time on acquiring/releasing VM lock.
135
163
 
136
164
  You can also read brotli docs for more info about options.
137
165
 
138
- | Option | Related constants |
139
- |-----------|-------------------|
140
- | `mode` | `BRS::Option::MODES` = `%i[text font generic]` |
141
- | `quality` | `BRS::Option::MIN_QUALITY` = 0, `BRS::Option::MAX_QUALITY` = 11 |
142
- | `lgwin` | `BRS::Option::MIN_LGWIN` = 10, `BRS::Option::MAX_LGWIN` = 24 |
143
- | `lgblock` | `BRS::Option::MIN_LGBLOCK` = 16, `BRS::Option::MAX_LGBLOCK` = 24 |
166
+ | Option | Related constants |
167
+ |------------|-------------------|
168
+ | `mode` | `BRS::Option::MODES` = `%i[text font generic]` |
169
+ | `quality` | `BRS::Option::MIN_QUALITY` = 0, `BRS::Option::MAX_QUALITY` = 11 |
170
+ | `lgwin` | `BRS::Option::MIN_LGWIN` = 10, `BRS::Option::MAX_LGWIN` = 24 |
171
+ | `lgblock` | `BRS::Option::MIN_LGBLOCK` = 16, `BRS::Option::MAX_LGBLOCK` = 24 |
172
+ | `npostfix` | `BRS::Option::MIN_NPOSTFIX` = 0, `BRS::Option::MAX_NPOSTFIX` = 3 |
173
+ | `ndirect` | `BRS::Option::MIN_NDIRECT` = 0, `BRS::Option::MAX_NDIRECT` = 120, `BRS::Option::NDIRECT_NPOSTFIX_STEP_BASE` = 1, `BRS::Option::NDIRECT_NPOSTFIX_MAX_BASE` = 15 |
144
174
 
145
175
  Possible compressor options:
146
176
  ```
@@ -151,6 +181,8 @@ Possible compressor options:
151
181
  :quality
152
182
  :lgwin
153
183
  :lgblock
184
+ :npostfix
185
+ :ndirect
154
186
  :disable_literal_context_modeling
155
187
  :size_hint
156
188
  :large_window
@@ -361,10 +393,6 @@ You should lock all shared data between threads.
361
393
  For example: you should not use same compressor/decompressor inside multiple threads.
362
394
  Please verify that you are using each processor inside single thread at the same time.
363
395
 
364
- ## Operating systems
365
-
366
- GNU/Linux, FreeBSD, OSX, Windows (MinGW).
367
-
368
396
  ## CI
369
397
 
370
398
  Please visit [scripts/test-images](scripts/test-images).
data/ext/brs_ext/buffer.c CHANGED
@@ -3,8 +3,6 @@
3
3
 
4
4
  #include "brs_ext/buffer.h"
5
5
 
6
- #include "ruby.h"
7
-
8
6
  VALUE brs_ext_create_string_buffer(VALUE length)
9
7
  {
10
8
  return rb_str_new(NULL, NUM2SIZET(length));
data/ext/brs_ext/error.c CHANGED
@@ -3,10 +3,6 @@
3
3
 
4
4
  #include "brs_ext/error.h"
5
5
 
6
- #include <brotli/decode.h>
7
-
8
- #include "ruby.h"
9
-
10
6
  brs_ext_result_t brs_ext_get_decompressor_error(BrotliDecoderErrorCode error_code)
11
7
  {
12
8
  switch (error_code) {
data/ext/brs_ext/gvl.h CHANGED
@@ -4,7 +4,7 @@
4
4
  #if !defined(BRS_EXT_GVL_H)
5
5
  #define BRS_EXT_GVL_H
6
6
 
7
- #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
7
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
8
8
 
9
9
  #include "ruby/thread.h"
10
10
 
@@ -19,6 +19,6 @@
19
19
 
20
20
  #define BRS_EXT_GVL_WRAP(_gvl, function, data) function((void*) data);
21
21
 
22
- #endif
22
+ #endif // HAVE_RB_THREAD_CALL_WITHOUT_GVL
23
23
 
24
24
  #endif // BRS_EXT_GVL_H
data/ext/brs_ext/io.c CHANGED
@@ -15,7 +15,6 @@
15
15
  #include "brs_ext/gvl.h"
16
16
  #include "brs_ext/macro.h"
17
17
  #include "brs_ext/option.h"
18
- #include "ruby.h"
19
18
  #include "ruby/io.h"
20
19
 
21
20
  // Additional possible results:
data/ext/brs_ext/macro.h CHANGED
@@ -8,6 +8,6 @@
8
8
  #define BRS_EXT_UNUSED(x) x __attribute__((__unused__))
9
9
  #else
10
10
  #define BRS_EXT_UNUSED(x) x
11
- #endif
11
+ #endif // __GNUC__
12
12
 
13
13
  #endif // BRS_EXT_MACRO_H
data/ext/brs_ext/main.c CHANGED
@@ -7,7 +7,6 @@
7
7
  #include "brs_ext/stream/compressor.h"
8
8
  #include "brs_ext/stream/decompressor.h"
9
9
  #include "brs_ext/string.h"
10
- #include "ruby.h"
11
10
 
12
11
  void Init_brs_ext()
13
12
  {
@@ -19,4 +18,8 @@ void Init_brs_ext()
19
18
  brs_ext_compressor_exports(root_module);
20
19
  brs_ext_decompressor_exports(root_module);
21
20
  brs_ext_string_exports(root_module);
21
+
22
+ VALUE version_arguments[] = {INT2FIX(16)};
23
+ VALUE version = rb_block_call(UINT2NUM(BrotliEncoderVersion()), rb_intern("to_s"), 1, version_arguments, 0, 0);
24
+ rb_define_const(root_module, "LIBRARY_VERSION", rb_obj_freeze(version));
22
25
  }
data/ext/brs_ext/option.c CHANGED
@@ -3,11 +3,7 @@
3
3
 
4
4
  #include "brs_ext/option.h"
5
5
 
6
- #include <brotli/decode.h>
7
- #include <brotli/encode.h>
8
-
9
6
  #include "brs_ext/error.h"
10
- #include "ruby.h"
11
7
 
12
8
  // -- values --
13
9
 
@@ -114,6 +110,8 @@ brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, b
114
110
  SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_QUALITY, options->quality);
115
111
  SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGWIN, options->lgwin);
116
112
  SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGBLOCK, options->lgblock);
113
+ SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_NPOSTFIX, options->npostfix);
114
+ SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_NDIRECT, options->ndirect);
117
115
  SET_ENCODER_PARAM(
118
116
  state_ptr, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING, options->disable_literal_context_modeling);
119
117
  SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_SIZE_HINT, options->size_hint);
@@ -138,6 +136,14 @@ brs_ext_result_t brs_ext_set_decompressor_options(
138
136
 
139
137
  // -- exports --
140
138
 
139
+ #define BROTLI_MIN_NPOSTFIX 0
140
+ #define BROTLI_MAX_NPOSTFIX 3
141
+
142
+ #define BROTLI_MIN_NDIRECT 0
143
+ #define BROTLI_NDIRECT_NPOSTFIX_STEP_BASE 1
144
+ #define BROTLI_NDIRECT_NPOSTFIX_MAX_BASE 0xf
145
+ #define BROTLI_MAX_NDIRECT (BROTLI_NDIRECT_NPOSTFIX_MAX_BASE << BROTLI_MAX_NPOSTFIX)
146
+
141
147
  #define EXPORT_PARAM_BOUNDS(module, param, name) \
142
148
  rb_define_const(module, "MIN_" name, UINT2NUM(BROTLI_MIN_##param)); \
143
149
  rb_define_const(module, "MAX_" name, UINT2NUM(BROTLI_MAX_##param));
@@ -151,7 +157,12 @@ void brs_ext_option_exports(VALUE root_module)
151
157
  rb_define_const(module, "MODES", modes);
152
158
  RB_GC_GUARD(modes);
153
159
 
154
- EXPORT_PARAM_BOUNDS(module, QUALITY, "QUALITY");
155
- EXPORT_PARAM_BOUNDS(module, WINDOW_BITS, "LGWIN");
156
160
  EXPORT_PARAM_BOUNDS(module, INPUT_BLOCK_BITS, "LGBLOCK");
161
+ EXPORT_PARAM_BOUNDS(module, WINDOW_BITS, "LGWIN");
162
+ EXPORT_PARAM_BOUNDS(module, QUALITY, "QUALITY");
163
+ EXPORT_PARAM_BOUNDS(module, NPOSTFIX, "NPOSTFIX");
164
+ EXPORT_PARAM_BOUNDS(module, NDIRECT, "NDIRECT");
165
+
166
+ rb_define_const(module, "NDIRECT_NPOSTFIX_STEP_BASE", UINT2NUM(BROTLI_NDIRECT_NPOSTFIX_STEP_BASE));
167
+ rb_define_const(module, "NDIRECT_NPOSTFIX_MAX_BASE", UINT2NUM(BROTLI_NDIRECT_NPOSTFIX_MAX_BASE));
157
168
  }
data/ext/brs_ext/option.h CHANGED
@@ -37,6 +37,8 @@ typedef struct
37
37
  brs_ext_option_t quality;
38
38
  brs_ext_option_t lgwin;
39
39
  brs_ext_option_t lgblock;
40
+ brs_ext_option_t npostfix;
41
+ brs_ext_option_t ndirect;
40
42
  brs_ext_option_t disable_literal_context_modeling;
41
43
  brs_ext_option_t size_hint;
42
44
  brs_ext_option_t large_window;
@@ -60,6 +62,8 @@ void brs_ext_resolve_option(VALUE options, brs_ext_option_t* option, brs_ext_opt
60
62
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, quality); \
61
63
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgwin); \
62
64
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgblock); \
65
+ BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, npostfix); \
66
+ BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, ndirect); \
63
67
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, disable_literal_context_modeling); \
64
68
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, size_hint); \
65
69
  BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, large_window);
@@ -3,14 +3,12 @@
3
3
 
4
4
  #include "brs_ext/stream/compressor.h"
5
5
 
6
- #include <brotli/encode.h>
7
6
  #include <brotli/types.h>
8
7
 
9
8
  #include "brs_ext/buffer.h"
10
9
  #include "brs_ext/error.h"
11
10
  #include "brs_ext/gvl.h"
12
11
  #include "brs_ext/option.h"
13
- #include "ruby.h"
14
12
 
15
13
  // -- initialization --
16
14
 
@@ -3,13 +3,10 @@
3
3
 
4
4
  #include "brs_ext/stream/decompressor.h"
5
5
 
6
- #include <brotli/decode.h>
7
-
8
6
  #include "brs_ext/buffer.h"
9
7
  #include "brs_ext/error.h"
10
8
  #include "brs_ext/gvl.h"
11
9
  #include "brs_ext/option.h"
12
- #include "ruby.h"
13
10
 
14
11
  // -- initialization --
15
12
 
data/ext/brs_ext/string.c CHANGED
@@ -13,7 +13,6 @@
13
13
  #include "brs_ext/gvl.h"
14
14
  #include "brs_ext/macro.h"
15
15
  #include "brs_ext/option.h"
16
- #include "ruby.h"
17
16
 
18
17
  // -- buffer --
19
18
 
data/ext/extconf.rb CHANGED
@@ -5,17 +5,93 @@ require "mkmf"
5
5
 
6
6
  have_func "rb_thread_call_without_gvl", "ruby/thread.h"
7
7
 
8
- def require_header(name, types = [])
8
+ def require_header(name, constants: [], macroses: [], types: [])
9
9
  abort "Can't find #{name} header" unless find_header name
10
10
 
11
+ constants.each do |constant|
12
+ abort "Can't find #{constant} constant in #{name} header" unless have_const constant, name
13
+ end
14
+
15
+ macroses.each do |macro|
16
+ abort "Can't find #{macro} macro in #{name} header" unless have_macro macro, name
17
+ end
18
+
11
19
  types.each do |type|
12
20
  abort "Can't find #{type} type in #{name} header" unless find_type type, nil, name
13
21
  end
14
22
  end
15
23
 
16
- require_header "brotli/types.h", %w[BROTLI_BOOL]
17
- require_header "brotli/encode.h", ["BrotliEncoderState *", "BrotliEncoderMode"]
18
- require_header "brotli/decode.h", ["BrotliDecoderState *", "BrotliDecoderResult", "BrotliDecoderErrorCode"]
24
+ require_header(
25
+ "brotli/decode.h",
26
+ :constants => %w[
27
+ BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES
28
+ BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP
29
+ BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES
30
+ BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1
31
+ BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2
32
+ BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS
33
+ BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1
34
+ BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2
35
+ BROTLI_DECODER_ERROR_FORMAT_CL_SPACE
36
+ BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT
37
+ BROTLI_DECODER_ERROR_FORMAT_DICTIONARY
38
+ BROTLI_DECODER_ERROR_FORMAT_DISTANCE
39
+ BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE
40
+ BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE
41
+ BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE
42
+ BROTLI_DECODER_ERROR_FORMAT_PADDING_1
43
+ BROTLI_DECODER_ERROR_FORMAT_PADDING_2
44
+ BROTLI_DECODER_ERROR_FORMAT_RESERVED
45
+ BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET
46
+ BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME
47
+ BROTLI_DECODER_ERROR_FORMAT_TRANSFORM
48
+ BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS
49
+ BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION
50
+ BROTLI_DECODER_PARAM_LARGE_WINDOW
51
+ BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT
52
+ BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT
53
+ BROTLI_DECODER_RESULT_SUCCESS
54
+ ],
55
+ :types => [
56
+ "BrotliDecoderErrorCode",
57
+ "BrotliDecoderResult",
58
+ "BrotliDecoderState *"
59
+ ]
60
+ )
61
+ require_header(
62
+ "brotli/encode.h",
63
+ :constants => %w[
64
+ BROTLI_MAX_INPUT_BLOCK_BITS
65
+ BROTLI_MAX_QUALITY
66
+ BROTLI_MAX_WINDOW_BITS
67
+ BROTLI_MIN_INPUT_BLOCK_BITS
68
+ BROTLI_MIN_QUALITY
69
+ BROTLI_MIN_WINDOW_BITS
70
+ BROTLI_MODE_FONT
71
+ BROTLI_MODE_GENERIC
72
+ BROTLI_MODE_TEXT
73
+ BROTLI_OPERATION_FINISH
74
+ BROTLI_OPERATION_FLUSH
75
+ BROTLI_OPERATION_PROCESS
76
+ BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING
77
+ BROTLI_PARAM_LARGE_WINDOW
78
+ BROTLI_PARAM_LGBLOCK
79
+ BROTLI_PARAM_LGWIN
80
+ BROTLI_PARAM_NDIRECT
81
+ BROTLI_PARAM_NPOSTFIX
82
+ BROTLI_PARAM_MODE
83
+ BROTLI_PARAM_QUALITY
84
+ BROTLI_PARAM_SIZE_HINT
85
+ ],
86
+ :types => [
87
+ "BrotliEncoderMode",
88
+ "BrotliEncoderState *"
89
+ ]
90
+ )
91
+ require_header(
92
+ "brotli/types.h",
93
+ :macroses => %w[BROTLI_BOOL]
94
+ )
19
95
 
20
96
  def require_library(name, functions)
21
97
  functions.each do |function|
@@ -26,12 +102,13 @@ end
26
102
  require_library(
27
103
  "brotlienc",
28
104
  %w[
29
- BrotliEncoderCreateInstance
30
- BrotliEncoderSetParameter
31
105
  BrotliEncoderCompressStream
106
+ BrotliEncoderCreateInstance
107
+ BrotliEncoderDestroyInstance
32
108
  BrotliEncoderHasMoreOutput
33
109
  BrotliEncoderIsFinished
34
- BrotliEncoderDestroyInstance
110
+ BrotliEncoderSetParameter
111
+ BrotliEncoderVersion
35
112
  ]
36
113
  )
37
114
 
@@ -39,10 +116,11 @@ require_library(
39
116
  "brotlidec",
40
117
  %w[
41
118
  BrotliDecoderCreateInstance
42
- BrotliDecoderSetParameter
43
119
  BrotliDecoderDecompressStream
44
- BrotliDecoderGetErrorCode
45
120
  BrotliDecoderDestroyInstance
121
+ BrotliDecoderGetErrorCode
122
+ BrotliDecoderSetParameter
123
+ BrotliDecoderVersion
46
124
  ]
47
125
  )
48
126
 
data/lib/brs/option.rb CHANGED
@@ -16,6 +16,8 @@ module BRS
16
16
  :quality => nil,
17
17
  :lgwin => nil,
18
18
  :lgblock => nil,
19
+ :npostfix => nil,
20
+ :ndirect => nil,
19
21
  :disable_literal_context_modeling => nil,
20
22
  :large_window => nil
21
23
  }
@@ -65,6 +67,24 @@ module BRS
65
67
  raise ValidateError, "invalid lgblock" if lgblock < MIN_LGBLOCK || lgblock > MAX_LGBLOCK
66
68
  end
67
69
 
70
+ npostfix = options[:npostfix]
71
+ unless npostfix.nil?
72
+ Validation.validate_not_negative_integer npostfix
73
+ raise ValidateError, "invalid npostfix" if npostfix < MIN_NPOSTFIX || npostfix > MAX_NPOSTFIX
74
+ end
75
+
76
+ ndirect = options[:ndirect]
77
+ unless ndirect.nil?
78
+ Validation.validate_not_negative_integer ndirect
79
+ raise ValidateError, "invalid ndirect" if ndirect < MIN_NDIRECT || ndirect > MAX_NDIRECT
80
+
81
+ raise ValidateError, "invalid ndirect" if
82
+ !npostfix.nil? && (
83
+ (ndirect - MIN_NDIRECT) % (NDIRECT_NPOSTFIX_STEP_BASE << npostfix) != 0 ||
84
+ (ndirect - MIN_NDIRECT) > (NDIRECT_NPOSTFIX_MAX_BASE << npostfix)
85
+ )
86
+ end
87
+
68
88
  disable_literal_context_modeling = options[:disable_literal_context_modeling]
69
89
  Validation.validate_bool disable_literal_context_modeling unless disable_literal_context_modeling.nil?
70
90
 
@@ -24,9 +24,7 @@ module BRS
24
24
 
25
25
  def initialize(io, options = {})
26
26
  @raw_stream = create_raw_stream
27
-
28
- Validation.validate_io io
29
- @io = io
27
+ @io = io
30
28
 
31
29
  @stat = Stat.new @io.stat if @io.respond_to? :stat
32
30
 
@@ -135,13 +133,19 @@ module BRS
135
133
  end
136
134
 
137
135
  def close
138
- @io.close
136
+ @io.close if @io.respond_to? :close
139
137
 
140
138
  nil
141
139
  end
142
140
 
143
141
  def closed?
144
- @raw_stream.closed? && @io.closed?
142
+ return false unless @raw_stream.closed?
143
+
144
+ if @io.respond_to? :closed
145
+ @io.closed?
146
+ else
147
+ true
148
+ end
145
149
  end
146
150
 
147
151
  def to_io
@@ -54,6 +54,9 @@ module BRS
54
54
  Validation.validate_not_negative_integer bytes_to_read unless bytes_to_read.nil?
55
55
  Validation.validate_string out_buffer unless out_buffer.nil?
56
56
 
57
+ raise ValidateError, "io should be responsible to read and eof" unless
58
+ @io.respond_to?(:read) && @io.respond_to?(:eof?)
59
+
57
60
  unless bytes_to_read.nil?
58
61
  return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
59
62
  return nil if eof?
@@ -86,16 +89,22 @@ module BRS
86
89
  end
87
90
 
88
91
  def eof?
92
+ raise ValidateError, "io should be responsible to eof" unless @io.respond_to? :eof?
93
+
89
94
  empty? && @io.eof?
90
95
  end
91
96
 
92
97
  # -- asynchronous --
93
98
 
94
99
  def readpartial(bytes_to_read, out_buffer = nil)
100
+ raise ValidateError, "io should be responsible to readpartial" unless @io.respond_to? :readpartial
101
+
95
102
  read_more_nonblock(bytes_to_read, out_buffer) { @io.readpartial @source_buffer_length }
96
103
  end
97
104
 
98
105
  def read_nonblock(bytes_to_read, out_buffer = nil, *options)
106
+ raise ValidateError, "io should be responsible to read nonblock" unless @io.respond_to? :read_nonblock
107
+
99
108
  read_more_nonblock(bytes_to_read, out_buffer) { @io.read_nonblock(@source_buffer_length, *options) }
100
109
  end
101
110
 
@@ -23,6 +23,8 @@ module BRS
23
23
  # -- synchronous --
24
24
 
25
25
  def write(*objects)
26
+ validate_write
27
+
26
28
  write_remaining_buffer
27
29
 
28
30
  bytes_written = 0
@@ -38,20 +40,26 @@ module BRS
38
40
  end
39
41
 
40
42
  def flush
43
+ validate_write
44
+
41
45
  finish :flush
42
46
 
43
- @io.flush
47
+ @io.flush if @io.respond_to? :flush
44
48
 
45
49
  self
46
50
  end
47
51
 
48
52
  def rewind
53
+ validate_write
54
+
49
55
  finish :close
50
56
 
51
57
  super
52
58
  end
53
59
 
54
60
  def close
61
+ validate_write
62
+
55
63
  finish :close
56
64
 
57
65
  super
@@ -75,6 +83,10 @@ module BRS
75
83
  @raw_stream.send(method_name, *args) { |portion| @io.write portion }
76
84
  end
77
85
 
86
+ def validate_write
87
+ raise ValidateError, "io should be responsible to write" unless @io.respond_to? :write
88
+ end
89
+
78
90
  # -- asynchronous --
79
91
 
80
92
  # IO write nonblock can raise wait writable error.
@@ -83,6 +95,8 @@ module BRS
83
95
  # So we have to accept content after processing IO write nonblock.
84
96
  # It means that first write nonblock won't call IO write nonblock.
85
97
  def write_nonblock(object, *options)
98
+ validate_write_nonblock
99
+
86
100
  return 0 unless write_remaining_buffer_nonblock(*options)
87
101
 
88
102
  source = transcode object.to_s
@@ -93,14 +107,18 @@ module BRS
93
107
  end
94
108
 
95
109
  def flush_nonblock(*options)
110
+ validate_write_nonblock
111
+
96
112
  return false unless finish_nonblock :flush, *options
97
113
 
98
- @io.flush
114
+ @io.flush if @io.respond_to? :flush
99
115
 
100
116
  true
101
117
  end
102
118
 
103
119
  def rewind_nonblock(*options)
120
+ validate_write_nonblock
121
+
104
122
  return false unless finish_nonblock :close, *options
105
123
 
106
124
  method(:rewind).super_method.call
@@ -109,6 +127,8 @@ module BRS
109
127
  end
110
128
 
111
129
  def close_nonblock(*options)
130
+ validate_write_nonblock
131
+
112
132
  return false unless finish_nonblock :close, *options
113
133
 
114
134
  method(:close).super_method.call
@@ -139,6 +159,10 @@ module BRS
139
159
  @raw_stream.send(method_name, *args) { |portion| @buffer << portion }
140
160
  end
141
161
 
162
+ def validate_write_nonblock
163
+ raise ValidateError, "io should be responsible to write nonblock" unless @io.respond_to? :write_nonblock
164
+ end
165
+
142
166
  # -- common --
143
167
 
144
168
  protected def transcode(data)
@@ -5,45 +5,20 @@ require_relative "error"
5
5
 
6
6
  module BRS
7
7
  module Validation
8
- IO_METHODS = %i[
9
- read
10
- write
11
- readpartial
12
- read_nonblock
13
- write_nonblock
14
- eof?
15
- flush
16
- close
17
- closed?
18
- ]
19
- .freeze
20
-
21
8
  def self.validate_bool(value)
22
9
  raise ValidateError, "invalid bool" unless value.is_a?(::TrueClass) || value.is_a?(::FalseClass)
23
10
  end
24
11
 
25
- def self.validate_positive_integer(value)
26
- raise ValidateError, "invalid positive integer" unless value.is_a?(::Integer) && value.positive?
12
+ def self.validate_hash(value)
13
+ raise ValidateError, "invalid hash" unless value.is_a? ::Hash
27
14
  end
28
15
 
29
16
  def self.validate_not_negative_integer(value)
30
17
  raise ValidateError, "invalid not negative integer" unless value.is_a?(::Integer) && value >= 0
31
18
  end
32
19
 
33
- def self.validate_string(value)
34
- raise ValidateError, "invalid string" unless value.is_a? ::String
35
- end
36
-
37
- def self.validate_symbol(value)
38
- raise ValidateError, "invalid symbol" unless value.is_a? ::Symbol
39
- end
40
-
41
- def self.validate_io(value)
42
- raise ValidateError, "invalid io" unless IO_METHODS.all? { |method| value.respond_to? method }
43
- end
44
-
45
- def self.validate_hash(value)
46
- raise ValidateError, "invalid hash" unless value.is_a? ::Hash
20
+ def self.validate_positive_integer(value)
21
+ raise ValidateError, "invalid positive integer" unless value.is_a?(::Integer) && value.positive?
47
22
  end
48
23
 
49
24
  def self.validate_proc(value)
@@ -51,5 +26,13 @@ module BRS
51
26
  raise ValidateError, "invalid proc"
52
27
  end
53
28
  end
29
+
30
+ def self.validate_string(value)
31
+ raise ValidateError, "invalid string" unless value.is_a? ::String
32
+ end
33
+
34
+ def self.validate_symbol(value)
35
+ raise ValidateError, "invalid symbol" unless value.is_a? ::Symbol
36
+ end
54
37
  end
55
38
  end
data/lib/brs/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
4
  module BRS
5
- VERSION = "1.2.1".freeze
5
+ VERSION = "1.3.2".freeze
6
6
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-brs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Aladjev
8
+ - Jenner La Fave
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2021-06-04 00:00:00.000000000 Z
12
+ date: 2022-03-18 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: codecov
@@ -58,28 +59,28 @@ dependencies:
58
59
  requirements:
59
60
  - - "~>"
60
61
  - !ruby/object:Gem::Version
61
- version: '5.14'
62
+ version: '5.15'
62
63
  type: :development
63
64
  prerelease: false
64
65
  version_requirements: !ruby/object:Gem::Requirement
65
66
  requirements:
66
67
  - - "~>"
67
68
  - !ruby/object:Gem::Version
68
- version: '5.14'
69
+ version: '5.15'
69
70
  - !ruby/object:Gem::Dependency
70
71
  name: ocg
71
72
  requirement: !ruby/object:Gem::Requirement
72
73
  requirements:
73
74
  - - "~>"
74
75
  - !ruby/object:Gem::Version
75
- version: '1.3'
76
+ version: '1.4'
76
77
  type: :development
77
78
  prerelease: false
78
79
  version_requirements: !ruby/object:Gem::Requirement
79
80
  requirements:
80
81
  - - "~>"
81
82
  - !ruby/object:Gem::Version
82
- version: '1.3'
83
+ version: '1.4'
83
84
  - !ruby/object:Gem::Dependency
84
85
  name: parallel
85
86
  requirement: !ruby/object:Gem::Requirement
@@ -128,56 +129,56 @@ dependencies:
128
129
  requirements:
129
130
  - - "~>"
130
131
  - !ruby/object:Gem::Version
131
- version: '1.16'
132
+ version: '1.26'
132
133
  type: :development
133
134
  prerelease: false
134
135
  version_requirements: !ruby/object:Gem::Requirement
135
136
  requirements:
136
137
  - - "~>"
137
138
  - !ruby/object:Gem::Version
138
- version: '1.16'
139
+ version: '1.26'
139
140
  - !ruby/object:Gem::Dependency
140
141
  name: rubocop-minitest
141
142
  requirement: !ruby/object:Gem::Requirement
142
143
  requirements:
143
144
  - - "~>"
144
145
  - !ruby/object:Gem::Version
145
- version: '0.12'
146
+ version: '0.17'
146
147
  type: :development
147
148
  prerelease: false
148
149
  version_requirements: !ruby/object:Gem::Requirement
149
150
  requirements:
150
151
  - - "~>"
151
152
  - !ruby/object:Gem::Version
152
- version: '0.12'
153
+ version: '0.17'
153
154
  - !ruby/object:Gem::Dependency
154
155
  name: rubocop-performance
155
156
  requirement: !ruby/object:Gem::Requirement
156
157
  requirements:
157
158
  - - "~>"
158
159
  - !ruby/object:Gem::Version
159
- version: '1.11'
160
+ version: '1.13'
160
161
  type: :development
161
162
  prerelease: false
162
163
  version_requirements: !ruby/object:Gem::Requirement
163
164
  requirements:
164
165
  - - "~>"
165
166
  - !ruby/object:Gem::Version
166
- version: '1.11'
167
+ version: '1.13'
167
168
  - !ruby/object:Gem::Dependency
168
169
  name: rubocop-rake
169
170
  requirement: !ruby/object:Gem::Requirement
170
171
  requirements:
171
172
  - - "~>"
172
173
  - !ruby/object:Gem::Version
173
- version: '0.5'
174
+ version: '0.6'
174
175
  type: :development
175
176
  prerelease: false
176
177
  version_requirements: !ruby/object:Gem::Requirement
177
178
  requirements:
178
179
  - - "~>"
179
180
  - !ruby/object:Gem::Version
180
- version: '0.5'
181
+ version: '0.6'
181
182
  - !ruby/object:Gem::Dependency
182
183
  name: simplecov
183
184
  requirement: !ruby/object:Gem::Requirement
@@ -241,7 +242,8 @@ files:
241
242
  homepage: https://github.com/andrew-aladev/ruby-brs
242
243
  licenses:
243
244
  - MIT
244
- metadata: {}
245
+ metadata:
246
+ rubygems_mfa_required: 'true'
245
247
  post_install_message:
246
248
  rdoc_options: []
247
249
  require_paths:
@@ -257,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
259
  - !ruby/object:Gem::Version
258
260
  version: '0'
259
261
  requirements: []
260
- rubygems_version: 3.2.15
262
+ rubygems_version: 3.3.7
261
263
  signing_key:
262
264
  specification_version: 4
263
265
  summary: Ruby bindings for brotli library.