ffi-libarchive 0.4.6 → 1.0.17

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c72d2c946ebbe1abc58adcc317403ec80da09dc6f1279da0a6ac4ba9b97f69b0
4
- data.tar.gz: 28b4880ea52ac6818b2c8278aece3cbb1733c6df31a7832bf0d7b079f6bb2e8b
3
+ metadata.gz: 27c509a1d26618d51623cca95acc84cfeb8c804bdf818b999c8d10ac173a99ae
4
+ data.tar.gz: 7d2a2184aa944ff1e91917be83e58be06d1df592154ce1a1bc33c8c1a6e1dd5e
5
5
  SHA512:
6
- metadata.gz: bc3da073141178fb7c7a92d86a345cfb1767218a1b30251b7ad610e8f3e21372e1937e63a4f5bc2375ebd032d3cb8401ac834c80bac35fb1821d081b779b850a
7
- data.tar.gz: fa05aa479a2909b02e5e74f8ec361e9cae5a6092cbe42a3db1b6443c02eee740d0eee9fb91ec2a485904641eb8de98e6675f386e17b22217c086cf56de0f717c
6
+ metadata.gz: e6ba3e6ccb7c1ce9656a6bf399e4d6050bf9b8bc813d4eb6f9435c0be177dda9c861d9387913e8220eb7e27067ce93cbd891f221efcdc62c11e61f0b9284b055
7
+ data.tar.gz: 84bec17cb6e83978bd5241c116668ade6e4b2cf25595bdd44f10267c8274f42eaec00ec9719ecec2020cc1d927c13d55c437de89f4b5a8c387ed1ee1083b3797
@@ -1,7 +1,7 @@
1
1
  module Archive
2
2
  # :stopdoc:
3
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
4
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
3
+ LIBPATH ||= __dir__ + ::File::SEPARATOR
4
+ PATH ||= ::File.dirname(LIBPATH) + ::File::SEPARATOR
5
5
  # :startdoc:
6
6
 
7
7
  # Returns the library path for the module. If any arguments are given,
@@ -46,7 +46,8 @@ module Archive
46
46
  def self.require_all_libs_relative_to(fname, dir = nil)
47
47
  dir ||= ::File.basename(fname, ".*")
48
48
  search_me = ::File.expand_path(
49
- ::File.join(::File.dirname(fname), dir, "**", "*.rb"))
49
+ ::File.join(::File.dirname(fname), dir, "**", "*.rb")
50
+ )
50
51
 
51
52
  Dir.glob(search_me).sort.each { |rb| require rb }
52
53
  end
@@ -1,4 +1,4 @@
1
- require "ffi"
1
+ require "ffi" unless defined?(FFI)
2
2
 
3
3
  module Archive
4
4
  module C
@@ -16,15 +16,24 @@ module Archive
16
16
  attach_function :archive_errno, [:pointer], :int
17
17
 
18
18
  attach_function :archive_read_new, [], :pointer
19
- attach_function :archive_read_open_filename, [:pointer, :string, :size_t], :int
20
- attach_function :archive_read_open_memory, [:pointer, :pointer, :size_t], :int
21
- attach_function :archive_read_support_compression_program, [:pointer, :string], :int
19
+ attach_function :archive_read_open_filename, %i{pointer string size_t}, :int
20
+ attach_function :archive_read_open_memory, %i{pointer pointer size_t}, :int
21
+ attach_function :archive_read_open1, [:pointer], :int
22
+ attach_function :archive_read_support_compression_program, %i{pointer string}, :int
22
23
  attach_function :archive_read_support_compression_all, [:pointer], :int
23
24
 
