rhc 0.92.11 → 0.93.18
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.
- data/README.md +1 -9
- data/Rakefile +1 -55
- data/bin/rhc +31 -1
- data/bin/rhc-app +62 -127
- data/bin/rhc-chk +6 -7
- data/bin/rhc-create-app +8 -8
- data/bin/rhc-create-domain +6 -86
- data/bin/rhc-ctl-app +3 -3
- data/bin/rhc-ctl-domain +4 -4
- data/bin/rhc-domain +16 -18
- data/bin/rhc-domain-info +3 -3
- data/bin/rhc-port-forward +127 -24
- data/bin/rhc-snapshot +7 -46
- data/bin/rhc-sshkey +13 -79
- data/bin/rhc-tail-files +16 -8
- data/lib/rhc-common.rb +406 -230
- data/lib/rhc-rest.rb +3 -3
- data/lib/rhc-rest/client.rb +1 -1
- data/lib/rhc-rest/domain.rb +1 -1
- data/lib/rhc.rb +20 -0
- data/lib/rhc/cli.rb +38 -0
- data/lib/rhc/client.rb +15 -0
- data/lib/rhc/commands.rb +32 -0
- data/lib/rhc/commands/base.rb +67 -0
- data/lib/rhc/commands/server.rb +24 -0
- data/lib/rhc/config.rb +141 -0
- data/lib/rhc/core_ext.rb +15 -0
- data/lib/rhc/helpers.rb +142 -0
- data/lib/rhc/json.rb +52 -0
- data/lib/rhc/targz.rb +46 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/wizard.rb +579 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/cli_spec.rb +24 -0
- data/spec/rhc/command_spec.rb +88 -0
- data/spec/rhc/commands/server_spec.rb +39 -0
- data/spec/rhc/helpers_spec.rb +171 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/targz_spec.rb +42 -0
- data/spec/rhc/wizard_spec.rb +426 -0
- data/spec/spec_helper.rb +192 -0
- data/test/functional/application_test.rb +71 -0
- data/test/functional/domain_test.rb +123 -0
- data/test/functional/test_credentials.rb +5 -0
- data/test/sample-usage.rb +122 -0
- data/test/support/server.rb +14 -0
- data/test/support/testcase.rb +3 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/command_test.rb +19 -0
- metadata +181 -29
- data/ext/mkrf_conf.rb +0 -58
- data/lib/rhc +0 -115
@@ -0,0 +1,628 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module RHC
|
4
|
+
module Vendor
|
5
|
+
module Zlib
|
6
|
+
|
7
|
+
ZLIBY_VERSION = "0.0.5"
|
8
|
+
ZLIB_VERSION = "1.2.3"
|
9
|
+
VERSION = "0.6.0" #For compatibility with Ruby-core Zlib
|
10
|
+
MAXBITS = 15
|
11
|
+
MAXLCODES = 286
|
12
|
+
MAXDCODES = 30
|
13
|
+
MAXCODES = (MAXLCODES+MAXDCODES)
|
14
|
+
FIXLCODES = 288
|
15
|
+
MAX_WBITS = 15
|
16
|
+
Z_DEFLATED = 8
|
17
|
+
|
18
|
+
def self.adler32 string="", adler=1
|
19
|
+
if adler > (2**128) - 1 then raise RangeError.new end
|
20
|
+
accum1 = adler & 0xffff
|
21
|
+
accum2 = (adler >> 16) & 0xffff
|
22
|
+
|
23
|
+
len = string.length
|
24
|
+
x = -1
|
25
|
+
while len > 0
|
26
|
+
tlen = len > 5552 ? 5552 : len
|
27
|
+
len -= tlen
|
28
|
+
while tlen >0
|
29
|
+
x += 1
|
30
|
+
accum1 += string[x]
|
31
|
+
accum2 += accum1
|
32
|
+
tlen -= 1
|
33
|
+
end
|
34
|
+
accum1 %= 65521
|
35
|
+
accum2 %= 65521
|
36
|
+
end
|
37
|
+
accum2 << 16 | accum1
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.crc_table
|
41
|
+
[0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.crc32 string="", crc=0
|
45
|
+
if crc > 2**128 - 1 then raise RangeError.new end
|
46
|
+
crc = crc ^ 0xffffffff
|
47
|
+
string.each_byte do |byte|
|
48
|
+
index = (crc ^ byte) & 0xff
|
49
|
+
crc = (crc >> 8) ^ crc_table[index]
|
50
|
+
end
|
51
|
+
crc ^ 0xffffffff
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
class ZStream
|
56
|
+
|
57
|
+
def initialize
|
58
|
+
@input_buffer = []
|
59
|
+
@output_buffer = []
|
60
|
+
@out_pos = -1
|
61
|
+
@in_pos = -1
|
62
|
+
@bit_bucket = 0
|
63
|
+
@bit_count = 0
|
64
|
+
|
65
|
+
end
|
66
|
+
#Returns the adler-32 checksum of the input data.
|
67
|
+
def adler
|
68
|
+
end
|
69
|
+
|
70
|
+
#Returns the number of bytes read. Normally 0 since all bytes are read at once.
|
71
|
+
def avail_in
|
72
|
+
@input_buffer.length - @in_pos
|
73
|
+
end
|
74
|
+
|
75
|
+
#Returns number of free bytes in the output buffer. As the output buffer is self expanding this normally returns 0.
|
76
|
+
def avail_out
|
77
|
+
@output_buffer.length - @out_pos
|
78
|
+
end
|
79
|
+
|
80
|
+
#Allocates size bytes in output buffer. If size < avail_out it truncates the buffer.
|
81
|
+
def avail_out= size
|
82
|
+
size.times do
|
83
|
+
if size > avail_out
|
84
|
+
@output_buffer.push nil
|
85
|
+
else
|
86
|
+
@output_buffer.pop
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#Closes stream. Further operations will raise Zlib::StreamError
|
92
|
+
def close
|
93
|
+
@closed = true
|
94
|
+
end
|
95
|
+
|
96
|
+
#True if stream closed, otherwise False.
|
97
|
+
def closed?
|
98
|
+
@closed
|
99
|
+
end
|
100
|
+
|
101
|
+
#Best guess of input data, one of Zlib::BINARY, Zlib::ASCII, or Zlib::UNKNOWN
|
102
|
+
def data_type
|
103
|
+
end
|
104
|
+
|
105
|
+
#See close
|
106
|
+
def end
|
107
|
+
close
|
108
|
+
end
|
109
|
+
|
110
|
+
#See closed?
|
111
|
+
def ended?
|
112
|
+
closed?
|
113
|
+
end
|
114
|
+
|
115
|
+
#Finishes the stream, flushes output buffer, implemented by child classes
|
116
|
+
def finish
|
117
|
+
close
|
118
|
+
end
|
119
|
+
|
120
|
+
#True if stream is finished, otherwise False
|
121
|
+
def finished?
|
122
|
+
if @finished.nil? then
|
123
|
+
false
|
124
|
+
else
|
125
|
+
@finished
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
#Flushes input buffer and returns the data therein.
|
130
|
+
def flush_next_in
|
131
|
+
@in_pos = @input_buffer.length
|
132
|
+
@finished = true
|
133
|
+
ret = @input_buffer.pack("c*")
|
134
|
+
@input_buffer = []
|
135
|
+
ret
|
136
|
+
end
|
137
|
+
|
138
|
+
#Flushes the output buffer and returns all the data
|
139
|
+
def flush_next_out
|
140
|
+
@out_pos = @output_buffer.length
|
141
|
+
@finished = true
|
142
|
+
ret = @output_buffer.pack("c*")
|
143
|
+
@output_buffer = []
|
144
|
+
ret
|
145
|
+
end
|
146
|
+
|
147
|
+
#Reset stream. Input and Output buffers are reset.
|
148
|
+
def reset
|
149
|
+
@out_pos = -1
|
150
|
+
@in_pos = -1
|
151
|
+
@input_buffer = []
|
152
|
+
@output_buffer = []
|
153
|
+
end
|
154
|
+
|
155
|
+
#See finished.
|
156
|
+
def stream_end?
|
157
|
+
finished?
|
158
|
+
end
|
159
|
+
|
160
|
+
#Size of input buffer.
|
161
|
+
def total_in
|
162
|
+
@input_buffer.length
|
163
|
+
end
|
164
|
+
|
165
|
+
#Size of output buffer.
|
166
|
+
def total_out
|
167
|
+
@output_buffer.length
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
#returns need bits from the input buffer
|
172
|
+
# == Format Notes
|
173
|
+
# bits are stored LSB to MSB
|
174
|
+
def get_bits need
|
175
|
+
val = @bit_bucket
|
176
|
+
while @bit_count < need
|
177
|
+
val |= (@input_buffer[@in_pos+=1] << @bit_count)
|
178
|
+
@bit_count += 8
|
179
|
+
end
|
180
|
+
|
181
|
+
@bit_bucket = val >> need
|
182
|
+
@bit_count -= need
|
183
|
+
val & ((1 << need) - 1)
|
184
|
+
end
|
185
|
+
public
|
186
|
+
end
|
187
|
+
|
188
|
+
#== DEFLATE Decompression
|
189
|
+
#Implements decompression of a RFC-1951[ftp://ftp.rfc-editor.org/in-notes/rfc1951.txt] compatible stream.
|
190
|
+
class Inflate < ZStream
|
191
|
+
|
192
|
+
def initialize window_bits=MAX_WBITS
|
193
|
+
@w_bits = window_bits
|
194
|
+
if @w_bits < 0 then
|
195
|
+
@rawdeflate = true
|
196
|
+
@w_bits *= -1
|
197
|
+
end
|
198
|
+
super()
|
199
|
+
@zstring = ""
|
200
|
+
end
|
201
|
+
|
202
|
+
#Appends data to the input stream
|
203
|
+
def <<(string)
|
204
|
+
@zstring << string
|
205
|
+
inflate
|
206
|
+
end
|
207
|
+
|
208
|
+
#Sets the inflate dictionary
|
209
|
+
def set_dictionary string
|
210
|
+
@dict = string
|
211
|
+
reset
|
212
|
+
end
|
213
|
+
|
214
|
+
#==Example
|
215
|
+
# f = File.open "example.z"
|
216
|
+
# i = Inflate.new
|
217
|
+
# i.inflate f.read
|
218
|
+
def inflate zstring=nil
|
219
|
+
@zstring = zstring unless zstring.nil?
|
220
|
+
#We can't use unpack, IronRuby doesn't have it yet.
|
221
|
+
@zstring.each_byte {|b| @input_buffer << b}
|
222
|
+
|
223
|
+
unless @rawdeflate then
|
224
|
+
|
225
|
+
compression_method_and_flags = @input_buffer[@in_pos+=1]
|
226
|
+
flags = @input_buffer[@in_pos+=1]
|
227
|
+
|
228
|
+
#CMF and FLG, when viewed as a 16-bit unsigned integer stored inMSB order (CMF*256 + FLG), is a multiple of 31
|
229
|
+
if ((compression_method_and_flags << 0x08) + flags) % 31 != 0 then raise Zlib::DataError.new("incorrect header check") end
|
230
|
+
|
231
|
+
#CM = 8 denotes the �deflate� compression method with a window size up to 32K. (RFC's only specify CM 8)
|
232
|
+
compression_method = compression_method_and_flags & 0x0F
|
233
|
+
|
234
|
+
if compression_method != Z_DEFLATED then raise Zlib::DataError.new("unknown compression method") end
|
235
|
+
|
236
|
+
#For CM = 8, CINFO is the base-2 logarithm of the LZ77 window size,minus eight (CINFO=7 indicates a 32K window size)
|
237
|
+
compression_info = compression_method_and_flags >> 0x04
|
238
|
+
|
239
|
+
if (compression_info + 8) > @w_bits then raise Zlib::DataError.new("invalid window size") end
|
240
|
+
|
241
|
+
preset_dictionary_flag = ((flags & 0x20) >> 0x05) == 1
|
242
|
+
compression_level = (flags & 0xC0) >> 0x06
|
243
|
+
|
244
|
+
if preset_dictionary_flag and @dict.nil? then raise Zlib::NeedDict.new "Preset dictionary needed!" end
|
245
|
+
|
246
|
+
#TODO: Add Preset dictionary support
|
247
|
+
if preset_dictionary_flag then
|
248
|
+
@dict_crc = @input_buffer[@in_pos+=1] << 24 | @input_buffer[@in_pos+=1] << 16 | @input_buffer[@in_pos+=1] << 8 | @input_buffer[@in_pos+=1]
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
252
|
+
last_block = false
|
253
|
+
#Begin processing DEFLATE stream
|
254
|
+
until last_block
|
255
|
+
last_block = (get_bits(1) == 1)
|
256
|
+
block_type = get_bits(2)
|
257
|
+
case block_type
|
258
|
+
when 0 then no_compression
|
259
|
+
when 1 then fixed_codes
|
260
|
+
when 2 then dynamic_codes
|
261
|
+
when 3 then raise Zlib::DataError.new("invalid block type")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
finish
|
265
|
+
end
|
266
|
+
|
267
|
+
#Finishes inflating and flushes the buffer
|
268
|
+
def finish
|
269
|
+
output = ""
|
270
|
+
inflate unless @output_buffer.length > 0
|
271
|
+
@output_buffer.each {|c| output << c }
|
272
|
+
super
|
273
|
+
output
|
274
|
+
end
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def no_compression
|
279
|
+
@bit_bucket = 0
|
280
|
+
@bit_count = 0
|
281
|
+
if @in_pos + 4 > @input_buffer.length then raise Zlib::DataError.new("not enough input to read length code") end
|
282
|
+
length = @input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8)
|
283
|
+
|
284
|
+
if (~length & 0xff != @input_buffer[@in_pos+=1]) || (((~length >> 8) & 0xff) != @input_buffer[@in_pos+=1]) then raise Zlib::DataError.new("invalid stored block lengths") end
|
285
|
+
|
286
|
+
if @in_pos + length > @input_buffer.length then raise Zlib::DataError.new("ran out of input") end
|
287
|
+
|
288
|
+
|
289
|
+
length.times do
|
290
|
+
@output_buffer[@out_pos += 1] = @input_buffer[@in_pos += 1]
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
def fixed_codes
|
297
|
+
if @fixed_length_codes.nil? && @fixed_distance_codes.nil? then generate_huffmans end
|
298
|
+
codes @fixed_length_codes, @fixed_distance_codes
|
299
|
+
end
|
300
|
+
|
301
|
+
def dynamic_codes
|
302
|
+
|
303
|
+
order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
|
304
|
+
nlen = get_bits(5) + 257
|
305
|
+
ndist = get_bits(5) + 1
|
306
|
+
ncode = get_bits(4) + 4
|
307
|
+
|
308
|
+
|
309
|
+
lengths=[]
|
310
|
+
dynamic_length_codes = Zlib::Inflate::HuffmanTree.new
|
311
|
+
dynamic_distance_codes = Zlib::Inflate::HuffmanTree.new
|
312
|
+
|
313
|
+
if (nlen > MAXLCODES || ndist > MAXDCODES) then raise Zlib::DataError.new("too many length or distance codes") end
|
314
|
+
idx = 0
|
315
|
+
|
316
|
+
while idx < ncode
|
317
|
+
lengths[order[idx]] = get_bits(3)
|
318
|
+
idx += 1
|
319
|
+
end
|
320
|
+
while idx < 19
|
321
|
+
lengths[order[idx]] = 0
|
322
|
+
idx += 1
|
323
|
+
end
|
324
|
+
err = construct_tree dynamic_length_codes, lengths, 18
|
325
|
+
if err != 0 then raise Zlib::DataError.new("code lengths codes incomplete") end
|
326
|
+
|
327
|
+
idx = 0
|
328
|
+
while idx < (nlen + ndist)
|
329
|
+
symbol = decode(dynamic_length_codes)
|
330
|
+
if symbol < 16 then
|
331
|
+
lengths[idx] = symbol
|
332
|
+
idx += 1;
|
333
|
+
else
|
334
|
+
len = 0
|
335
|
+
if symbol == 16 then
|
336
|
+
if idx == 0 then raise Zlib::DataError.new("repeat lengths with no first length") end
|
337
|
+
len = lengths[idx - 1]
|
338
|
+
symbol = 3 + get_bits(2)
|
339
|
+
elsif symbol == 17 then
|
340
|
+
symbol = 3 + get_bits(3)
|
341
|
+
elsif symbol == 18 then
|
342
|
+
symbol = 11 + get_bits(7)
|
343
|
+
else
|
344
|
+
raise Zlib::DataError.new("invalid repeat length code")
|
345
|
+
end
|
346
|
+
if (idx + symbol) > (nlen + ndist) then raise Zlib::DataError.new("repeat more than specified lengths") end
|
347
|
+
until symbol == 0
|
348
|
+
lengths[idx] = len
|
349
|
+
idx+=1
|
350
|
+
symbol -= 1
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
err = construct_tree dynamic_length_codes, lengths, nlen-1
|
356
|
+
|
357
|
+
if err < 0 || (err > 0 && (nlen - dynamic_length_codes.count[0] != 1)) then raise Zlib::DataError.new("invalid literal/length code lengths") end
|
358
|
+
|
359
|
+
nlen.times { lengths.delete_at 0 } #We do this since we don't have pointer arithmetic in ruby
|
360
|
+
|
361
|
+
err = construct_tree dynamic_distance_codes, lengths, ndist-1
|
362
|
+
if err < 0 || (err > 0 && (ndist - dynamic_distance_codes.count[0] != 1)) then raise Zlib::DataError.new("invalid distance code lengths") end
|
363
|
+
|
364
|
+
codes dynamic_length_codes, dynamic_distance_codes
|
365
|
+
end
|
366
|
+
|
367
|
+
def generate_huffmans
|
368
|
+
|
369
|
+
lengths = []
|
370
|
+
|
371
|
+
#literal/length table
|
372
|
+
for idx in (000..143)
|
373
|
+
lengths[idx] = 8
|
374
|
+
end
|
375
|
+
for idx in (144..255)
|
376
|
+
lengths[idx] = 9
|
377
|
+
end
|
378
|
+
for idx in (256..279)
|
379
|
+
lengths[idx] = 7
|
380
|
+
end
|
381
|
+
for idx in (280..287)
|
382
|
+
lengths[idx] = 8
|
383
|
+
end
|
384
|
+
@fixed_length_codes = Zlib::Inflate::HuffmanTree.new
|
385
|
+
construct_tree @fixed_length_codes, lengths, 287
|
386
|
+
|
387
|
+
for idx in (00..29)
|
388
|
+
lengths[idx] = 5
|
389
|
+
end
|
390
|
+
@fixed_distance_codes = Zlib::Inflate::HuffmanTree.new
|
391
|
+
construct_tree @fixed_distance_codes, lengths, 29
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
def codes length_codes, distance_codes
|
396
|
+
lens = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258]
|
397
|
+
lext = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]
|
398
|
+
dists = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577]
|
399
|
+
dext = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]
|
400
|
+
|
401
|
+
symbol = 0
|
402
|
+
|
403
|
+
until symbol == 256
|
404
|
+
symbol = decode(length_codes)
|
405
|
+
if symbol < 0 then return symbol end
|
406
|
+
if symbol < 256 then @output_buffer[@out_pos+=1] = symbol end
|
407
|
+
if symbol > 256 then
|
408
|
+
symbol -= 257
|
409
|
+
if symbol >= 29 then raise Zlib::DataError.new("invalid literal/length or distance code in fixed or dynamic block") end
|
410
|
+
len = lens[symbol] + get_bits(lext[symbol])
|
411
|
+
symbol = decode(distance_codes)
|
412
|
+
if symbol < 0 then return symbol end
|
413
|
+
dist = dists[symbol] + get_bits(dext[symbol])
|
414
|
+
if dist > @output_buffer.length then raise Zlib::DataError.new("distance is too far back in fixed or dynamic block") end
|
415
|
+
while len > 0
|
416
|
+
@output_buffer[@out_pos+=1] = @output_buffer[@out_pos - dist]
|
417
|
+
len -= 1
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
return 0
|
422
|
+
end
|
423
|
+
|
424
|
+
def decode huffman_tree
|
425
|
+
code = 0
|
426
|
+
first = 0
|
427
|
+
index = 0
|
428
|
+
for len in (1..15)
|
429
|
+
code |= get_bits(1)
|
430
|
+
count = huffman_tree.count[len]
|
431
|
+
if code < (first + count) then return huffman_tree.symbol[index + (code - first)] end
|
432
|
+
index += count
|
433
|
+
first += count
|
434
|
+
first <<= 1
|
435
|
+
code <<= 1
|
436
|
+
end
|
437
|
+
-9
|
438
|
+
end
|
439
|
+
|
440
|
+
def construct_tree huffman_tree, lengths, n_symbols
|
441
|
+
offs = []
|
442
|
+
|
443
|
+
for len in (000..MAXBITS)
|
444
|
+
huffman_tree.count[len] = 0
|
445
|
+
end
|
446
|
+
|
447
|
+
for symbol in (000..n_symbols)
|
448
|
+
huffman_tree.count[lengths[symbol]] += 1
|
449
|
+
end
|
450
|
+
|
451
|
+
if huffman_tree.count[0] == n_symbols then return 0 end
|
452
|
+
|
453
|
+
left = 1
|
454
|
+
for len in (1..MAXBITS)
|
455
|
+
left <<= 1
|
456
|
+
left -= huffman_tree.count[len];
|
457
|
+
if left < 0 then return left end
|
458
|
+
end
|
459
|
+
|
460
|
+
offs[1] = 0
|
461
|
+
|
462
|
+
for len in (1..(MAXBITS-1))
|
463
|
+
offs[len+1] = offs[len] + huffman_tree.count[len]
|
464
|
+
end
|
465
|
+
|
466
|
+
for symbol in (0..n_symbols)
|
467
|
+
if lengths[symbol] != 0 then
|
468
|
+
huffman_tree.symbol[offs[lengths[symbol]]] = symbol
|
469
|
+
offs[lengths[symbol]] += 1
|
470
|
+
end
|
471
|
+
|
472
|
+
end
|
473
|
+
left
|
474
|
+
end
|
475
|
+
|
476
|
+
class HuffmanTree
|
477
|
+
attr_accessor :count, :symbol
|
478
|
+
def initialize
|
479
|
+
@count = []
|
480
|
+
@symbol = []
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
class << self
|
485
|
+
def inflate zstring
|
486
|
+
d = self.new
|
487
|
+
d.inflate zstring
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
class GzipFile
|
495
|
+
|
496
|
+
def initialize
|
497
|
+
@input_buffer = []
|
498
|
+
@output_buffer = []
|
499
|
+
@out_pos = -1
|
500
|
+
@in_pos = -1
|
501
|
+
end
|
502
|
+
|
503
|
+
def close
|
504
|
+
end
|
505
|
+
|
506
|
+
class Error < Exception
|
507
|
+
end
|
508
|
+
|
509
|
+
end
|
510
|
+
|
511
|
+
class GzipReader < GzipFile
|
512
|
+
OSES = ['FAT filesystem',
|
513
|
+
'Amiga',
|
514
|
+
'VMS (or OpenVMS)',
|
515
|
+
'Unix',
|
516
|
+
'VM/CMS',
|
517
|
+
'Atari TOS',
|
518
|
+
'HPFS fileystem (OS/2, NT)',
|
519
|
+
'Macintosh',
|
520
|
+
'Z-System',
|
521
|
+
'CP/M',
|
522
|
+
'TOPS-20',
|
523
|
+
'NTFS filesystem (NT)',
|
524
|
+
'QDOS',
|
525
|
+
'Acorn RISCOS',
|
526
|
+
'unknown']
|
527
|
+
|
528
|
+
def initialize io
|
529
|
+
|
530
|
+
#Add a helper method to check bits
|
531
|
+
::Fixnum.module_eval do
|
532
|
+
def isbitset? bit_to_check
|
533
|
+
if self & (2 ** bit_to_check) == (2 ** bit_to_check) then true else false end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
super()
|
538
|
+
@io = io
|
539
|
+
io.read.each_byte {|b| @input_buffer << b}
|
540
|
+
if @input_buffer[@in_pos+=1] != 0x1f || @input_buffer[@in_pos+=1] != 0x8b then raise Zlib::GzipFile::Error.new("not in gzip format") end
|
541
|
+
if @input_buffer[@in_pos+=1] != 0x08 then raise Zlib::GzipFile::Error.new("unknown compression method") end
|
542
|
+
flg = @input_buffer[@in_pos+=1]
|
543
|
+
@ftext = flg.isbitset? 0
|
544
|
+
@fhcrc = flg.isbitset? 1
|
545
|
+
@fextra = flg.isbitset? 2
|
546
|
+
@fname = flg.isbitset? 3
|
547
|
+
@fcomment = flg.isbitset? 4
|
548
|
+
@mtime = Time.at(@input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8) | (@input_buffer[@in_pos+=1] << 16) | (@input_buffer[@in_pos+=1] << 24))
|
549
|
+
@xfl = @input_buffer[@in_pos+=1]
|
550
|
+
@os = OSES[@input_buffer[@in_pos+=1]]
|
551
|
+
if @fextra then
|
552
|
+
@xlen = (@input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8))
|
553
|
+
@xtra_field = []
|
554
|
+
@xlen.times {@xtra_field << @input_buffer[@in_pos+=1]}
|
555
|
+
end
|
556
|
+
if @fname then
|
557
|
+
@original_name = ""
|
558
|
+
until @original_name["\0"].nil? == false
|
559
|
+
@original_name.concat(@input_buffer[@in_pos+=1])
|
560
|
+
end
|
561
|
+
@original_name.chop!
|
562
|
+
end
|
563
|
+
if @fcomment then
|
564
|
+
@comment = ""
|
565
|
+
until @comment["\0"].nil? == false
|
566
|
+
@comment.concat(@input_buffer[@in_pos+=1])
|
567
|
+
end
|
568
|
+
@comment.chop!
|
569
|
+
end
|
570
|
+
if @fhcrc then
|
571
|
+
@header_crc = @input_buffer[@in_pos+=1] | (@input_buffer[@in_pos+=1] << 8)
|
572
|
+
end
|
573
|
+
@contents = ""
|
574
|
+
until @in_pos == @input_buffer.length-1
|
575
|
+
@contents.concat(@input_buffer[@in_pos+=1])
|
576
|
+
end
|
577
|
+
|
578
|
+
#we do raw deflate, no headers
|
579
|
+
@zstream = Zlib::Inflate.new -MAX_WBITS
|
580
|
+
@inflated = StringIO.new(@zstream.inflate @contents)
|
581
|
+
|
582
|
+
end
|
583
|
+
|
584
|
+
def read length=nil
|
585
|
+
@inflated.read length
|
586
|
+
end
|
587
|
+
|
588
|
+
def eof?
|
589
|
+
@inflated.eof?
|
590
|
+
end
|
591
|
+
|
592
|
+
def pos
|
593
|
+
@inflated.pos
|
594
|
+
end
|
595
|
+
|
596
|
+
def rewind
|
597
|
+
@inflated.rewind
|
598
|
+
@io.seek 0, IO::SEEK_SET
|
599
|
+
end
|
600
|
+
|
601
|
+
class << self
|
602
|
+
|
603
|
+
def open filename
|
604
|
+
io = File.open filename, 'rb'
|
605
|
+
gz = self.new io
|
606
|
+
if block_given? then yield gz else gz end
|
607
|
+
end
|
608
|
+
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
|
613
|
+
#Generic Error
|
614
|
+
class Error < Exception
|
615
|
+
end
|
616
|
+
|
617
|
+
#Dictionary Needed
|
618
|
+
class NeedDict < Error
|
619
|
+
end
|
620
|
+
|
621
|
+
#Invalid Data
|
622
|
+
class DataError < Error
|
623
|
+
end
|
624
|
+
|
625
|
+
end
|
626
|
+
|
627
|
+
end
|
628
|
+
end
|