ruby-lzws 1.1.0 → 1.1.5

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.
@@ -20,6 +20,8 @@ module LZWS
20
20
  open_files(source, destination) do |source_io, destination_io|
21
21
  LZWS._native_compress_io source_io, destination_io, options
22
22
  end
23
+
24
+ nil
23
25
  end
24
26
 
25
27
  def self.decompress(source, destination, options = {})
@@ -31,6 +33,8 @@ module LZWS
31
33
  open_files(source, destination) do |source_io, destination_io|
32
34
  LZWS._native_decompress_io source_io, destination_io, options
33
35
  end
36
+
37
+ nil
34
38
  end
35
39
 
36
40
  private_class_method def self.open_files(source, destination, &_block)
@@ -1,6 +1,8 @@
1
1
  # Ruby bindings for lzws library.
2
2
  # Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
+ require "lzws_ext"
5
+
4
6
  require_relative "error"
5
7
  require_relative "validation"
6
8
 
@@ -38,8 +40,7 @@ module LZWS
38
40
  Validation.validate_positive_integer max_code_bit_length
39
41
 
40
42
  raise ValidateError, "invalid max code bit length" if
41
- max_code_bit_length < LOWEST_MAX_CODE_BIT_LENGTH ||
42
- max_code_bit_length > BIGGEST_MAX_CODE_BIT_LENGTH
43
+ max_code_bit_length < LOWEST_MAX_CODE_BIT_LENGTH || max_code_bit_length > BIGGEST_MAX_CODE_BIT_LENGTH
43
44
 
44
45
  Validation.validate_bool options[:without_magic_header]
45
46
  Validation.validate_bool options[:block_mode]
@@ -17,23 +17,19 @@ module LZWS
17
17
 
18
18
  include Delegates
19
19
 
20
- attr_reader :io
21
- attr_reader :stat
22
- attr_reader :external_encoding
23
- attr_reader :internal_encoding
24
- attr_reader :transcode_options
25
- attr_reader :pos
20
+ attr_reader :io, :stat, :external_encoding, :internal_encoding, :transcode_options, :pos
21
+
26
22
  alias tell pos
27
23
 
28
- def initialize(io, external_encoding: nil, internal_encoding: nil, transcode_options: {})
24
+ def initialize(io, options = {})
29
25
  @raw_stream = create_raw_stream
30
26
 
31
27
  Validation.validate_io io
32
28
  @io = io
33
29
 
34
- @stat = Stat.new @io.stat
30
+ @stat = Stat.new @io.stat if @io.respond_to? :stat
35
31
 
36
- set_encoding external_encoding, internal_encoding, transcode_options
32
+ set_encoding options[:external_encoding], options[:internal_encoding], options[:transcode_options]
37
33
  reset_buffer
38
34
  reset_io_advise
39
35
 
@@ -50,8 +46,8 @@ module LZWS
50
46
 
51
47
  protected def reset_io_advise
52
48
  # Both compressor and decompressor need sequential io access.
53
- @io.advise :sequential
54
- rescue ::Errno::ESPIPE # rubocop:disable Lint/HandleExceptions
49
+ @io.advise :sequential if @io.respond_to? :advise
50
+ rescue ::Errno::ESPIPE
55
51
  # ok
56
52
  end
57
53
 
@@ -126,7 +122,8 @@ module LZWS
126
122
  def rewind
127
123
  @raw_stream = create_raw_stream
128
124
 
129
- @io.rewind
125
+ @io.rewind if @io.respond_to? :rewind
126
+
130
127
  reset_buffer
131
128
  reset_io_advise
132
129
 
@@ -27,9 +27,9 @@ module LZWS
27
27
  nil
28
28
  end
29
29
 
30
- protected def flush_destination_buffer(&writer)
30
+ protected def more_destination(&writer)
31
31
  result_bytesize = write_result(&writer)
32
- raise NotEnoughDestinationError, "not enough destination" if result_bytesize == 0
32
+ raise NotEnoughDestinationError, "not enough destination" if result_bytesize.zero?
33
33
  end
34
34
 
35
35
  protected def write_result(&_writer)
@@ -50,6 +50,8 @@ module LZWS
50
50
 
51
51
  @native_stream.close
52
52
  @is_closed = true
53
+
54
+ nil
53
55
  end
54
56
 
55
57
  def closed?