24
- attach_function_maybe :archive_read_set_format, [:pointer, :int], :int
25
- attach_function_maybe :archive_read_append_filter, [:pointer, :int], :int
26
- attach_function_maybe :archive_read_append_filter_program, [:pointer, :pointer], :int
27
- attach_function_maybe :archive_read_append_filter_program_signature, [:pointer, :string, :pointer, :size_t], :int
25
+ callback :archive_read_callback, %i{pointer pointer pointer}, :int
26
+ callback :archive_skip_callback, %i{pointer pointer int64}, :int
27
+ callback :archive_seek_callback, %i{pointer pointer int64 int}, :int
28
+ attach_function :archive_read_set_read_callback, %i{pointer archive_read_callback}, :int
29
+ attach_function :archive_read_set_callback_data, %i{pointer pointer}, :int
30
+ attach_function :archive_read_set_skip_callback, %i{pointer archive_skip_callback}, :int
31
+ attach_function :archive_read_set_seek_callback, %i{pointer archive_seek_callback}, :int
32
+
33
+ attach_function_maybe :archive_read_set_format, %i{pointer int}, :int
34
+ attach_function_maybe :archive_read_append_filter, %i{pointer int}, :int
35
+ attach_function_maybe :archive_read_append_filter_program, %i{pointer pointer}, :int
36
+ attach_function_maybe :archive_read_append_filter_program_signature, %i{pointer string pointer size_t}, :int
28
37
 
29
38
  attach_function_maybe :archive_read_support_filter_all, [:pointer], :int
30
39
  attach_function_maybe :archive_read_support_filter_bzip2, [:pointer], :int
@@ -64,18 +73,18 @@ module Archive
64
73
  attach_function_maybe :archive_read_support_format_zip_seekable, [:pointer], :int
65
74
 
66
75
  attach_function :archive_read_finish, [:pointer], :int
67
- attach_function :archive_read_extract, [:pointer, :pointer, :int], :int
76
+ attach_function :archive_read_extract, %i{pointer pointer int}, :int
68
77
  attach_function :archive_read_header_position, [:pointer], :int
69
- attach_function :archive_read_next_header, [:pointer, :pointer], :int
70
- attach_function :archive_read_data, [:pointer, :pointer, :size_t], :size_t
71
- attach_function :archive_read_data_into_fd, [:pointer, :int], :int
78
+ attach_function :archive_read_next_header, %i{pointer pointer}, :int
79
+ attach_function :archive_read_data, %i{pointer pointer size_t}, :size_t
80
+ attach_function :archive_read_data_into_fd, %i{pointer int}, :int
72
81
 
73
82
  attach_function :archive_write_new, [], :pointer
74
- attach_function :archive_write_open_filename, [:pointer, :string], :int
75
- callback :archive_open_callback, [:pointer, :pointer], :int
76
- callback :archive_write_callback, [:pointer, :pointer, :pointer, :size_t], :int
77
- callback :archive_close_callback, [:pointer, :pointer], :int
78
- attach_function :archive_write_open, [:pointer, :pointer, :pointer, :archive_write_callback, :pointer], :int
83
+ attach_function :archive_write_open_filename, %i{pointer string}, :int
84
+ callback :archive_open_callback, %i{pointer pointer}, :int
85
+ callback :archive_write_callback, %i{pointer pointer pointer size_t}, :int
86
+ callback :archive_close_callback, %i{pointer pointer}, :int
87
+ attach_function :archive_write_open, %i{pointer pointer pointer archive_write_callback pointer}, :int
79
88
  attach_function :archive_write_set_compression_none, [:pointer], :int
80
89
  attach_function_maybe :archive_write_set_compression_gzip, [:pointer], :int
81
90
  attach_function_maybe :archive_write_set_compression_bzip2, [:pointer], :int
@@ -83,7 +92,7 @@ module Archive
83
92
  attach_function_maybe :archive_write_set_compression_compress, [:pointer], :int
84
93
  attach_function_maybe :archive_write_set_compression_lzma, [:pointer], :int
85
94
  attach_function_maybe :archive_write_set_compression_xz, [:pointer], :int
86
- attach_function :archive_write_set_compression_program, [:pointer, :string], :int
95
+ attach_function :archive_write_set_compression_program, %i{pointer string}, :int
87
96
 
88
97
  def self.archive_write_set_compression(archive, compression)
89
98
  case compression
@@ -106,94 +115,95 @@ module Archive
106
115
  end
107
116
  end
108
117
 
