bzip2-ffi 1.0.0 → 1.1.1

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.
@@ -1,10 +1,13 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  require 'pathname'
2
5
  require 'stringio'
3
6
 
4
7
  module Bzip2
5
8
  module FFI
6
- # `Reader` reads and decompresses a bzip2 compressed stream or file. The
7
- # public instance methods of `Reader` are intended to be equivalent to those
9
+ # {Reader} reads and decompresses a bzip2 compressed stream or file. The
10
+ # public instance methods of {Reader} are intended to be equivalent to those
8
11
  # of a standard `IO` object.
9
12
  #
10
13
  # Data can be read as a stream using {open} and {#read}, for example:
@@ -15,7 +18,7 @@ module Bzip2
15
18
  # end
16
19
  # end
17
20
  #
18
- # Alternatively, without passing a block to `open`:
21
+ # Alternatively, without passing a block to {open}:
19
22
  #
20
23
  # reader = Bzip2::FFI::Reader.open(io_or_path)
21
24
  # begin
@@ -26,77 +29,93 @@ module Bzip2
26
29
  # reader.close
27
30
  # end
28
31
  #
29
- # An entire bzip2 structure can be read in a single step using {read}:
32
+ # All the available bzipped data can be read in a single step using {read}:
30
33
  #
31
34
  # uncompressed = Bzip2::FFI::Reader.read(io_or_path)
32
35
  #
33
- # The {open} and {read} methods accept either an `IO`-like object or a file
34
- # path. `IO`-like objects must have a `read` method. Paths can be given as
36
+ # The {open} and {read} methods accept either an IO-like object or a file
37
+ # path. IO-like objects must have a `#read` method. Paths can be given as
35
38
  # either a `String` or `Pathname`.
36
39
  #
37
40
  # No character conversion is performed on decompressed bytes. The {read} and
38
41
  # {#read} methods return instances of `String` that represent the raw
39
- # decompressed bytes, with `encoding` set to `Encoding::ASCII_8BIT` (also
42
+ # decompressed bytes, with `#encoding` set to `Encoding::ASCII_8BIT` (also
40
43
  # known as `Encoding::BINARY`).
41
44
  #
42
- # `Reader` will read a single bzip2 compressed structure from the given
43
- # stream or file. If the stream or file contains data beyond the end of
44
- # the bzip2 structure, such data may be read during decompression. If such
45
- # an overread has occurred and the `IO`-like object being read from has a
46
- # `seek` method, `Reader` will use it to reposition the stream to the byte
47
- # immediately following the end of the bzip2 structure. If `seek` raises
48
- # an `IOError`, it will be caught and the stream position will be left
49
- # unchanged.
45
+ # {Reader} will normally read all consecutive bzip2 compressed structure
46
+ # from the given stream or file (unless the `:first_only` parameter is
47
+ # specified - see {open}). If the stream or file contains additional data
48
+ # beyond the end of the compressed bzip2 data, it may be read during
49
+ # decompression. If such an overread has occurred and the IO-like object
50
+ # being read from has a `#seek` method, {Reader} will use it to reposition
51
+ # the stream to the byte immediately following the end of the compressed
52
+ # bzip2 data. If `#seek` raises an `IOError`, it will be caught and the
53
+ # stream position will be left unchanged.
54
+ #
55
+ # {Reader} does not support seeking (it's not supported by the underlying
56
+ # libbz2 library). There are no `#seek` or `#pos=` methods. The only way to
57
+ # advance the position is to call {#read}. Discard the result if it's not
58
+ # needed.
50
59
  class Reader < IO
51
60
  # The number of bytes read from the compressed data stream at a time.
52
61
  #
53
62
  # @private
54
63
  READ_BUFFER_SIZE = 4096 #:nodoc:
64
+ private_constant :READ_BUFFER_SIZE
55
65
 
56
66
  # The number of uncompressed bytes to read at a time when using {#read}
57
67
  # without a length.
58
68
  #
59
69
  # @private
60
70
  DEFAULT_DECOMPRESS_COUNT = 4096 #:nodoc:
71
+ private_constant :DEFAULT_DECOMPRESS_COUNT
61
72
 
62
73
  class << self
63
74
  # Use send to keep this hidden from YARD (visibility tag does not work).
64
75
  send(:public, :new)
65
76
 
66
- # Opens a {Reader} to read and decompress data from either an `IO`-like
67
- # object or a file. `IO`-like objects must have a `read` method. Files
77
+ # Opens a {Reader} to read and decompress data from either an IO-like
78
+ # object or a file. IO-like objects must have a `#read` method. Files
68
79
  # can be specified using either a `String` containing the file path or a
