ruby-zstds 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +1 -0
  3. data/LICENSE +21 -0
  4. data/README.md +498 -0
  5. data/ext/extconf.rb +82 -0
  6. data/ext/zstds_ext/buffer.c +30 -0
  7. data/ext/zstds_ext/buffer.h +23 -0
  8. data/ext/zstds_ext/common.h +16 -0
  9. data/ext/zstds_ext/dictionary.c +106 -0
  10. data/ext/zstds_ext/dictionary.h +16 -0
  11. data/ext/zstds_ext/error.c +81 -0
  12. data/ext/zstds_ext/error.h +35 -0
  13. data/ext/zstds_ext/io.c +512 -0
  14. data/ext/zstds_ext/io.h +14 -0
  15. data/ext/zstds_ext/macro.h +13 -0
  16. data/ext/zstds_ext/main.c +25 -0
  17. data/ext/zstds_ext/option.c +287 -0
  18. data/ext/zstds_ext/option.h +122 -0
  19. data/ext/zstds_ext/stream/compressor.c +241 -0
  20. data/ext/zstds_ext/stream/compressor.h +31 -0
  21. data/ext/zstds_ext/stream/decompressor.c +183 -0
  22. data/ext/zstds_ext/stream/decompressor.h +29 -0
  23. data/ext/zstds_ext/string.c +254 -0
  24. data/ext/zstds_ext/string.h +14 -0
  25. data/lib/zstds.rb +9 -0
  26. data/lib/zstds/dictionary.rb +47 -0
  27. data/lib/zstds/error.rb +22 -0
  28. data/lib/zstds/file.rb +46 -0
  29. data/lib/zstds/option.rb +194 -0
  30. data/lib/zstds/stream/abstract.rb +153 -0
  31. data/lib/zstds/stream/delegates.rb +36 -0
  32. data/lib/zstds/stream/raw/abstract.rb +55 -0
  33. data/lib/zstds/stream/raw/compressor.rb +101 -0
  34. data/lib/zstds/stream/raw/decompressor.rb +70 -0
  35. data/lib/zstds/stream/reader.rb +166 -0
  36. data/lib/zstds/stream/reader_helpers.rb +192 -0
  37. data/lib/zstds/stream/stat.rb +78 -0
  38. data/lib/zstds/stream/writer.rb +145 -0
  39. data/lib/zstds/stream/writer_helpers.rb +93 -0
  40. data/lib/zstds/string.rb +31 -0
  41. data/lib/zstds/validation.rb +48 -0
  42. data/lib/zstds/version.rb +6 -0
  43. metadata +182 -0