109
- attach_function :archive_write_set_format, [:pointer, :int], :int
110
- attach_function :archive_write_data, [:pointer, :pointer, :size_t], :ssize_t
111
- attach_function :archive_write_header, [:pointer, :pointer], :int
118
+ attach_function :archive_write_set_format, %i{pointer int}, :int
119
+ attach_function :archive_write_data, %i{pointer pointer size_t}, :ssize_t
120
+ attach_function :archive_write_header, %i{pointer pointer}, :int
112
121
  attach_function :archive_write_finish, [:pointer], :void
113
122
  attach_function :archive_write_get_bytes_in_last_block, [:pointer], :int
114
- attach_function :archive_write_set_bytes_in_last_block, [:pointer, :int], :int
123
+ attach_function :archive_write_set_bytes_in_last_block, %i{pointer int}, :int
115
124
 
116
125
  attach_function :archive_entry_new, [], :pointer
126
+ attach_function :archive_entry_clone, [:pointer], :pointer
117
127
  attach_function :archive_entry_free, [:pointer], :void
118
128
  attach_function :archive_entry_atime, [:pointer], :time_t
119
- attach_function :archive_entry_atime_nsec, [:pointer, :time_t, :long], :void
129
+ attach_function :archive_entry_atime_nsec, %i{pointer time_t long}, :void
120
130
  attach_function_maybe :archive_entry_atime_is_set, [:pointer], :int
121
- attach_function :archive_entry_set_atime, [:pointer, :time_t, :long], :int
131
+ attach_function :archive_entry_set_atime, %i{pointer time_t long}, :int
122
132
  attach_function_maybe :archive_entry_unset_atime, [:pointer], :int
123
133
  attach_function_maybe :archive_entry_birthtime, [:pointer], :time_t
124
- attach_function_maybe :archive_entry_birthtime_nsec, [:pointer, :time_t, :long], :void
134
+ attach_function_maybe :archive_entry_birthtime_nsec, %i{pointer time_t long}, :void
125
135
  attach_function_maybe :archive_entry_birthtime_is_set, [:pointer], :int
126
- attach_function_maybe :archive_entry_set_birthtime, [:pointer, :time_t, :long], :int
136
+ attach_function_maybe :archive_entry_set_birthtime, %i{pointer time_t long}, :int
127
137
  attach_function_maybe :archive_entry_unset_birthtime, [:pointer], :int
128
138
  attach_function :archive_entry_ctime, [:pointer], :time_t
129
- attach_function :archive_entry_ctime_nsec, [:pointer, :time_t, :long], :void
139
+ attach_function :archive_entry_ctime_nsec, %i{pointer time_t long}, :void
130
140
  attach_function_maybe :archive_entry_ctime_is_set, [:pointer], :int
131
- attach_function :archive_entry_set_ctime, [:pointer, :time_t, :long], :int
141
+ attach_function :archive_entry_set_ctime, %i{pointer time_t long}, :int
132
142
  attach_function_maybe :archive_entry_unset_ctime, [:pointer], :int
133
143
  attach_function :archive_entry_mtime, [:pointer], :time_t
134
- attach_function :archive_entry_mtime_nsec, [:pointer, :time_t, :long], :void
144
+ attach_function :archive_entry_mtime_nsec, %i{pointer time_t long}, :void
135
145
  attach_function_maybe :archive_entry_mtime_is_set, [:pointer], :int
136
- attach_function :archive_entry_set_mtime, [:pointer, :time_t, :long], :int
146
+ attach_function :archive_entry_set_mtime, %i{pointer time_t long}, :int
137
147
  attach_function_maybe :archive_entry_unset_mtime, [:pointer], :int
138
148
  attach_function :archive_entry_dev, [:pointer], :dev_t
139
- attach_function :archive_entry_set_dev, [:pointer, :dev_t], :void
149
+ attach_function :archive_entry_set_dev, %i{pointer dev_t}, :void
140
150
  attach_function :archive_entry_devmajor, [:pointer], :dev_t
141
- attach_function :archive_entry_set_devmajor, [:pointer, :dev_t], :void
151
+ attach_function :archive_entry_set_devmajor, %i{pointer dev_t}, :void
142
152
  attach_function :archive_entry_devminor, [:pointer], :dev_t