@@ -35,13 +35,15 @@ module LZWS
35
35
 
36
36
  if need_more_destination
37
37
  source = source.byteslice bytes_written, source.bytesize - bytes_written
38
- flush_destination_buffer(&writer)
38
+ more_destination(&writer)
39
39
  next
40
40
  end
41
41
 
42
42
  unless bytes_written == source.bytesize
43
+ # :nocov:
43
44
  # Compressor write should eat all provided "source" without remainder.
44
45
  raise UnexpectedError, "unexpected error"
46
+ # :nocov:
45
47
  end
46
48
 
47
49
  break
@@ -59,7 +61,7 @@ module LZWS
59
61
  need_more_destination = @native_stream.finish
60
62
 
61
63
  if need_more_destination
62
- flush_destination_buffer(&writer)
64
+ more_destination(&writer)
63
65
  next
64
66
  end
65
67
 
@@ -67,8 +69,6 @@ module LZWS
67
69
  end
68
70
 
69
71
  super
70
-
71
- nil
72
72
  end
73
73
  end
74
74
  end
@@ -34,7 +34,7 @@ module LZWS
34
34
 
35
35
  if need_more_destination
36
36
  source = source.byteslice bytes_read, source.bytesize - bytes_read
37
- flush_destination_buffer(&writer)
37
+ more_destination(&writer)
38
38
  next
39
39
  end
40
40
 
@@ -51,8 +51,6 @@ module LZWS
51
51
  Validation.validate_proc writer
52
52
 
53
53
  super
54
-
55
- nil
56
54
  end
57
55
  end
58
56
  end
@@ -20,79 +20,60 @@ module LZWS
20
20
 
21
21
  initialize_source_buffer_length
22
22
  reset_io_remainder
23
+ reset_need_to_flush
23
24
 
24
25
  @lineno = 0
25
26
  end
26
27
 
28
+ protected def create_raw_stream
29
+ Raw::Decompressor.new @options
30
+ end
31
+
27
32
  protected def initialize_source_buffer_length
28
33
  source_buffer_length = @options[:source_buffer_length]
29
34
  Validation.validate_not_negative_integer source_buffer_length unless source_buffer_length.nil?
30
35
 
31
36
  source_buffer_length = Buffer::DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR \
32
- if source_buffer_length == 0 || source_buffer_length.nil?
37
+ if source_buffer_length.nil? || source_buffer_length.zero?
33
38
 
34
39
  @source_buffer_length = source_buffer_length
35
40
  end
36
41
 
37
- protected def create_raw_stream
38
- Raw::Decompressor.new @options
39
- end
40
-
41
42
  protected def reset_io_remainder
42
43
  @io_remainder = ::String.new :encoding => ::Encoding::BINARY
43
44
  end
44
45
 
46
+ protected def reset_need_to_flush
47
+ @need_to_flush = false
48
+ end
49
+
45
50
  # -- synchronous --
46
51
 
47
52
  def read(bytes_to_read = nil, out_buffer = nil)
48
53
  Validation.validate_not_negative_integer bytes_to_read unless bytes_to_read.nil?
49
54
  Validation.validate_string out_buffer unless out_buffer.nil?
50
55
 
51
- return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read == 0
52
-
53
56
  unless bytes_to_read.nil?
57
+ return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
54
58
  return nil if eof?
55
59
 
56
- read_more_from_buffer until @buffer.bytesize >= bytes_to_read || @io.eof?
60
+ append_io_data @io.read(@source_buffer_length) while @buffer.bytesize < bytes_to_read && !@io.eof?
61
+ flush_io_data if @buffer.bytesize < bytes_to_read
57
62
 
58
63
  return read_bytes_from_buffer bytes_to_read, out_buffer
59
64
  end
60
65
 
61
- read_more_from_buffer until @io.eof?
62
-
63
- result = @buffer
64
- reset_buffer
65
- @pos += result.bytesize
66
+ append_io_data @io.read(@source_buffer_length) until @io.eof?
67
+ flush_io_data
66
68
 