@@ -0,0 +1,29 @@
1
+ // Ruby bindings for zstd library.
2
+ // Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ #if !defined(ZSTDS_EXT_STREAM_DECOMPRESSOR_H)
5
+ #define ZSTDS_EXT_STREAM_DECOMPRESSOR_H
6
+
7
+ #include <stdint.h>
8
+ #include <stdlib.h>
9
+ #include <zstd.h>
10
+
11
+ #include "ruby.h"
12
+
13
+ typedef struct {
14
+ ZSTD_DCtx* ctx;
15
+ uint8_t* destination_buffer;
16
+ size_t destination_buffer_length;
17
+ uint8_t* remaining_destination_buffer;
18
+ size_t remaining_destination_buffer_length;
19
+ } zstds_ext_decompressor_t;
20
+
21
+ VALUE zstds_ext_allocate_decompressor(VALUE klass);
22
+ VALUE zstds_ext_initialize_decompressor(VALUE self, VALUE options);
23
+ VALUE zstds_ext_decompress(VALUE self, VALUE source);
24
+ VALUE zstds_ext_decompressor_read_result(VALUE self);
25
+ VALUE zstds_ext_decompressor_close(VALUE self);
26
+
27
+ void zstds_ext_decompressor_exports(VALUE root_module);
28
+
29
+ #endif // ZSTDS_EXT_STREAM_DECOMPRESSOR_H
@@ -0,0 +1,254 @@
1
+ // Ruby bindings for zstd library.
2
+ // Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ #include "zstds_ext/string.h"
5
+
6
+ #include <stdint.h>
7
+ #include <stdlib.h>
8
+ #include <zstd.h>
9
+
10
+ #include "ruby.h"
11
+ #include "zstds_ext/buffer.h"
12
+ #include "zstds_ext/common.h"
13
+ #include "zstds_ext/error.h"
14
+ #include "zstds_ext/macro.h"
15
+ #include "zstds_ext/option.h"
16
+
17
+ // -- buffer --
18
+
19
+ static inline zstds_ext_result_t increase_destination_buffer(
20
+ VALUE destination_value, size_t destination_length,
21
+ size_t* remaining_destination_buffer_length_ptr, size_t destination_buffer_length)
22
+ {
23
+ if (*remaining_destination_buffer_length_ptr == destination_buffer_length) {
24
+ // We want to write more data at once, than buffer has.
25
+ return ZSTDS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER;
26
+ }
27
+
28
+ int exception;
29
+
30
+ ZSTDS_EXT_RESIZE_STRING_BUFFER(destination_value, destination_length + destination_buffer_length, exception);
31
+ if (exception != 0) {
32
+ return ZSTDS_EXT_ERROR_ALLOCATE_FAILED;
33
+ }
34
+
35
+ *remaining_destination_buffer_length_ptr = destination_buffer_length;
36
+
37
+ return 0;
38
+ }
39
+
40
+ // -- utils --
41
+
42
+ #define GET_SOURCE_DATA(source_value) \
43
+ Check_Type(source_value, T_STRING); \
44
+ \
45
+ const char* source = RSTRING_PTR(source_value); \
46
+ size_t source_length = RSTRING_LEN(source_value);
47
+
48
+ // -- compress --
49
+
50
+ static inline zstds_ext_result_t compress(
51
+ ZSTD_CCtx* ctx,
52
+ const char* source, size_t source_length,
53
+ VALUE destination_value, size_t destination_buffer_length)
54
+ {
55
+ zstds_result_t result;
56
+ zstds_ext_result_t ext_result;
57
+
58
+ ZSTD_inBuffer in_buffer;
59
+ in_buffer.src = source;
60
+ in_buffer.size = source_length;
61
+ in_buffer.pos = 0;
62
+
63
+ ZSTD_outBuffer out_buffer;
64
+ size_t destination_length = 0;
65
+ size_t remaining_destination_buffer_length = destination_buffer_length;
66
+
67
+ while (true) {
68
+ out_buffer.dst = (uint8_t*)RSTRING_PTR(destination_value) + destination_length;
69
+ out_buffer.size = remaining_destination_buffer_length;
70
+ out_buffer.pos = 0;
71
+
72
+ result = ZSTD_compressStream2(ctx, &out_buffer, &in_buffer, ZSTD_e_end);
73
+ if (ZSTD_isError(result)) {
74
+ return zstds_ext_get_error(ZSTD_getErrorCode(result));
75
+ }
76
+
77
+ destination_length += out_buffer.pos;
78
+ remaining_destination_buffer_length -= out_buffer.pos;
79
+
80
+ if (result != 0) {
81
+ ext_result = increase_destination_buffer(
82
+ destination_value, destination_length,
83
+ &remaining_destination_buffer_length, destination_buffer_length);
84
+
85
+ if (ext_result != 0) {
86
+ return ext_result;
87
+ }
88
+
89
+ continue;
90
+ }
91
+
92
+ break;
93
+ }
94
+
95
+ int exception;
96
+
97
+ ZSTDS_EXT_RESIZE_STRING_BUFFER(destination_value, destination_length, exception);
98
+ if (exception != 0) {
99
+ return ZSTDS_EXT_ERROR_ALLOCATE_FAILED;
100
+ }
101
+
102
+ return 0;
103
+ }
104
+
105
+ VALUE zstds_ext_compress_string(VALUE ZSTDS_EXT_UNUSED(self), VALUE source_value, VALUE options)
106
+ {
107
+ GET_SOURCE_DATA(source_value);
108
+ Check_Type(options, T_HASH);
109
+ ZSTDS_EXT_GET_COMPRESSOR_OPTIONS(options);
110
+ ZSTDS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
111
+
112
+ ZSTD_CCtx* ctx = ZSTD_createCCtx();
113
+ if (ctx == NULL) {
114
+ zstds_ext_raise_error(ZSTDS_EXT_ERROR_ALLOCATE_FAILED);
115
+ }
116
+
117
+ zstds_ext_result_t ext_result = zstds_ext_set_compressor_options(ctx, &compressor_options);
118
+ if (ext_result != 0) {
119
+ ZSTD_freeCCtx(ctx);
120
+ zstds_ext_raise_error(ext_result);
121
+ }
122
+
123
+ if (destination_buffer_length == 0) {
124
+ destination_buffer_length = ZSTD_CStreamOutSize();
125
+ }
126
+
127
+ int exception;
128
+
129
+ ZSTDS_EXT_CREATE_STRING_BUFFER(destination_value, destination_buffer_length, exception);
130
+ if (exception != 0) {
131
+ ZSTD_freeCCtx(ctx);
132
+ zstds_ext_raise_error(ZSTDS_EXT_ERROR_ALLOCATE_FAILED);
133
+ }
134
+
135
+ ext_result = compress(
136
+ ctx,
137
+ source, source_length,
138
+ destination_value, destination_buffer_length);
139
+
140
+ ZSTD_freeCCtx(ctx);
141
+
142
+ if (ext_result != 0) {
143
+ zstds_ext_raise_error(ext_result);
144
+ }
145
+
146
+ return destination_value;
147
+ }
148
+
149
+ // -- decompress --
150
+
151
+ static inline zstds_ext_result_t decompress(
152
+ ZSTD_DCtx* ctx,
153
+ const char* source, size_t source_length,
154
+ VALUE destination_value, size_t destination_buffer_length)
155
+ {
156
+ zstds_result_t result;
157
+ zstds_ext_result_t ext_result;
158
+
159
+ ZSTD_inBuffer in_buffer;
160
+ in_buffer.src = source;
161
+ in_buffer.size = source_length;
162
+ in_buffer.pos = 0;
163
+
164
+ ZSTD_outBuffer out_buffer;
165
+ size_t destination_length = 0;
166
+ size_t remaining_destination_buffer_length = destination_buffer_length;
167
+
168
+ while (true) {
169
+ out_buffer.dst = (uint8_t*)RSTRING_PTR(destination_value) + destination_length;
170
+ out_buffer.size = remaining_destination_buffer_length;
171
+ out_buffer.pos = 0;
172
+
173
+ result = ZSTD_decompressStream(ctx, &out_buffer, &in_buffer);
174
+ if (ZSTD_isError(result)) {
175
+ return zstds_ext_get_error(ZSTD_getErrorCode(result));
176
+ }
177
+
178
+ destination_length += out_buffer.pos;
179
+ remaining_destination_buffer_length -= out_buffer.pos;
180
+
181
+ if (remaining_destination_buffer_length == 0) {
182
+ ext_result = increase_destination_buffer(
183
+ destination_value, destination_length,
184
+ &remaining_destination_buffer_length, destination_buffer_length);
185
+
186
+ if (ext_result != 0) {
187
+ return ext_result;
188
+ }
189
+
190
+ continue;
191
+ }
192
+
193
+ break;
194
+ }
195
+
196
+ int exception;
197
+
198
+ ZSTDS_EXT_RESIZE_STRING_BUFFER(destination_value, destination_length, exception);
199
+ if (exception != 0) {
200
+ zstds_ext_raise_error(ZSTDS_EXT_ERROR_ALLOCATE_FAILED);
201
+ }
202
+
203
+ return 0;
204
+ }
205
+
206
+ VALUE zstds_ext_decompress_string(VALUE ZSTDS_EXT_UNUSED(self), VALUE source_value, VALUE options)
207
+ {
208
+ GET_SOURCE_DATA(source_value);
209
+ Check_Type(options, T_HASH);
210
+ ZSTDS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
211
+ ZSTDS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
212
+
213
+ ZSTD_DCtx* ctx = ZSTD_createDCtx();
214
+ if (ctx == NULL) {
215
+ zstds_ext_raise_error(ZSTDS_EXT_ERROR_ALLOCATE_FAILED);
216
+ }
217
+
218
+ zstds_ext_result_t ext_result = zstds_ext_set_decompressor_options(ctx, &decompressor_options);
219
+ if (ext_result != 0) {
220
+ ZSTD_freeDCtx(ctx);
221
+ zstds_ext_raise_error(ext_result);
222
+ }
223
+
224
+ if (destination_buffer_length == 0) {
225
+ destination_buffer_length = ZSTD_DStreamOutSize();
226
+ }
227
+
228
+ int exception;
229
+
230
+ ZSTDS_EXT_CREATE_STRING_BUFFER(destination_value, destination_buffer_length, exception);
231
+ if (exception != 0) {
232
+ ZSTD_freeDCtx(ctx);
233
+ zstds_ext_raise_error(ZSTDS_EXT_ERROR_ALLOCATE_FAILED);
234
+ }
235
+
236
+ ext_result = decompress(
237
+ ctx,
238
+ source, source_length,
239
+ destination_value, destination_buffer_length);
240
+
241
+ ZSTD_freeDCtx(ctx);
242
+
243
+ if (ext_result != 0) {
244
+ zstds_ext_raise_error(ext_result);
245
+ }
246
+
247
+ return destination_value;
248
+ }
249
+
250
+ void zstds_ext_string_exports(VALUE root_module)
251
+ {
252
+ rb_define_module_function(root_module, "_native_compress_string", RUBY_METHOD_FUNC(zstds_ext_compress_string), 2);
253
+ rb_define_module_function(root_module, "_native_decompress_string", RUBY_METHOD_FUNC(zstds_ext_decompress_string), 2);
254
+ }
@@ -0,0 +1,14 @@
1
+ // Ruby bindings for zstd library.
2
+ // Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ #if !defined(ZSTDS_EXT_STRING_H)
5
+ #define ZSTDS_EXT_STRING_H
6
+
7
+ #include "ruby.h"
8
+
9
+ VALUE zstds_ext_compress_string(VALUE self, VALUE source, VALUE options);
10
+ VALUE zstds_ext_decompress_string(VALUE self, VALUE source, VALUE options);
11
+
12
+ void zstds_ext_string_exports(VALUE root_module);
13
+
14
+ #endif // ZSTDS_EXT_STRING_H
data/lib/zstds.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Ruby bindings for zstd library.
2
+ # Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ require_relative "zstds/stream/reader"
5
+ require_relative "zstds/stream/writer"
6
+ require_relative "zstds/dictionary"
7
+ require_relative "zstds/file"
8
+ require_relative "zstds/string"
9
+ require_relative "zstds/version"
@@ -0,0 +1,47 @@
1
+ # Ruby bindings for zstd library.
2
+ # Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ require "zstds_ext"
5
+
6
+ require_relative "error"
7
+ require_relative "validation"
8
+
9
+ module ZSTDS
10
+ class Dictionary
11
+ TRAIN_DEFAULTS = {
12
+ :capacity => 0
13
+ }
14
+ .freeze
15
+
16
+ attr_reader :buffer
17
+
18
+ def initialize(buffer)
19
+ Validation.validate_string buffer
20
+ raise ValidateError, "dictionary buffer should not be empty" if buffer.empty?
21
+
22
+ @buffer = buffer
23
+ end
24
+
25
+ def id
26
+ self.class.get_buffer_id @buffer
27
+ end
28
+
29
+ def self.train(samples, options = {})
30
+ Validation.validate_array samples
31
+
32
+ samples.each do |sample|
33
+ Validation.validate_string sample
34
+ raise ValidateError, "dictionary sample should not be empty" if sample.empty?
35
+ end
36
+
37
+ Validation.validate_hash options
38
+
39
+ options = TRAIN_DEFAULTS.merge options
40
+
41
+ Validation.validate_not_negative_integer options[:capacity]
42
+
43
+ buffer = train_buffer samples, options
44
+ new buffer
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ # Ruby bindings for zstd library.
2
+ # Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ module ZSTDS
5
+ class BaseError < ::StandardError; end
6
+
7
+ class AllocateError < BaseError; end
8
+ class ValidateError < BaseError; end
9
+
10
+ class UsedAfterCloseError < BaseError; end
11
+ class NotEnoughSourceBufferError < BaseError; end
12
+ class NotEnoughDestinationBufferError < BaseError; end
13
+ class NotEnoughDestinationError < BaseError; end
14
+ class DecompressorCorruptedSourceError < BaseError; end
15
+ class CorruptedDictionaryError < BaseError; end
16
+
17
+ class AccessIOError < BaseError; end
18
+ class ReadIOError < BaseError; end
19
+ class WriteIOError < BaseError; end
20
+
21
+ class UnexpectedError < BaseError; end
22
+ end
data/lib/zstds/file.rb ADDED
@@ -0,0 +1,46 @@
1
+ # Ruby bindings for zstd library.
2
+ # Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ require "zstds_ext"
5
+
6
+ require_relative "error"
7
+ require_relative "option"
8
+ require_relative "validation"
9
+
10
+ module ZSTDS
11
+ module File
12
+ BUFFER_LENGTH_NAMES = %i[source_buffer_length destination_buffer_length].freeze
13
+
14
+ def self.compress(source, destination, options = {})
15
+ Validation.validate_string source
16
+ Validation.validate_string destination
17
+
18
+ options = Option.get_compressor_options options, BUFFER_LENGTH_NAMES
19
+
20
+ options[:pledged_size] = ::File.size source
21
+
22
+ open_files(source, destination) do |source_io, destination_io|
23
+ ZSTDS._native_compress_io source_io, destination_io, options
24
+ end
25
+ end
26
+
27
+ def self.decompress(source, destination, options = {})
28
+ Validation.validate_string source
29
+ Validation.validate_string destination
30
+
31
+ options = Option.get_decompressor_options options, BUFFER_LENGTH_NAMES
32
+
33
+ open_files(source, destination) do |source_io, destination_io|
34
+ ZSTDS._native_decompress_io source_io, destination_io, options
35
+ end
36
+ end
37
+
38
+ private_class_method def self.open_files(source, destination, &_block)
39
+ ::File.open source, "rb" do |source_io|
40
+ ::File.open destination, "wb" do |destination_io|
41
+ yield source_io, destination_io
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,194 @@
1
+ # Ruby bindings for zstd library.
2
+ # Copyright (c) 2019 AUTHORS, MIT License.
3
+
4
+ require "zstds_ext"
5
+
6
+ require_relative "dictionary"
7
+ require_relative "error"
8
+ require_relative "validation"
9
+
10
+ module ZSTDS
11
+ module Option
12
+ DEFAULT_BUFFER_LENGTH = 0
13
+
14
+ COMPRESSOR_DEFAULTS = {
15
+ :compression_level => nil,
16
+ :window_log => nil,
17
+ :hash_log => nil,
18
+ :chain_log => nil,
19
+ :search_log => nil,
20
+ :min_match => nil,
21
+ :target_length => nil,
22
+ :strategy => nil,
23
+ :enable_long_distance_matching => nil,
24
+ :ldm_hash_log => nil,
25
+ :ldm_min_match => nil,
26
+ :ldm_bucket_size_log => nil,
27
+ :ldm_hash_rate_log => nil,
28
+ :content_size_flag => nil,
29
+ :checksum_flag => nil,
30
+ :dict_id_flag => nil,
31
+ :nb_workers => nil,
32
+ :job_size => nil,
33
+ :overlap_log => nil,
34
+ :dictionary => nil
35
+ }
36
+ .freeze
37
+
38
+ DECOMPRESSOR_DEFAULTS = {
39
+ :window_log_max => nil,
40
+ :dictionary => nil
41
+ }
42
+ .freeze
43
+
44
+ def self.get_compressor_options(options, buffer_length_names)
45
+ Validation.validate_hash options
46
+
47
+ buffer_length_defaults = buffer_length_names.each_with_object({}) { |name, defaults| defaults[name] = DEFAULT_BUFFER_LENGTH }
48
+ options = COMPRESSOR_DEFAULTS.merge(buffer_length_defaults).merge options
49
+
50
+ buffer_length_names.each { |name| Validation.validate_not_negative_integer options[name] }
51
+
52
+ compression_level = options[:compression_level]
53
+ unless compression_level.nil?
54
+ Validation.validate_integer compression_level
55
+ raise ValidateError, "invalid compression level" if
56
+ compression_level < MIN_COMPRESSION_LEVEL || compression_level > MAX_COMPRESSION_LEVEL
57
+ end
58
+
59
+ window_log = options[:window_log]
60
+ unless window_log.nil?
61
+ Validation.validate_not_negative_integer window_log
62
+ raise ValidateError, "invalid window log" if
63
+ window_log < MIN_WINDOW_LOG || window_log > MAX_WINDOW_LOG
64
+ end
65
+
66
+ hash_log = options[:hash_log]
67
+ unless hash_log.nil?
68
+ Validation.validate_not_negative_integer hash_log
69
+ raise ValidateError, "invalid hash log" if
70
+ hash_log < MIN_HASH_LOG || hash_log > MAX_HASH_LOG
71
+ end
72
+
73
+ chain_log = options[:chain_log]
74
+ unless chain_log.nil?
75
+ Validation.validate_not_negative_integer chain_log
76
+ raise ValidateError, "invalid chain log" if
77
+ chain_log < MIN_CHAIN_LOG || chain_log > MAX_CHAIN_LOG
78
+ end
79
+
80
+ search_log = options[:search_log]
81
+ unless search_log.nil?
82
+ Validation.validate_not_negative_integer search_log
83
+ raise ValidateError, "invalid search log" if
84
+ search_log < MIN_SEARCH_LOG || search_log > MAX_SEARCH_LOG
85
+ end
86
+
87
+ min_match = options[:min_match]
88
+ unless min_match.nil?
89
+ Validation.validate_not_negative_integer min_match
90
+ raise ValidateError, "invalid min match" if
91
+ min_match < MIN_MIN_MATCH || min_match > MAX_MIN_MATCH
92
+ end
93
+
94
+ target_length = options[:target_length]
95
+ unless target_length.nil?
96
+ Validation.validate_not_negative_integer target_length
97
+ raise ValidateError, "invalid target length" if
98
+ target_length < MIN_TARGET_LENGTH || target_length > MAX_TARGET_LENGTH
99
+ end
100
+
101
+ strategy = options[:strategy]
102
+ unless strategy.nil?
103
+ Validation.validate_symbol strategy
104
+ raise ValidateError, "invalid strategy" unless STRATEGIES.include? strategy
105
+ end
106
+
107
+ enable_long_distance_matching = options[:enable_long_distance_matching]
108
+ Validation.validate_bool enable_long_distance_matching unless enable_long_distance_matching.nil?
109
+
110
+ ldm_hash_log = options[:ldm_hash_log]
111
+ unless ldm_hash_log.nil?
112
+ Validation.validate_not_negative_integer ldm_hash_log
113
+ raise ValidateError, "invalid ldm hash log" if
114
+ ldm_hash_log < MIN_LDM_HASH_LOG || ldm_hash_log > MAX_LDM_HASH_LOG
115
+ end
116
+
117
+ ldm_min_match = options[:ldm_min_match]
118
+ unless ldm_min_match.nil?
119
+ Validation.validate_not_negative_integer ldm_min_match
120
+ raise ValidateError, "invalid ldm min match" if
121
+ ldm_min_match < MIN_LDM_MIN_MATCH || ldm_min_match > MAX_LDM_MIN_MATCH
122
+ end
123
+
124
+ ldm_bucket_size_log = options[:ldm_bucket_size_log]
125
+ unless ldm_bucket_size_log.nil?
126
+ Validation.validate_not_negative_integer ldm_bucket_size_log
127
+ raise ValidateError, "invalid ldm bucket size log" if
128
+ ldm_bucket_size_log < MIN_LDM_BUCKET_SIZE_LOG || ldm_bucket_size_log > MAX_LDM_BUCKET_SIZE_LOG
129
+ end
130
+
131
+ ldm_hash_rate_log = options[:ldm_hash_rate_log]
132
+ unless ldm_hash_rate_log.nil?
133
+ Validation.validate_not_negative_integer ldm_hash_rate_log
134
+ raise ValidateError, "invalid ldm hash rate log" if
135
+ ldm_hash_rate_log < MIN_LDM_HASH_RATE_LOG || ldm_hash_rate_log > MAX_LDM_HASH_RATE_LOG
136
+ end
137
+
138
+ content_size_flag = options[:content_size_flag]
139
+ Validation.validate_bool content_size_flag unless content_size_flag.nil?
140
+
141
+ checksum_flag = options[:checksum_flag]
142
+ Validation.validate_bool checksum_flag unless checksum_flag.nil?
143
+
144
+ dict_id_flag = options[:dict_id_flag]
145
+ Validation.validate_bool dict_id_flag unless dict_id_flag.nil?
146
+
147
+ nb_workers = options[:nb_workers]
148
+ unless nb_workers.nil?
149
+ Validation.validate_not_negative_integer nb_workers
150
+ raise ValidateError, "invalid nb workers" if
151
+ nb_workers < MIN_NB_WORKERS || nb_workers > MAX_NB_WORKERS
152
+ end
153
+
154
+ job_size = options[:job_size]
155
+ unless job_size.nil?
156
+ Validation.validate_not_negative_integer job_size
157
+ raise ValidateError, "invalid job size" if
158
+ job_size < MIN_JOB_SIZE || job_size > MAX_JOB_SIZE
159
+ end
160
+
161
+ overlap_log = options[:overlap_log]
162
+ unless overlap_log.nil?
163
+ Validation.validate_not_negative_integer overlap_log
164
+ raise ValidateError, "invalid overlap log" if
165
+ overlap_log < MIN_OVERLAP_LOG || overlap_log > MAX_OVERLAP_LOG
166
+ end
167
+
168
+ dictionary = options[:dictionary]
169
+ unless dictionary.nil?
170
+ raise ValidateError, "invalid dictionary" unless dictionary.is_a? Dictionary
171
+ end
172
+
173
+ options
174
+ end
175
+
176
+ def self.get_decompressor_options(options, buffer_length_names)
177
+ Validation.validate_hash options
178
+
179
+ buffer_length_defaults = buffer_length_names.each_with_object({}) { |name, defaults| defaults[name] = DEFAULT_BUFFER_LENGTH }
180
+ options = DECOMPRESSOR_DEFAULTS.merge(buffer_length_defaults).merge options
181
+
182
+ buffer_length_names.each { |name| Validation.validate_not_negative_integer options[name] }
183
+
184
+ window_log_max = options[:window_log_max]
185
+ unless window_log_max.nil?
186
+ Validation.validate_not_negative_integer window_log_max
187
+ raise ValidateError, "invalid window log max" if
188
+ window_log_max < MIN_WINDOW_LOG_MAX || window_log_max > MAX_WINDOW_LOG_MAX
189
+ end
190
+
191
+ options
192
+ end
193
+ end
194
+ end