69
80
  # `Pathname`.
70
81
  #
71
- # If no block is given, the opened `Reader` instance is returned. After
82
+ # If no block is given, the opened {Reader} instance is returned. After
72
83
  # use, the instance should be closed using the {#close} method.
73
84
  #
74
- # If a block is given, it will be passed the opened `Reader` instance
75
- # as an argument. After the block terminates, the `Reader` instance will
76
- # automatically be closed. `open` will then return the result of the
85
+ # If a block is given, it will be passed the opened {Reader} instance
86
+ # as an argument. After the block terminates, the {Reader} instance will
87
+ # automatically be closed. {open} will then return the result of the
77
88
  # block.
78
89
  #
79
90
  # The following options can be specified using the `options` `Hash`:
80
91
  #
81
- # * `:autoclose` - When passing an `IO`-like object, set to `true` to
82
- # close the `IO` when the `Reader` instance is closed.
92
+ # * `:autoclose` - When passing an IO-like object, set to `true` to
93
+ # close it when the {Reader} instance is closed.
94
+ # * `:first_only` - Bzip2 files can contain multiple consecutive
95
+ # compressed strctures. Normally all the structures
96
+ # will be decompressed with the decompressed bytes
97
+ # concatenated. Set to `true` to only read the first
98
+ # structure.
83
99
  # * `:small` - Set to `true` to use an alternative decompression
84
100
  # algorithm that uses less memory, but at the cost of
85
101
  # decompressing more slowly (roughly 2,300 kB less memory
86
102
  # at about half the speed).
87
103
  #
88
- # If an `IO`-like object that has a `binmode` method is passed to
89
- # `open`, `binmode` will be called on `io_or_path` before yielding to
90
- # the block or returning.
104
+ # If an IO-like object that has a `#binmode` method is passed to {open},
105
+ # `#binmode` will be called on `io_or_path` before yielding to the block
106
+ # or returning.
91
107
  #
92
- # @param io_or_path [Object] Either an `IO`-like object with a `read`
108
+ # @param io_or_path [Object] Either an IO-like object with a `#read`
93
109
  # method or a file path as a `String` or
94
110
  # `Pathname`.
95
111
  # @param options [Hash] Optional parameters (`:autoclose` and `:small`).
96
- # @return [Object] The opened `Reader` instance if no block is given, or
112
+ # @yield [reader] If a block is given, it is yielded to.
113
+ # @yieldparam reader [Reader] The new {Reader} instance.
114
+ # @yieldresult [Object] A result to be returned as the result of {open}.
115
+ # @return [Object] The opened {Reader} instance if no block is given, or
97
116
  # the result of the block if a block is given.
98
117
  # @raise [ArgumentError] If `io_or_path` is _not_ a `String`, `Pathname`
99
- # or an `IO`-like object with a `read` method.
118
+ # or an IO-like object with a `#read` method.
100
119
  # @raise [Errno::ENOENT] If the specified file does not exist.
101
120
  # @raise [Error::Bzip2Error] If an error occurs when initializing
102
121
  # libbz2.
@@ -113,37 +132,42 @@ module Bzip2
113
132
  end
114
133
 
115
134
  # Reads and decompresses and entire bzip2 compressed structure from
116
- # either an `IO`-like object or a file and returns the decompressed
117
- # bytes as a `String`. `IO`-like objects must have a `read` method.
118
- # Files can be specified using either a `String` containing the file
119
- # path or a `Pathname`.
135
+ # either an IO-like object or a file and returns the decompressed bytes
136
+ # as a `String`. IO-like objects must have a `#read` method. Files can
137
+ # be specified using either a `String` containing the file path or a
138
+ # `Pathname`.
120
139
  #
121
140
  # The following options can be specified using the `options` `Hash`:
122
141
  #
123
- # * `:autoclose` - When passing an `IO`-like object, set to `true` to
124
- # close the `IO` when the compressed data has been
125
- # read.
142
+ # * `:autoclose` - When passing an IO-like object, set to `true` to
143
+ # close it when the compressed data has been read.
144
+ # * `:first_only` - Bzip2 files can contain multiple consecutive
145
+ # compressed strctures. Normally all the structures
146
+ # will be decompressed with the decompressed bytes
147
+ # concatenated. Set to `true` to only read the first
148
+ # structure.
126
149
  # * `:small` - Set to `true` to use an alternative decompression