143
- attach_function :archive_entry_set_devminor, [:pointer, :dev_t], :void
153
+ attach_function :archive_entry_set_devminor, %i{pointer dev_t}, :void
144
154
  attach_function :archive_entry_filetype, [:pointer], :mode_t
145
- attach_function :archive_entry_set_filetype, [:pointer, :mode_t], :void
146
- attach_function :archive_entry_fflags, [:pointer, :pointer, :pointer], :void
147
- attach_function :archive_entry_set_fflags, [:pointer, :ulong, :ulong], :void
155
+ attach_function :archive_entry_set_filetype, %i{pointer mode_t}, :void
156
+ attach_function :archive_entry_fflags, %i{pointer pointer pointer}, :void
157
+ attach_function :archive_entry_set_fflags, %i{pointer ulong ulong}, :void
148
158
  attach_function :archive_entry_fflags_text, [:pointer], :string
149
- attach_function :archive_entry_gid, [:pointer], :gid_t
150
- attach_function :archive_entry_set_gid, [:pointer, :gid_t], :void
159
+ attach_function :archive_entry_gid, [:pointer], :uint
160
+ attach_function :archive_entry_set_gid, %i{pointer uint}, :void
151
161
  attach_function :archive_entry_gname, [:pointer], :string
152
- attach_function :archive_entry_set_gname, [:pointer, :string], :void
162
+ attach_function :archive_entry_set_gname, %i{pointer string}, :void
153
163
  attach_function :archive_entry_hardlink, [:pointer], :string
154
- attach_function :archive_entry_set_hardlink, [:pointer, :string], :void
155
- attach_function :archive_entry_set_link, [:pointer, :string], :void
164
+ attach_function :archive_entry_set_hardlink, %i{pointer string}, :void
165
+ attach_function :archive_entry_set_link, %i{pointer string}, :void
156
166
  attach_function :archive_entry_ino, [:pointer], :ino_t
157
- attach_function :archive_entry_set_ino, [:pointer, :ino_t], :void
167
+ attach_function :archive_entry_set_ino, %i{pointer ino_t}, :void
158
168
  attach_function :archive_entry_mode, [:pointer], :mode_t
159
- attach_function :archive_entry_set_mode, [:pointer, :mode_t], :void
160
- attach_function :archive_entry_set_perm, [:pointer, :mode_t], :void
169
+ attach_function :archive_entry_set_mode, %i{pointer mode_t}, :void
170
+ attach_function :archive_entry_set_perm, %i{pointer mode_t}, :void
161
171
  attach_function :archive_entry_nlink, [:pointer], :uint
162
- attach_function :archive_entry_set_nlink, [:pointer, :uint], :void
172
+ attach_function :archive_entry_set_nlink, %i{pointer uint}, :void
163
173
  attach_function :archive_entry_pathname, [:pointer], :string
164
- attach_function :archive_entry_set_pathname, [:pointer, :string], :void
174
+ attach_function :archive_entry_set_pathname, %i{pointer string}, :void
165
175
  attach_function :archive_entry_rdev, [:pointer], :dev_t
166
- attach_function :archive_entry_set_rdev, [:pointer, :dev_t], :void
176
+ attach_function :archive_entry_set_rdev, %i{pointer dev_t}, :void
167
177
  attach_function :archive_entry_rdevmajor, [:pointer], :dev_t
168
- attach_function :archive_entry_set_rdevmajor, [:pointer, :dev_t], :void
178
+ attach_function :archive_entry_set_rdevmajor, %i{pointer dev_t}, :void
169
179
  attach_function :archive_entry_rdevminor, [:pointer], :dev_t
170
- attach_function :archive_entry_set_rdevminor, [:pointer, :dev_t], :void
180
+ attach_function :archive_entry_set_rdevminor, %i{pointer dev_t}, :void
171
181
  attach_function :archive_entry_size, [:pointer], :int64_t
172
- attach_function :archive_entry_set_size, [:pointer, :int64_t], :void
182
+ attach_function :archive_entry_set_size, %i{pointer int64_t}, :void
173
183
  attach_function_maybe :archive_entry_unset_size, [:pointer], :void
