Class: Archive::Reader
- Inherits:
-
BaseArchive
- Object
- BaseArchive
- Archive::Reader
- Defined in:
- lib/ffi-libarchive/reader.rb
Class Method Summary collapse
- .open_filename(file_name, command = nil) ⇒ Object
- .open_memory(string, command = nil) ⇒ Object
- .open_stream(reader) ⇒ Object
Instance Method Summary collapse
- #each_entry ⇒ Object
- #each_entry_with_data(_size = C::DATA_BUFFER_SIZE) ⇒ Object
- #extract(entry, flags = 0) ⇒ Object
- #header_position ⇒ Object
-
#initialize(params = {}) ⇒ Reader
constructor
A new instance of Reader.
- #next_header(clone_entry: false) ⇒ Object
- #read_data(size = C::DATA_BUFFER_SIZE) ⇒ Object
- #save_data(file_name) ⇒ Object
Methods inherited from BaseArchive
#close, #errno, #error_string, finalizer
Constructor Details
#initialize(params = {}) ⇒ Reader
Returns a new instance of Reader.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ffi-libarchive/reader.rb', line 44 def initialize(params = {}) super C.method(:archive_read_new), C.method(:archive_read_finish) if params[:command] cmd = params[:command] raise Error, @archive if C.archive_read_support_compression_program(archive, cmd) != C::OK else raise Error, @archive if C.archive_read_support_compression_all(archive) != C::OK end raise Error, @archive if C.archive_read_support_format_all(archive) != C::OK case when params[:file_name] raise Error, @archive if C.archive_read_open_filename(archive, params[:file_name], 1024) != C::OK when params[:memory] str = params[:memory] @data = FFI::MemoryPointer.new(str.bytesize + 1) @data.write_string str, str.bytesize raise Error, @archive if C.archive_read_open_memory(archive, @data, str.bytesize) != C::OK when params[:reader] @reader = params[:reader] @buffer = nil @read_callback = FFI::Function.new(:int, %i{pointer pointer pointer}) do |_, _, archive_data| data = @reader.call || "" @buffer = FFI::MemoryPointer.new(:char, data.size) if @buffer.nil? || @buffer.size < data.size @buffer.write_bytes(data) archive_data.write_pointer(@buffer) data.size end C.archive_read_set_read_callback(archive, @read_callback) if @reader.respond_to?(:skip) @skip_callback = FFI::Function.new(:int, %i{pointer pointer int64}) do |_, _, offset| @reader.skip(offset) end C.archive_read_set_skip_callback(archive, @skip_callback) end if @reader.respond_to?(:seek) @seek_callback = FFI::Function.new(:int, %i{pointer pointer int64 int}) do |_, _, offset, whence| @reader.seek(offset, whence) end C.archive_read_set_seek_callback(archive, @seek_callback) end # Required or open1 will segfault, even though the callback data is not used. C.archive_read_set_callback_data(archive, nil) raise Error, @archive if C.archive_read_open1(archive) != C::OK end rescue close raise end |
Class Method Details
.open_filename(file_name, command = nil) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/ffi-libarchive/reader.rb', line 5 def self.open_filename(file_name, command = nil) if block_given? reader = open_filename file_name, command begin yield reader ensure reader.close end else new file_name: file_name, command: command end end |
.open_memory(string, command = nil) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/ffi-libarchive/reader.rb', line 18 def self.open_memory(string, command = nil) if block_given? reader = open_memory string, command begin yield reader ensure reader.close end else new memory: string, command: command end end |
.open_stream(reader) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/ffi-libarchive/reader.rb', line 31 def self.open_stream(reader) if block_given? reader = new reader: reader begin yield reader ensure reader.close end else new reader: reader end end |
Instance Method Details
#each_entry ⇒ Object
125 126 127 128 129 |
# File 'lib/ffi-libarchive/reader.rb', line 125 def each_entry while (entry = next_header) yield entry end end |
#each_entry_with_data(_size = C::DATA_BUFFER_SIZE) ⇒ Object
131 132 133 134 135 |
# File 'lib/ffi-libarchive/reader.rb', line 131 def each_entry_with_data(_size = C::DATA_BUFFER_SIZE) while (entry = next_header) yield entry, read_data end end |
#extract(entry, flags = 0) ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/ffi-libarchive/reader.rb', line 100 def extract(entry, flags = 0) raise ArgumentError, "Expected Archive::Entry as first argument" unless entry.is_a? Entry raise ArgumentError, "Expected Integer as second argument" unless flags.is_a? Integer flags |= EXTRACT_FFLAGS raise Error, @archive if C.archive_read_extract(archive, entry.entry, flags) != C::OK end |
#header_position ⇒ Object
108 109 110 |
# File 'lib/ffi-libarchive/reader.rb', line 108 def header_position raise Error, @archive if C.archive_read_header_position archive end |
#next_header(clone_entry: false) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/ffi-libarchive/reader.rb', line 112 def next_header(clone_entry: false) entry_ptr = FFI::MemoryPointer.new(:pointer) case C.archive_read_next_header(archive, entry_ptr) when C::OK Entry.from_pointer entry_ptr.read_pointer, clone: clone_entry when C::EOF @eof = true nil else raise Error, @archive end end |
#read_data(size = C::DATA_BUFFER_SIZE) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/ffi-libarchive/reader.rb', line 137 def read_data(size = C::DATA_BUFFER_SIZE) raise ArgumentError, "Buffer size must be > 0 (was: #{size})" unless size.is_a?(Integer) && size > 0 data = nil buffer = FFI::MemoryPointer.new(size) len = 0 while (n = C.archive_read_data(archive, buffer, size)) > 0 case n when C::FATAL, C::WARN, C::RETRY raise Error, @archive else if block_given? yield buffer.get_bytes(0, n) else data ||= "" data.concat(buffer.get_bytes(0, n)) end end len += n end data || len end |