ffi-libarchive 0.4.6 → 1.0.17

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: 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.