174
184
  attach_function_maybe :archive_entry_size_is_set, [:pointer], :int
175
185
  attach_function :archive_entry_sourcepath, [:pointer], :string
176
186
  attach_function :archive_entry_strmode, [:pointer], :string
177
187
  attach_function :archive_entry_symlink, [:pointer], :string
178
- attach_function :archive_entry_set_symlink, [:pointer, :string], :void
179
- attach_function :archive_entry_uid, [:pointer], :uid_t
180
- attach_function :archive_entry_set_uid, [:pointer, :uid_t], :void
188
+ attach_function :archive_entry_set_symlink, %i{pointer string}, :void
189
+ attach_function :archive_entry_uid, [:pointer], :uint
190
+ attach_function :archive_entry_set_uid, %i{pointer uint}, :void
181
191
  attach_function :archive_entry_uname, [:pointer], :string
182
- attach_function :archive_entry_set_uname, [:pointer, :string], :void
183
- attach_function :archive_entry_copy_stat, [:pointer, :pointer], :void
184
- attach_function :archive_entry_copy_fflags_text, [:pointer, :string], :string
185
- attach_function :archive_entry_copy_gname, [:pointer, :string], :string
186
- attach_function :archive_entry_copy_uname, [:pointer, :string], :string
187
- attach_function :archive_entry_copy_hardlink, [:pointer, :string], :string
188
- attach_function :archive_entry_copy_link, [:pointer, :string], :string
189
- attach_function :archive_entry_copy_symlink, [:pointer, :string], :string
190
- attach_function :archive_entry_copy_sourcepath, [:pointer, :string], :string
191
- attach_function :archive_entry_copy_pathname, [:pointer, :string], :string
192
+ attach_function :archive_entry_set_uname, %i{pointer string}, :void
193
+ attach_function :archive_entry_copy_stat, %i{pointer pointer}, :void
194
+ attach_function :archive_entry_copy_fflags_text, %i{pointer string}, :string
195
+ attach_function :archive_entry_copy_gname, %i{pointer string}, :string
196
+ attach_function :archive_entry_copy_uname, %i{pointer string}, :string
197
+ attach_function :archive_entry_copy_hardlink, %i{pointer string}, :string
198
+ attach_function :archive_entry_copy_link, %i{pointer string}, :string
199
+ attach_function :archive_entry_copy_symlink, %i{pointer string}, :string
200
+ attach_function :archive_entry_copy_sourcepath, %i{pointer string}, :string
201
+ attach_function :archive_entry_copy_pathname, %i{pointer string}, :string
192
202
  attach_function :archive_entry_xattr_clear, [:pointer], :void
193
- attach_function :archive_entry_xattr_add_entry, [:pointer, :string, :pointer, :size_t], :void
203
+ attach_function :archive_entry_xattr_add_entry, %i{pointer string pointer size_t}, :void
194
204
  attach_function :archive_entry_xattr_count, [:pointer], :int
195
205
  attach_function :archive_entry_xattr_reset, [:pointer], :int
196
- attach_function :archive_entry_xattr_next, [:pointer, :pointer, :pointer, :pointer], :int
206
+ attach_function :archive_entry_xattr_next, %i{pointer pointer pointer pointer}, :int
197
207
 
198
208
  EOF = 1
199
209
  OK = 0
@@ -278,6 +288,10 @@ module Archive
278
288
  Reader.open_memory string, command, &block
279
289
  end
280
290
 
291
+ def self.read_open_stream(reader, &block)
292
+ Reader.open_stream reader, &block
293
+ end
294
+
281
295
  def self.write_open_filename(file_name, compression, format, &block)
282
296
  Writer.open_filename file_name, compression, format, &block
283
297
  end
@@ -336,6 +350,7 @@ module Archive
336
350
 
337
351
  def archive
338
352
  raise Error, "No archive open" unless @archive
353
+
339
354
  @archive
340
355
  end
341
356
  protected :archive
@@ -17,14 +17,14 @@ module Archive
17
17
  CHARACTER_SPECIAL = 0020000 # character device
18
18
  FIFO = 0010000 # FIFO
