lzma-ffi 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
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
+