lzma-ffi 0.0.1.alpha

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.
Binary file
Binary file
data/lib/lzma.rb ADDED
@@ -0,0 +1,199 @@
1
+ #--
2
+ # Copyleft shura. [ shura1991@gmail.com ]
3
+ #
4
+ # This file is part of lzma-ffi.
5
+ #
6
+ # lzma-ffi is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # lzma-ffi is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with lzma-ffi. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'ffi'
21
+
22
+ class String
23
+ def pointer
24
+ FFI::Pointer.new([self].pack('P').unpack('L!').first)
25
+ end
26
+ end
27
+
28
+ class LZMA
29
+ module C
30
+ extend FFI::Library
31
+
32
+ if RUBY_PLATFORM =~ /(?<!dar)win/
33
+ case 1.size * 8
34
+ when 64
35
+ ffi_lib File.realpath(File.join('..', 'liblzma_x86_64.dll'), __FILE__)
36
+ when 32
37
+ ffi_lib File.realpath(File.join('..', 'liblzma_x86.dll'), __FILE__)
38
+ else
39
+ raise LoadError, "Windows architecture not supported"
40
+ end
41
+ else
42
+ ffi_lib ['lzma.so.5.0.3', 'lzma.so.5', 'lzma.so', 'lzma']
43
+ end
44
+
45
+ enum :lzma_ret, [:OK, 0, :STREAM_END, :NO_CHECK, :UNSUPPORTED_CHECK,
46
+ :GET_CHECK, :MEM_ERROR, :MEMLIMIT_ERROR, :FORMAT_ERROR, :OPTIONS_ERROR,
47
+ :DATA_ERROR, :BUF_ERROR, :PROG_ERROR]
48
+
49
+ enum :lzma_action, [:RUN, 0, :SYNC_FLUSH, :FULL_FLUSH, :FINISH]
50
+ enum :lzma_reserved_enum, [:LZMA_RESERVED_ENUM, 0]
51
+
52
+ class LZMAStream < FFI::Struct
53
+ layout \
54
+ :next_in, :pointer,
55
+ :avail_in, :uint,
56
+ :total_in, :uint64,
57
+
58
+ :next_out, :pointer,
59
+ :avail_out, :uint,
60
+ :total_out, :uint64,
61
+
62
+ :allocator, :pointer,
63
+ :internal, :pointer,
64
+
65
+ :reserved_ptr1, :pointer,
66
+ :reserved_ptr2, :pointer,
67
+ :reserved_ptr3, :pointer,
68
+ :reserved_ptr4, :pointer,
69
+ :reserved_int1, :uint64,
70
+ :reserved_int2, :uint64,
71
+ :reserved_int3, :uint,
72
+ :reserved_int4, :uint,
73
+ :reserved_enum1, :lzma_reserved_enum,
74
+ :reserved_enum2, :lzma_reserved_enum
75
+ end
76
+
77
+ attach_function :lzma_auto_decoder, [:pointer, :uint64, :uint32], :lzma_ret
78
+ attach_function :lzma_code, [:pointer, :lzma_action], :lzma_ret
79
+ attach_function :lzma_end, [:pointer], :void
80
+ end
81
+
82
+ class Stream
83
+ INIT = [nil, 0, 0, nil, 0, 0, nil, nil, nil, nil, nil, nil, 0, 0, 0, 0, 0, 0].pack('PL!QPL!QPPPPPPQQL!L!i!i!').pointer.freeze
84
+
85
+ def initialize(stream, buf_len=4096)
86
+ @stream, @buf_len = stream, buf_len || 4096
87
+ @buf = (' ' * @buf_len).pointer
88
+ @struct = C::LZMAStream.new(INIT)
89
+
90
+ ObjectSpace.define_finalizer(self, method(:finalize))
91
+ end
92
+
93
+ def next_in
94
+ @struct[:next_in].read_string rescue nil
95
+ end
96
+
97
+ def avail_in
98
+ @struct[:avail_in]
99
+ end
100
+
101
+ def total_in
102
+ @struct[:total_in]
103
+ end
104
+
105
+ def next_out
106
+ @struct[:next_out].read_string rescue nil
107
+ end
108
+
109
+ def avail_out
110
+ @struct[:avail_out]
111
+ end
112
+
113
+ def total_out
114
+ @struct[:total_out]
115
+ end
116
+
117
+ def to_ffi
118
+ @struct
119
+ end
120
+
121
+ def ptr
122
+ @struct.pointer
123
+ end
124
+
125
+ def size
126
+ @struct.size
127
+ end
128
+
129
+ def to_s
130
+ %w[in out].flat_map {|i|
131
+ %w[next avail total].map {|w|
132
+ send("#{w}_#{i}".to_sym)
133
+ }
134
+ }
135
+ end
136
+
137
+ def decoder(limit, flags)
138
+ raise RuntimeError, "lzma_stream_decoder error" if C.lzma_auto_decoder(@struct.pointer, 0xffffffffffffffff, 0x02 | 0x08) != :OK
139
+ self
140
+ end
141
+
142
+ def read
143
+ @struct[:next_in] = FFI::MemoryPointer.from_string(str = @stream.read(@buf_len))
144
+ @struct[:avail_in] = str.bytesize
145
+ end
146
+
147
+ def code(action)
148
+ @struct[:next_out] = @buf
149
+ @struct[:avail_out] = @buf_len
150
+ C.lzma_code(@struct.pointer, action)
151
+ end
152
+
153
+ def next_out
154
+ @buf.read_string_length(@buf_len - @struct[:avail_out])
155
+ end
156
+
157
+ def finalize
158
+ C.lzma_end(@struct.pointer)
159
+ end
160
+
161
+ def self.size
162
+ C::LZMAStream.size
163
+ end
164
+ end
165
+
166
+ def self.decompress(what, buf_len=4096, &blk)
167
+ what = StringIO.new(what.to_s) unless what.is_a?(IO)
168
+ res = ''
169
+ blk = lambda {|chunk| res << chunk } unless block_given?
170
+
171
+ stream = Stream.new(what, buf_len).decoder(0xffffffffffffffff, 0x02 | 0x08)
172
+
173
+ until what.eof?
174
+ stream.read
175
+ action = what.eof? ? :FINISH : :RUN
176
+
177
+ begin
178
+ raise RuntimeError, "lzma_code error" unless [:OK, :STREAM_END].include?(stream.code(action))
179
+
180
+ blk.call(stream.next_out)
181
+ end while stream.avail_out.zero?
182
+ end
183
+
184
+ stream.finalize
185
+ what.close
186
+
187
+ block_given? ? what : res
188
+ end
189
+
190
+ def self.extract(file, to=file.gsub(/\.(xz|lzma)$/, ''))
191
+ File.open(to, 'wb') {|f|
192
+ decompress(File.open(file)) {|chunk|
193
+ f.write(chunk)
194
+ }
195
+ }
196
+
197
+ to
198
+ end
199
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lzma-ffi
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ - alpha
10
+ version: 0.0.1.alpha
11
+ platform: ruby
12
+ authors:
13
+ - shura
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-28 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ffi
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: liblzma bindings for ruby
35
+ email: shura1991@gmail.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - lib/lzma.rb
44
+ - lib/liblzma_x86.dll
45
+ - lib/liblzma_x86_64.dll
46
+ has_rdoc: true
47
+ homepage: http://github.com/shurizzle/ruby-lzma-ffi
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options: []
52
+
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">"
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 1
70
+ - 3
71
+ - 1
72
+ version: 1.3.1
73
+ requirements: []
74
+
75
+ rubyforge_project:
76
+ rubygems_version: 1.3.7
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: liblzma bindings for ruby
80
+ test_files: []
81
+