67
- result.force_encoding @external_encoding unless @external_encoding.nil?
68
- result = transcode_to_internal result
69
- result = out_buffer.replace result unless out_buffer.nil?
70
-
71
- result
72
- end
73
-
74
- protected def read_more_from_buffer
75
- io_data = @io.read @source_buffer_length
76
- append_io_data_to_buffer io_data
77
- end
78
-
79
- def readpartial(bytes_to_read = nil, out_buffer = nil)
80
- raise ::EOFError if eof?
81
-
82
- readpartial_from_buffer until @buffer.bytesize >= bytes_to_read || @io.eof?
83
-
84
- read_bytes_from_buffer bytes_to_read, out_buffer
85
- end
86
-
87
- protected def readpartial_from_buffer
88
- io_data = @io.readpartial @source_buffer_length
89
- append_io_data_to_buffer io_data
69
+ read_buffer out_buffer
90
70
  end
91
71
 
92
72
  def rewind
93
73
  raw_wrapper :close
94
74
 
95
75
  reset_io_remainder
76
+ reset_need_to_flush
96
77
 
97
78
  super
98
79
  end
@@ -103,25 +84,61 @@ module LZWS
103
84
  super
104
85
  end
105
86
 
87
+ def eof?
88
+ empty? && @io.eof?
89
+ end
90
+
106
91
  # -- asynchronous --
107
92
 
93
+ def readpartial(bytes_to_read, out_buffer = nil)
94
+ read_more_nonblock(bytes_to_read, out_buffer) { @io.readpartial @source_buffer_length }
95
+ end
96
+
108
97
  def read_nonblock(bytes_to_read, out_buffer = nil, *options)
109
- raise ::EOFError if eof?
98
+ read_more_nonblock(bytes_to_read, out_buffer) { @io.read_nonblock(@source_buffer_length, *options) }
99
+ end
100
+
101
+ protected def read_more_nonblock(bytes_to_read, out_buffer, &_block)
102
+ Validation.validate_not_negative_integer bytes_to_read
103
+ Validation.validate_string out_buffer unless out_buffer.nil?
104
+
105
+ return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
106
+
107
+ io_provided_eof_error = false
110
108
 
111
- read_more_from_buffer_nonblock(*options) until @buffer.bytesize >= bytes_to_read || @io.eof?
109
+ if @buffer.bytesize < bytes_to_read
110
+ begin
111
+ append_io_data yield
112
+ rescue ::EOFError
113
+ io_provided_eof_error = true
114
+ end
115
+ end
116
+
117
+ flush_io_data if @buffer.bytesize < bytes_to_read
118
+ raise ::EOFError if empty? && io_provided_eof_error
112
119
 
113
120
  read_bytes_from_buffer bytes_to_read, out_buffer
114
121
  end
115
122
 
116
- protected def read_more_from_buffer_nonblock(*options)
117
- io_data = @io.read_nonblock @source_buffer_length, *options
118
- append_io_data_to_buffer io_data
123
+ # -- common --
124
+
125
+ protected def append_io_data(io_data)
126
+ io_portion = @io_remainder + io_data
127
+ bytes_read = raw_wrapper :read, io_portion
128
+ @io_remainder = io_portion.byteslice bytes_read, io_portion.bytesize - bytes_read
129
+
130
+ # Even empty io data may require flush.
131
+ @need_to_flush = true
119
132
  end
120
133
 
121
- # -- common --
134
+ protected def flush_io_data
135
+ raw_wrapper :flush
122
136
 
123
- def eof?
124
- @io.eof? && @buffer.bytesize == 0
137
+ @need_to_flush = false
138
+ end
139
+
140
+ protected def empty?
141
+ !@need_to_flush && @buffer.bytesize.zero?
125
142
  end
126
143
 
127
144
  protected def read_bytes_from_buffer(bytes_to_read, out_buffer)
@@ -136,18 +153,20 @@ module LZWS
136
153
  result
137
154
  end
138
155
 
139
- protected def append_io_data_to_buffer(io_data)
140
- io_portion = @io_remainder + io_data
141
- bytes_read = raw_wrapper :read, io_portion
142
- @io_remainder = io_portion.byteslice bytes_read, io_portion.bytesize - bytes_read
156
+ protected def read_buffer(out_buffer)
157
+ result = @buffer
158
+ reset_buffer
159
+ @pos += result.bytesize
143
160
 
144
- # We should just ignore case when "io.eof?" appears but "io_remainder" is not empty.
145
- # Ancient compress implementations can write bytes from not initialized buffer parts to output.
146
- raw_wrapper :flush if @io.eof?
161
+ result.force_encoding @external_encoding unless @external_encoding.nil?
162
+ result = transcode_to_internal result
163
+
164
+ result = out_buffer.replace result unless out_buffer.nil?
165
+ result
147
166
  end