127
150
  # algorithm that uses less memory, but at the cost of
128
151
  # decompressing more slowly (roughly 2,300 kB less memory
129
152
  # at about half the speed).
130
153
  #
131
- # No character conversion is performed on decompressed bytes. `read`
154
+ # No character conversion is performed on decompressed bytes. {read}
132
155
  # returns a `String` that represents the raw decompressed bytes, with
133
156
  # `encoding` set to `Encoding::ASCII_8BIT` (also known as
134
157
  # `Encoding::BINARY`).
135
158
  #
136
- # If an `IO`-like object that has a `binmode` method is passed to
137
- # `read`, `binmode` will be called on `io_or_path` before any compressed
138
- # data is read.
159
+ # If an IO-like object that has a `#inmode` method is passed to {read},
160
+ # `#binmode` will be called on `io_or_path` before any compressed data
161
+ # is read.
139
162
  #
140
- # @param io_or_path [Object] Either an `IO`-like object with a `read`
163
+ # @param io_or_path [Object] Either an IO-like object with a `#read`
141
164
  # method or a file path as a `String` or
142
165
  # `Pathname`.
143
- # @param options [Hash] Optional parameters (`:autoclose` and `:small`).
166
+ # @param options [Hash] Optional parameters (`:autoclose`, `:first_only`
167
+ # and `:small`).
144
168
  # @return [String] The decompressed data.
145
169
  # @raise [ArgumentError] If `io_or_path` is _not_ a `String`, `Pathname`
146
- # or an `IO`-like object with a `read` method.
170
+ # or an IO-like object with a `#read` method.
147
171
  # @raise [Errno::ENOENT] If the specified file does not exist.
148
172
  # @raise [Error::Bzip2Error] If an error occurs when initializing
149
173
  # libbz2 or decompressing data.
@@ -155,11 +179,11 @@ module Bzip2
155
179
 
156
180
  private
157
181
 
158
- # Returns a Proc that can be used as a finalizer to call
159
- # `BZ2_bzDecompressEnd` with the given `stream`.
182
+ # Returns a `Proc` that can be used as a finalizer to call
183
+ # {Libbz2::BZ2_bzDecompressEnd} with the given `stream`.
160
184
  #
161
185
  # @param stream [Libbz2::BzStream] The stream that should be passed to
162
- # `BZ2_bzDecompressEnd`.
186
+ # {Libbz2::BZ2_bzDecompressEnd}.
163
187
  def finalize(stream)
164
188
  ->(id) do
165
189
  Libbz2::BZ2_bzDecompressEnd(stream)
@@ -167,65 +191,74 @@ module Bzip2
167
191
  end
168
192
  end
169
193
 
170
- # Initializes a {Reader} to read compressed data from an `IO`-like object
171
- # (`io`). `io` must have a `read` method.
194
+ # Initializes a {Reader} to read compressed data from an IO-like object
195
+ # (`io`). `io` must have a `#read` method.
172
196
  #
173
197
  # The following options can be specified using the `options` `Hash`:
174
198
  #
175
- # * `:autoclose` - Set to `true` to close `io` when the `Reader` instance
199
+ # * `:autoclose` - Set to `true` to close `io` when the {Reader} instance
176
200
  # is closed.
201
+ # * `:first_only` - Bzip2 files can contain multiple consecutive
202
+ # compressed strctures. Normally all the structures will
203
+ # be decompressed with the decompressed bytes
204
+ # concatenated. Set to `true` to only read the first
205
+ # structure.
177
206
  # * `:small` - Set to `true` to use an alternative decompression
178
207
  # algorithm that uses less memory, but at the cost of
179
208
  # decompressing more slowly (roughly 2,300 kB less memory
180
209
  # at about half the speed).
181
210
  #
182
- # `binmode` is called on `io` if `io` responds to `binmode`.
211
+ # `#binmode` is called on `io` if `io` responds to `#binmode`.
183
212
  #
184
- # After use, the `Reader` instance should be closed using the {#close}
213
+ # After use, the {Reader} instance should be closed using the {#close}
185
214
  # method.
186
215
  #
187
- # @param io [Object] An `IO`-like object with a `read` method.
188
- # @param options [Hash] Optional parameters (`:autoclose` and `:small`).
189
- # @raise [ArgumentError] If `io` is `nil` or does not respond to `read`.
216
+ # @param io [Object] An IO-like object with a `#read` method.
217
+ # @param options [Hash] Optional parameters (`:autoclose`, `:first_only`
218
+ # and `:small`).
219
+ # @raise [ArgumentError] If `io` is `nil` or does not respond to `#read`.
190
220
  # @raise [Error::Bzip2Error] If an error occurs when initializing libbz2.