19
19
 
20
- def self.from_pointer(entry)
21
- new entry
20
+ def self.from_pointer(entry, clone: false)
21
+ new entry, clone: clone
22
22
  end
23
23
 
24
- def initialize(entry = nil)
24
+ def initialize(entry = nil, clone: false)
25
25
  @entry_free = [true]
26
26
  if entry
27
- @entry = entry
27
+ @entry = clone ? C.archive_entry_clone(entry) : entry
28
28
  yield self if block_given?
29
29
  else
30
30
  @entry = C.archive_entry_new
@@ -34,7 +34,7 @@ module Archive
34
34
  result = yield self
35
35
  C.archive_entry_free(@entry)
36
36
  @entry = nil
37
- return result
37
+ result
38
38
  else
39
39
  @entry_free[0] = false
40
40
  ObjectSpace.define_finalizer(self, Entry.finalizer(@entry, @entry_free))
@@ -60,6 +60,7 @@ module Archive
60
60
 
61
61
  def entry
62
62
  raise "No entry object" unless @entry
63
+
63
64
  @entry
64
65
  end
65
66
 
@@ -182,6 +183,7 @@ module Archive
182
183
 
183
184
  stat = Archive::Stat.ffi_libarchive_create_lstat(filename)
184
185
  raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
186
+
185
187
  C.archive_entry_copy_stat(entry, stat)
186
188
  ensure
187
189
  Archive::Stat.ffi_libarchive_free_stat(stat)
@@ -207,6 +209,7 @@ module Archive
207
209
 
208
210
  stat = Archive::Stat.ffi_libarchive_create_stat(filename)
209
211
  raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
212
+
210
213
  C.archive_entry_copy_stat(entry, stat)
211
214
  ensure
212
215
  Archive::Stat.ffi_libarchive_free_stat(stat)
@@ -459,10 +462,10 @@ module Archive
459
462
  value = FFI::MemoryPointer.new :pointer
460
463
  size = FFI::MemoryPointer.new :size_t
461
464
  if C.archive_entry_xattr_next(entry, name, value, size) != C::OK
462
- return nil
465
+ nil
463
466
  else
464
467
  # TODO: someday size.read_size_t could work
