pbox 1.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/autocomplete/pbox_bash +1639 -0
- data/bin/pbox +37 -0
- data/conf/protonbox.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +178 -0
- data/features/deployments_feature.rb +127 -0
- data/features/domains_feature.rb +49 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +186 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +701 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +96 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +326 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +167 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/git_clone.rb +29 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +320 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +88 -0
- data/lib/rhc/exceptions.rb +232 -0
- data/lib/rhc/git_helpers.rb +91 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +477 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +332 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +154 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1024 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/ssh_helpers.rb +378 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +35 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +633 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +89 -0
- data/spec/direct_execution_helper.rb +338 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -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/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +188 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +754 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +145 -0
- data/spec/rhc/commands/cartridge_spec.rb +641 -0
- data/spec/rhc/commands/deployment_spec.rb +286 -0
- data/spec/rhc/commands/domain_spec.rb +383 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +80 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +228 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +524 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +248 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +435 -0
@@ -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
|