191
221
  def initialize(io, options = {})
192
222
  super
193
223
  raise ArgumentError, 'io must respond to read' unless io.respond_to?(:read)
194
224
 
195
- small = options[:small]
225
+ @first_only = options[:first_only]
226
+ @small = options[:small] ? 1 : 0
196
227
 
197
228
  @in_eof = false
198
229
  @out_eof = false
199
230
  @in_buffer = nil
231
+ @structure_number = 1
232
+ @structure_start_pos = 0
233
+ @in_pos = 0
234
+ @out_pos = 0
200
235
 
201
- check_error(Libbz2::BZ2_bzDecompressInit(stream, 0, small ? 1 : 0))
202
-
203
- ObjectSpace.define_finalizer(self, self.class.send(:finalize, stream))
236
+ decompress_init(stream)
204
237
  end
205
238
 
206
239
  # Ends decompression and closes the {Reader}.
207
240
  #
208
241
  # If the {open} method is used with a block, it is not necessary to call
209
- # `close`. Otherwise, `close` should be called once the `Reader` is no
242
+ # {#close}. Otherwise, {#close} should be called once the {Reader} is no
210
243
  # longer needed.
211
244
  #
212
245
  # @return [NilType] `nil`.
213
- # @raise [IOError] If the `Reader` has already been closed.
246
+ # @raise [IOError] If the {Reader} has already been closed.
214
247
  def close
215
248
  s = stream
216
249
 
217
250
  unless @out_eof
218
251
  decompress_end(s)
219
252
  end
220
-
253
+
221
254
  s[:next_in] = nil
222
255
  s[:next_out] = nil
223
-
256
+
224
257
  if @in_buffer
225
258
  @in_buffer.free
226
259
  @in_buffer = nil
227
260
  end
228
-
261
+
229
262
  super
230
263
  end
231
264
 
@@ -240,17 +273,17 @@ module Bzip2
240
273
  # A result of `nil` or a `String` with a length less than `length` bytes
241
274
  # indicates that the end of the decompressed data has been reached.
242
275
  #
243
- # If `length` is `nil`, `read` reads until the end of the decompressed
276
+ # If `length` is `nil`, {#read} reads until the end of the decompressed
244
277
  # data, returning the uncompressed bytes as a `String`.
245
278
  #
246
- # If `length` is 0, `read` returns an empty `String`.
279
+ # If `length` is 0, {#read} returns an empty `String`.
247
280
  #
248
281
  # If the optional `buffer` argument is present, it must reference a
249
282
  # `String` that will receive the decompressed data. `buffer` will
250
- # contain only the decompressed data after the call to `read`, even if it
283
+ # contain only the decompressed data after the call to {#read}, even if it
251
284
  # is not empty beforehand.
252
285
  #
253
- # No character conversion is performed on decompressed bytes. `read`
286
+ # No character conversion is performed on decompressed bytes. {#read}
254
287
  # returns a `String` that represents the raw decompressed bytes, with
255
288
  # `encoding` set to `Encoding::ASCII_8BIT` (also known as
256
289
  # `Encoding::BINARY`).
@@ -267,7 +300,7 @@ module Bzip2
267
300
  # the end of the decompressed data has been reached.
268
301
  # @raise [ArgumentError] If `length` is negative.
269
302
  # @raise [Error::Bzip2Error] If an error occurs during decompression.
270
- # @raise [IOError] If the `Reader` has been closed.
303
+ # @raise [IOError] If the {Reader} has been closed.
271
304
  def read(length = nil, buffer = nil)
272
305
  if buffer
273
306
  buffer.clear
@@ -279,11 +312,11 @@ module Bzip2
279
312
 
280
313
  if length == 0
281
314
  check_closed
282
- return buffer || ''
315
+ return buffer || String.new
283
316
  end
284
317
 
285
318
  decompressed = decompress(length)
286
-
319
+
287
320
  return nil unless decompressed
288
321
  buffer ? buffer << decompressed : decompressed
289
322
  else
@@ -292,11 +325,11 @@ module Bzip2
292
325
  # StringIO#binmode is a no-op, but call in case it is implemented in
293
326
  # future versions.
294
327
  result.binmode
295
-
328
+
296
329
  result.set_encoding(Encoding::ASCII_8BIT)
297
330
 