465
- return [name.null? ? nil : name.read_string,
468
+ [name.null? ? nil : name.read_string,
466
469
  value.null? ? nil : value.get_string(0, size.read_ulong)]
467
470
  end
468
471
  end
@@ -28,6 +28,19 @@ module Archive
28
28
  end
29
29
  end
30
30
 
31
+ def self.open_stream(reader)
32
+ if block_given?
33
+ reader = new reader: reader
34
+ begin
35
+ yield reader
36
+ ensure
37
+ reader.close
38
+ end
39
+ else
40
+ new reader: reader
41
+ end
42
+ end
43
+
31
44
  def initialize(params = {})
32
45
  super C.method(:archive_read_new), C.method(:archive_read_finish)
33
46
 
@@ -40,22 +53,60 @@ module Archive
40
53
 
41
54
  raise Error, @archive if C.archive_read_support_format_all(archive) != C::OK
42
55
 
43
- if params[:file_name]
56
+ case
57
+ when params[:file_name]
44
58
  raise Error, @archive if C.archive_read_open_filename(archive, params[:file_name], 1024) != C::OK
45
- elsif params[:memory]
59
+ when params[:memory]
46
60
  str = params[:memory]
47
61
  @data = FFI::MemoryPointer.new(str.bytesize + 1)
48
62
  @data.write_string str, str.bytesize
49
63
  raise Error, @archive if C.archive_read_open_memory(archive, @data, str.bytesize) != C::OK
64
+ when params[:reader]
65
+ @reader = params[:reader]
66
+ @buffer = nil
67
+
68
+ @read_callback = FFI::Function.new(:int, %i{pointer pointer pointer}) do |_, _, archive_data|
69
+ data = @reader.call || ""
70
+ @buffer = FFI::MemoryPointer.new(:char, data.size) if @buffer.nil? || @buffer.size < data.size
71
+ @buffer.write_bytes(data)
72
+ archive_data.write_pointer(@buffer)
73
+ data.size
74
+ end
75
+ C.archive_read_set_read_callback(archive, @read_callback)
76
+
77
+ if @reader.respond_to?(:skip)
78
+ @skip_callback = FFI::Function.new(:int, %i{pointer pointer int64}) do |_, _, offset|
79
+ @reader.skip(offset)
80
+ end
81
+ C.archive_read_set_skip_callback(archive, @skip_callback)
82
+ end
83
+
84
+ if @reader.respond_to?(:seek)
85
+ @seek_callback = FFI::Function.new(:int, %i{pointer pointer int64 int}) do |_, _, offset, whence|
86
+ @reader.seek(offset, whence)
87
+ end
88
+ C.archive_read_set_seek_callback(archive, @seek_callback)
89
+ end
90
+
91
+ # Required or open1 will segfault, even though the callback data is not used.
92
+ C.archive_read_set_callback_data(archive, nil)
93
+ raise Error, @archive if C.archive_read_open1(archive) != C::OK
50
94
  end
51
95
  rescue
52
96
  close
53
97
  raise
54
98
  end
55
99
 
56
- def extract(entry, flags = 0)
100
+ def extract(entry, flags = 0, destination: nil)
57
101
  raise ArgumentError, "Expected Archive::Entry as first argument" unless entry.is_a? Entry
58
102
  raise ArgumentError, "Expected Integer as second argument" unless flags.is_a? Integer
103
+ raise ArgumentError, "Expected String as destination" if destination && !destination.is_a?(String)
104
+
105
+ if destination
106
+ # We update the pathname here so this will change for the caller as a side effect, but this seems convenient and accurate?
107
+ pathname = C.archive_entry_pathname(entry.entry)
108
+ C.archive_entry_set_pathname(entry.entry, "#{destination}/#{pathname}")
109
+ end
59
110
 
60
111
  flags |= EXTRACT_FFLAGS
61
112
  raise Error, @archive if C.archive_read_extract(archive, entry.entry, flags) != C::OK
@@ -65,11 +116,11 @@ module Archive
65
116
  raise Error, @archive if C.archive_read_header_position archive
66
117
  end
67
118
 
68
- def next_header
119
+ def next_header(clone_entry: false)
69
120
  entry_ptr = FFI::MemoryPointer.new(:pointer)
70
121
  case C.archive_read_next_header(archive, entry_ptr)
71
122
  when C::OK
72
- Entry.from_pointer entry_ptr.read_pointer
123
+ Entry.from_pointer entry_ptr.read_pointer, clone: clone_entry
73
124
  when C::EOF
74
125
  @eof = true
75
126
  nil
@@ -1,3 +1,3 @@
1
1
  module Archive
2
- VERSION = "0.4.6".freeze
2
+ VERSION = "1.0.17".freeze
3
3
  end
@@ -58,9 +58,9 @@ module Archive
58
58
  end
59
59
  @data = write_callback params[:memory]
60
60
  raise Error, @archive if C.archive_write_open(archive, nil,
61
- nil,
62
- @data,
63
- nil) != C::OK
61
+ nil,
62
+ @data,
63
+ nil) != C::OK
64
64
  end
65
65
  rescue
66
66
  close
@@ -117,10 +117,12 @@ module Archive
117
117
  if (n = C.archive_write_data(ar, str, str.bytesize)) < 1
118
118
  return len
119
119
  end
120
+
120
121
  len += n
121
122
  end
122
123
  else
123
124
  raise ArgumentError, "wrong number of argument (#{args.size}) for 1)" if args.size != 1
125
+
124
126
  str = args[0]
125
127
  C.archive_write_data(archive, str, str.bytesize)
126
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-libarchive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 1.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Bellone
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-12-07 00:00:00.000000000 Z
13
+ date: 2021-02-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ffi
@@ -76,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  requirements: []
79
- rubyforge_project:
80
- rubygems_version: 2.7.6
79
+ rubygems_version: 3.1.4
81
80
  signing_key:
82
81
  specification_version: 4
83
82
  summary: A Ruby FFI binding to libarchive.