148
167
 
149
168
  protected def transcode_to_internal(data)
150
- data = data.encode @internal_encoding, @transcode_options unless @internal_encoding.nil?
169
+ data = data.encode @internal_encoding, **@transcode_options unless @internal_encoding.nil?
151
170
  data
152
171
  end
153
172
 
@@ -1,6 +1,8 @@
1
1
  # Ruby bindings for lzws library.
2
2
  # Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
+ require "English"
5
+
4
6
  require_relative "../validation"
5
7
 
6
8
  module LZWS
@@ -64,7 +64,7 @@ module LZWS
64
64
  end
65
65
 
66
66
  protected def write_remaining_buffer
67
- return nil if @buffer.bytesize == 0
67
+ return nil if @buffer.bytesize.zero?
68
68
 
69
69
  @io.write @buffer
70
70
 
@@ -77,6 +77,11 @@ module LZWS
77
77
 
78
78
  # -- asynchronous --
79
79
 
80
+ # IO write nonblock can raise wait writable error.
81
+ # After resolving this error user may provide same content again.
82
+ # It is not possible to revert accepted content after error.
83
+ # So we have to accept content after processing IO write nonblock.
84
+ # It means that first write nonblock won't call IO write nonblock.
80
85
  def write_nonblock(object, *options)
81
86
  return 0 unless write_remaining_buffer_nonblock(*options)
82
87
 
@@ -120,14 +125,14 @@ module LZWS
120
125
  end
121
126
 
122
127
  protected def write_remaining_buffer_nonblock(*options)
123
- return true if @buffer.bytesize == 0
128
+ return true if @buffer.bytesize.zero?
124
129
 
125
130
  bytes_written = @io.write_nonblock @buffer, *options
126
- return false if bytes_written == 0
131
+ return false if bytes_written.zero?
127
132
 
128
133
  @buffer = @buffer.byteslice bytes_written, @buffer.bytesize - bytes_written
129
134
 
130
- @buffer.bytesize == 0
135
+ @buffer.bytesize.zero?
131
136
  end
132
137
 
133
138
  protected def raw_nonblock_wrapper(method_name, *args)
@@ -137,7 +142,7 @@ module LZWS
137
142
  # -- common --
138
143
 
139
144
  protected def transcode(data)
140
- data = data.encode @external_encoding, @transcode_options unless @external_encoding.nil?
145
+ data = data.encode @external_encoding, **@transcode_options unless @external_encoding.nil?
141
146
  data
142
147
  end
143
148
  end
@@ -1,6 +1,8 @@
1
1
  # Ruby bindings for lzws library.
2
2
  # Copyright (c) 2019 AUTHORS, MIT License.
3
3
 
4
+ require "English"
5
+
4
6
  require_relative "../error"
5
7
  require_relative "../validation"
6
8
 
@@ -11,18 +13,13 @@ module LZWS
11
13
  write object
12
14
  end
13
15
 
14
- def print(*objects)
15
- if objects.empty?
16
- write $LAST_READ_LINE unless $LAST_READ_LINE.nil?
17
- return nil
18
- end
19
-
16
+ def print(*objects, field_separator: $OUTPUT_FIELD_SEPARATOR, record_separator: $OUTPUT_RECORD_SEPARATOR)
20
17
  objects.each do |object|
21
18
  write object
22
- write $OUTPUT_FIELD_SEPARATOR unless $OUTPUT_FIELD_SEPARATOR.nil?
19
+ write field_separator unless field_separator.nil?
23
20
  end
24
21
 
25
- write $OUTPUT_RECORD_SEPARATOR unless $OUTPUT_RECORD_SEPARATOR.nil?
22
+ write record_separator unless record_separator.nil?
26
23
 
27
24
  nil
28
25
  end
@@ -34,9 +31,10 @@ module LZWS
34
31
  end
35
32
 
36
33
  def putc(object, encoding: ::Encoding::BINARY)
37
- if object.is_a? ::Numeric
34
+ case object
35
+ when ::Numeric
38
36
  write object.chr(encoding)
39
- elsif object.is_a? ::String
37
+ when ::String
40
38
  write object[0]
41
39
  else
42
40
  raise ValidateError, "invalid object: \"#{object}\" for putc"