298
331
  loop do
299
- decompressed = decompress(DEFAULT_DECOMPRESS_COUNT)
332
+ decompressed = decompress(DEFAULT_DECOMPRESS_COUNT)
300
333
  break unless decompressed
301
334
  result.write(decompressed)
302
335
  break if decompressed.bytesize < DEFAULT_DECOMPRESS_COUNT
@@ -306,6 +339,30 @@ module Bzip2
306
339
  end
307
340
  end
308
341
 
342
+ # Returns `true` if decompression has completed, otherwise `false`.
343
+ #
344
+ # Note that it is possible for `false` to be returned after all the
345
+ # decompressed data has been read. In such cases, the next call to {#read}
346
+ # will detect the end of the bzip2 structure and set {#eof?} to `true`.
347
+ #
348
+ # @return [Boolean] If decompression has completed, otherwise `false`.
349
+ # @raise [IOError] If the {Reader} has been closed.
350
+ def eof?
351
+ check_closed
352
+ @out_eof
353
+ end
354
+ alias eof eof?
355
+
356
+ # Returns the number of decompressed bytes that have been read.
357
+ #
358
+ # @return [Integer] The number of decompressed bytes that have been read.
359
+ # @raise [IOError] If the {Reader} has been closed.
360
+ def tell
361
+ check_closed
362
+ @out_pos
363
+ end
364
+ alias pos tell
365
+
309
366
  private
310
367
 
311
368
  # Attempts to decompress and return `count` bytes.
@@ -315,9 +372,9 @@ module Bzip2
315
372
  # @return [String] The decompressed data as a `String` with ASCII-8BIT
316
373
  # encoding, or `nil` if length was a positive integer and
317
374
  # the end of the decompressed data has been reached.
318
- # @raise [ArgumentError] if `count` is not greater than or equal to 1.
375
+ # @raise [ArgumentError] If `count` is not greater than or equal to 1.
319
376
  # @raise [Error::Bzip2Error] If an error occurs during decompression.
320
- # @raise [IOError] If the `Reader` has been closed.
377
+ # @raise [IOError] If the {Reader} has been closed.
321
378
  def decompress(count)
322
379
  raise ArgumentError, "count must be a positive integer" unless count >= 1
323
380
  s = stream
@@ -335,6 +392,7 @@ module Bzip2
335
392
  bytes = io.read(READ_BUFFER_SIZE)
336
393
 
337
394
  if bytes && bytes.bytesize > 0
395
+ @in_pos += bytes.bytesize
338
396
  @in_eof = bytes.bytesize < READ_BUFFER_SIZE
339
397
  @in_buffer = ::FFI::MemoryPointer.new(1, bytes.bytesize)
340
398
  @in_buffer.write_bytes(bytes)
@@ -345,8 +403,15 @@ module Bzip2
345
403
  end
346
404
  end
347
405
 
406
+ # Reached the end of input without reading anything in the current
407
+ # bzip2 structure. No more data to process.
408
+ if @in_pos == @structure_start_pos
409
+ @out_eof = true
410
+ break
411
+ end
412
+
348
413
  prev_avail_out = s[:avail_out]
349
-
414
+
350
415
  res = Libbz2::BZ2_bzDecompress(s)
351
416
 
352
417
  if s[:avail_in] == 0 && @in_buffer
@@ -355,43 +420,51 @@ module Bzip2
355
420
  @in_buffer = nil
356
421
  end
357
422
 
358
- check_error(res)
359
-
360
- if res == Libbz2::BZ_STREAM_END
361
- # The input could contain data after the end of the bzip2 stream.
362
- #
363
- # s[:avail_in] will contain the number of bytes that have been
364
- # read from io, but not been consumed by BZ2_bzDecompress.
423
+ if @structure_number > 1 && res == Libbz2::BZ_DATA_ERROR_MAGIC
424
+ # Found something other than the bzip2 magic bytes after the end
425
+ # of a bzip2 structure.
365
426
  #
366
427
  # Attempt to move the input stream back by the amount that has
367
428
  # been over-read.
368
- if s[:avail_in] > 0 && io.respond_to?(:seek)
369
- io.seek(-s[:avail_in], ::IO::SEEK_CUR) rescue IOError
370
- end
371
-
372
- if @in_buffer
373
- s[:next_in] = nil
374
- @in_buffer.free
375
- @in_buffer = nil
376
- end
377
-
429
+ attempt_seek_to_structure_start
378
430
  decompress_end(s)
379
-
380
431
  @out_eof = true
381
432
  break
382
433
  end
383
434
 
384
- break if s[:avail_out] == 0
435
+ check_error(res)
385
436
 
386
- # No more input available and calling BZ2_bzDecompress didn't
387
- # advance the output. Raise an error.
388
- if @in_eof && prev_avail_out == s[:avail_out]
389
- raise Error::UnexpectedEofError.new
437
+ if res == Libbz2::BZ_STREAM_END
438
+ decompress_end(s)
439
+
440
+ if (s[:avail_in] > 0 || !@in_eof) && !@first_only
441
+ # Re-initialize to read a second bzip2 structure if there is
442
+ # still input available and not restricting to the first stream.
443
+ @structure_number += 1
444
+ @structure_start_pos = @in_pos - s[:avail_in]
445
+ decompress_init(s)
446
+ else
447
+ # May have already read data after the end of the first bzip2
448
+ # structure.
449
+ attempt_seek_to_structure_start if @first_only
450
+ @out_eof = true
451
+ break
452
+ end
453
+ else
454
+ # No more input available and calling BZ2_bzDecompress didn't
455
+ # advance the output. Raise an error.
456
+ if @in_eof && s[:avail_in] == 0 && prev_avail_out == s[:avail_out]
457
+ decompress_end(s)
458
+ @out_eof = true
459
+ raise Error::UnexpectedEofError.new
460
+ end
390
461
  end
462
+
463
+ break if s[:avail_out] == 0
391
464
  end
392
465
 
393
466
  result = out_buffer.read_bytes(out_buffer.size - s[:avail_out])
394
- ensure
467
+ ensure
395
468
  out_buffer.free
396
469
  s[:next_out] = nil
397
470
  s[:avail_out] = 0
@@ -400,18 +473,51 @@ module Bzip2
400
473
  if @out_eof && result.bytesize == 0
401
474
  nil
402
475
  else
476
+ @out_pos += result.bytesize
403
477
  result
404
- end
478
+ end
479
+ end
480
+
481
+ # Attempts to reposition the compressed stream to the start of the current
482
+ # structure. Used when {Libbz2::BZ2_bzDecompress} has read beyond the end
483
+ # of a bzip2 structure.
484
+ def attempt_seek_to_structure_start
485
+ if io.respond_to?(:seek)
486
+ diff = @structure_start_pos - @in_pos
487
+ if diff < 0
488
+ begin
489
+ io.seek(diff, ::IO::SEEK_CUR)
490
+ @in_pos += diff
491
+ rescue IOError
492
+ end
493
+ end
494
+ end
495
+ end
496
+
497
+ # Calls {Libbz2::BZ2_bzDecompressInit} to initialize the decompression
498
+ # stream `s`.
499
+ #
500
+ # Defines a finalizer to ensure that the memory associated with the stream
501
+ # is deallocated.
502
+ #
503
+ # @param s [Libbz2::BzStream] The stream to initialize decompression for.
504
+ # @raise [Error::Bzip2Error] If {Libbz2::BZ2_bzDecompressInit} reports an
505
+ # error.
506
+ def decompress_init(s)
507
+ check_error(Libbz2::BZ2_bzDecompressInit(s, 0, @small))
508
+
509
+ ObjectSpace.define_finalizer(self, self.class.send(:finalize, s))
405
510
  end
406
511
 
407
- # Calls BZ2_bzDecompressEnd to release memeory associated with the
408
- # decompression stream `s`.
512
+ # Calls {Libbz2::BZ2_bzDecompressEnd} to release memory associated with
513
+ # the decompression stream `s`.
409
514
  #
410
515
  # Notifies `ObjectSpace` that it is no longer necessary to finalize the
411
- # `Reader` instance.
516
+ # {Reader} instance.
412
517
  #
413
518
  # @param s [Libbz2::BzStream] The stream to end decompression for.
414
- # @raise [Error::Bzip2Error] If `BZ2_bzDecompressEnd` reports an error.
519
+ # @raise [Error::Bzip2Error] If {Libbz2::BZ2_bzDecompressEnd} reports an
520
+ # error.
415
521
  def decompress_end(s)
416
522
  res = Libbz2::BZ2_bzDecompressEnd(s)
417
523
  ObjectSpace.undefine_finalizer(self)
@@ -1,6 +1,9 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  module Bzip2
2
5
  module FFI
3
6
  # The Bzip2::FFI version number.
4
- VERSION = '1.0.0'
7
+ VERSION = '1.1.1'
5
8
  end
6
9
  end