rubyzip 0.9.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +354 -0
- data/Rakefile +15 -104
- data/TODO +0 -1
- data/lib/zip/central_directory.rb +212 -0
- data/lib/zip/compressor.rb +9 -0
- data/lib/zip/constants.rb +115 -0
- data/lib/zip/crypto/decrypted_io.rb +40 -0
- data/lib/zip/crypto/encryption.rb +11 -0
- data/lib/zip/crypto/null_encryption.rb +43 -0
- data/lib/zip/crypto/traditional_encryption.rb +99 -0
- data/lib/zip/decompressor.rb +31 -0
- data/lib/zip/deflater.rb +34 -0
- data/lib/zip/dos_time.rb +53 -0
- data/lib/zip/entry.rb +719 -0
- data/lib/zip/entry_set.rb +88 -0
- data/lib/zip/errors.rb +19 -0
- data/lib/zip/extra_field/generic.rb +44 -0
- data/lib/zip/extra_field/ntfs.rb +94 -0
- data/lib/zip/extra_field/old_unix.rb +46 -0
- data/lib/zip/extra_field/universal_time.rb +77 -0
- data/lib/zip/extra_field/unix.rb +39 -0
- data/lib/zip/extra_field/zip64.rb +70 -0
- data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
- data/lib/zip/extra_field.rb +103 -0
- data/lib/zip/file.rb +468 -0
- data/lib/zip/filesystem.rb +643 -0
- data/lib/zip/inflater.rb +54 -0
- data/lib/zip/input_stream.rb +180 -0
- data/lib/zip/ioextras/abstract_input_stream.rb +122 -0
- data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
- data/lib/zip/ioextras.rb +21 -140
- data/lib/zip/null_compressor.rb +15 -0
- data/lib/zip/null_decompressor.rb +19 -0
- data/lib/zip/null_input_stream.rb +10 -0
- data/lib/zip/output_stream.rb +198 -0
- data/lib/zip/pass_thru_compressor.rb +23 -0
- data/lib/zip/pass_thru_decompressor.rb +31 -0
- data/lib/zip/streamable_directory.rb +15 -0
- data/lib/zip/streamable_stream.rb +52 -0
- data/lib/zip/version.rb +3 -0
- data/lib/zip.rb +72 -0
- data/samples/example.rb +44 -32
- data/samples/example_filesystem.rb +16 -19
- data/samples/example_recursive.rb +54 -0
- data/samples/gtk_ruby_zip.rb +84 -0
- data/samples/qtzip.rb +25 -34
- data/samples/write_simple.rb +10 -13
- data/samples/zipfind.rb +38 -45
- metadata +182 -91
- data/ChangeLog +0 -1504
- data/NEWS +0 -144
- data/README +0 -72
- data/install.rb +0 -22
- data/lib/download_quizzes.rb +0 -119
- data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +0 -205
- data/lib/quiz1/t/solutions/Carlos/solitaire.rb +0 -111
- data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +0 -111
- data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +0 -301
- data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +0 -268
- data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +0 -132
- data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +0 -13
- data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +0 -230
- data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +0 -24
- data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +0 -30
- data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +0 -19
- data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +0 -31
- data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +0 -66
- data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +0 -17
- data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +0 -2
- data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +0 -204
- data/lib/quiz1/t/solutions/Jim Menard/test.rb +0 -47
- data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +0 -97
- data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +0 -140
- data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +0 -14
- data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +0 -68
- data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +0 -146
- data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +0 -38
- data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +0 -5
- data/lib/quiz1/t/solutions/Moses Hohman/util.rb +0 -27
- data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +0 -151
- data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +0 -198
- data/lib/zip/stdrubyext.rb +0 -111
- data/lib/zip/tempfile_bugfixed.rb +0 -195
- data/lib/zip/zip.rb +0 -1847
- data/lib/zip/zipfilesystem.rb +0 -609
- data/lib/zip/ziprequire.rb +0 -90
- data/samples/gtkRubyzip.rb +0 -86
- data/test/alltests.rb +0 -9
- data/test/data/file1.txt +0 -46
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +0 -1504
- data/test/data/notzippedruby.rb +0 -7
- data/test/data/rubycode.zip +0 -0
- data/test/data/rubycode2.zip +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/gentestfiles.rb +0 -157
- data/test/ioextrastest.rb +0 -208
- data/test/stdrubyexttest.rb +0 -52
- data/test/zipfilesystemtest.rb +0 -831
- data/test/ziprequiretest.rb +0 -43
- data/test/ziptest.rb +0 -1599
@@ -1,38 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'test/unit'
|
3
|
-
require 'util'
|
4
|
-
|
5
|
-
class TestArray < Test::Unit::TestCase
|
6
|
-
def test_peel_all_arrays_same_length
|
7
|
-
tuples = []
|
8
|
-
a1 = [1,3,5]
|
9
|
-
a2 = [2,4,6]
|
10
|
-
a3 = [1,4,9]
|
11
|
-
[a1, a2, a3].peel { |x,y,z| tuples << [x,y,z] }
|
12
|
-
assert_equal([[1,2,1],[3,4,4],[5,6,9]], tuples)
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_peel_one_array_shorter
|
16
|
-
tuples = []
|
17
|
-
a1 = [1,3,5]
|
18
|
-
a2 = [2,4]
|
19
|
-
a3 = [1,4,9]
|
20
|
-
[a1, a2, a3].peel { |x,y,z| tuples << [x,y,z] }
|
21
|
-
assert_equal([[1,2,1],[3,4,4]], tuples)
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_collect_peel
|
25
|
-
a1 = [1,3,5]
|
26
|
-
a2 = [2,4,6]
|
27
|
-
assert_equal([3,7,11], [a1, a2].collect_peel { |a,b| a+b })
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class TestFixnum < Test::Unit::TestCase
|
32
|
-
def test_offset_mod
|
33
|
-
assert_equal(1, 27.offset_mod(26), "27 wrong")
|
34
|
-
assert_equal(26, 26.offset_mod(26), "26 wrong")
|
35
|
-
assert_equal(26, 0.offset_mod(26), "0 wrong")
|
36
|
-
assert_equal(25, -1.offset_mod(26), "-1 wrong")
|
37
|
-
end
|
38
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
class Array
|
4
|
-
# "Peels" off a tuple of the elements at each successive index across multiple arrays.
|
5
|
-
# Assumes self is an array of these multiple arrays. Stops when any of the arrays is
|
6
|
-
# exhausted. I stole this from a ruby mailing list somewhere. I also considered calling this each_tuple
|
7
|
-
def peel(&p)
|
8
|
-
collect { |a|
|
9
|
-
a.length
|
10
|
-
}.min.times { |i|
|
11
|
-
yield collect { |a| a[i] }
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
# syntactic sugar for Cipher
|
16
|
-
def collect_peel(&p)
|
17
|
-
collected = []
|
18
|
-
peel { |a,b| collected << p.call(a,b) }
|
19
|
-
collected
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Fixnum
|
24
|
-
def offset_mod(base)
|
25
|
-
((self-1)%base)+1
|
26
|
-
end
|
27
|
-
end
|
@@ -1,151 +0,0 @@
|
|
1
|
-
def succ?(*a)
|
2
|
-
begin
|
3
|
-
(0..(a.size-2)).each {|i| return false if a[i].succ != a[i+1]}
|
4
|
-
return true
|
5
|
-
rescue
|
6
|
-
return false
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Deck
|
11
|
-
def initialize
|
12
|
-
@deck = (1..52).to_a + [:A, :B]
|
13
|
-
end
|
14
|
-
|
15
|
-
def move_a
|
16
|
-
move_down(@deck.index(:A))
|
17
|
-
end
|
18
|
-
|
19
|
-
def move_b
|
20
|
-
move_down(move_down(@deck.index(:B)))
|
21
|
-
end
|
22
|
-
|
23
|
-
def move_down(index)
|
24
|
-
if index < 53
|
25
|
-
new = index + 1
|
26
|
-
@deck[new], @deck[index] = @deck[index], @deck[new]
|
27
|
-
else
|
28
|
-
@deck = @deck[0,1] + @deck[-1,1] + @deck[1..-2]
|
29
|
-
new = 1
|
30
|
-
end
|
31
|
-
return new
|
32
|
-
end
|
33
|
-
|
34
|
-
def triple_cut
|
35
|
-
jokers = [@deck.index(:A), @deck.index(:B)]
|
36
|
-
top, bottom = jokers.min, jokers.max
|
37
|
-
@deck = @deck[(bottom+1)..-1] + @deck[top..bottom] + @deck[0...top]
|
38
|
-
end
|
39
|
-
|
40
|
-
def number_value(x)
|
41
|
-
return 53 if x == :A or x == :B
|
42
|
-
return x
|
43
|
-
end
|
44
|
-
|
45
|
-
def count_cut
|
46
|
-
count = number_value( @deck[-1] )
|
47
|
-
@deck = @deck[count..-2] + @deck[0,count] + @deck[-1,1]
|
48
|
-
end
|
49
|
-
|
50
|
-
def output
|
51
|
-
return @deck[ number_value(@deck[0]) ]
|
52
|
-
end
|
53
|
-
|
54
|
-
def update
|
55
|
-
move_a
|
56
|
-
move_b
|
57
|
-
triple_cut
|
58
|
-
count_cut
|
59
|
-
end
|
60
|
-
|
61
|
-
def get
|
62
|
-
while true
|
63
|
-
update
|
64
|
-
c = output
|
65
|
-
if c != :A and c != :B
|
66
|
-
letter = ( ((c-1) % 26) + 65 ).chr
|
67
|
-
return letter
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def to_s
|
73
|
-
a = []
|
74
|
-
@deck.each_index {|i|
|
75
|
-
if succ?(a[-1], @deck[i], @deck[i+1])
|
76
|
-
a << "..."
|
77
|
-
elsif a[-1] == "..." and succ?(@deck[i-1], @deck[i], @deck[i+1])
|
78
|
-
# nop
|
79
|
-
else
|
80
|
-
a << @deck[i]
|
81
|
-
end
|
82
|
-
}
|
83
|
-
return a.join(" ")
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
class Encrypter
|
88
|
-
def initialize(keystream)
|
89
|
-
@keystream = keystream
|
90
|
-
end
|
91
|
-
|
92
|
-
def sanitize(s)
|
93
|
-
s = s.upcase
|
94
|
-
s = s.gsub(/[^A-Z]/, "")
|
95
|
-
s = s + "X" * ((5 - s.size % 5) % 5)
|
96
|
-
out = ""
|
97
|
-
(s.size / 5).times {|i| out << s[i*5,5] << " "}
|
98
|
-
return out
|
99
|
-
end
|
100
|
-
|
101
|
-
def mod(c)
|
102
|
-
return c - 26 if c > 26
|
103
|
-
return c + 26 if c < 1
|
104
|
-
return c
|
105
|
-
end
|
106
|
-
|
107
|
-
def process(s, &combiner)
|
108
|
-
s = sanitize(s)
|
109
|
-
out = ""
|
110
|
-
s.each_byte { |c|
|
111
|
-
if c >= ?A and c <= ?Z
|
112
|
-
key = @keystream.get
|
113
|
-
res = combiner.call(c, key[0])
|
114
|
-
out << res.chr
|
115
|
-
else
|
116
|
-
out << c.chr
|
117
|
-
end
|
118
|
-
}
|
119
|
-
return out
|
120
|
-
end
|
121
|
-
|
122
|
-
def encrypt(s)
|
123
|
-
return process(s) {|c, key| 64 + mod(c + key - 128)}
|
124
|
-
end
|
125
|
-
|
126
|
-
def decrypt(s)
|
127
|
-
return process(s) {|c, key| 64 + mod(c -key)}
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
|
132
|
-
def test
|
133
|
-
d = Deck.new()
|
134
|
-
d.update
|
135
|
-
puts d
|
136
|
-
|
137
|
-
e = Encrypter.new( Deck.new() )
|
138
|
-
cipher = e.encrypt('Code in Ruby, live longer!')
|
139
|
-
puts cipher
|
140
|
-
|
141
|
-
e = Encrypter.new( Deck.new() )
|
142
|
-
puts e.decrypt(cipher)
|
143
|
-
|
144
|
-
e = Encrypter.new( Deck.new() )
|
145
|
-
puts e.decrypt("CLEPK HHNIY CFPWH FDFEH")
|
146
|
-
|
147
|
-
e = Encrypter.new( Deck.new() )
|
148
|
-
puts e.decrypt("ABVAW LWZSY OORYK DUPVH")
|
149
|
-
end
|
150
|
-
|
151
|
-
test()
|
@@ -1,198 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'optparse'
|
4
|
-
require 'ostruct'
|
5
|
-
|
6
|
-
# Handles the deck
|
7
|
-
class Deck
|
8
|
-
|
9
|
-
# Initializes the deck with the default values
|
10
|
-
def initialize
|
11
|
-
@deck = (1..52).to_a << 'A' << 'B'
|
12
|
-
end
|
13
|
-
|
14
|
-
# Operation "move a" (step 2)
|
15
|
-
def move_A
|
16
|
-
move_down( @deck.index( 'A' ) )
|
17
|
-
end
|
18
|
-
|
19
|
-
# Operation "move b" (step 3)
|
20
|
-
def move_B
|
21
|
-
2.times { move_down( @deck.index( 'B' ) ) }
|
22
|
-
end
|
23
|
-
|
24
|
-
# Operation "triple cut" (step 4)
|
25
|
-
def triple_cut
|
26
|
-
a = @deck.index( 'A' )
|
27
|
-
b = @deck.index( 'B' )
|
28
|
-
a, b = b, a if a > b
|
29
|
-
@deck.replace( [@deck[(b + 1)..-1], @deck[a..b], @deck[0...a]].flatten )
|
30
|
-
end
|
31
|
-
|
32
|
-
# Operation "count cut" (step 5)
|
33
|
-
def count_cut
|
34
|
-
temp = @deck[0..(@deck[-1] - 1)]
|
35
|
-
@deck[0..(@deck[-1] - 1)] = []
|
36
|
-
@deck[-1..-1] = [temp, @deck[-1]].flatten
|
37
|
-
end
|
38
|
-
|
39
|
-
# Operation "output the found letter" (step 6)
|
40
|
-
def output_letter
|
41
|
-
a = @deck.first
|
42
|
-
a = 53 if a.instance_of? String
|
43
|
-
output = @deck[a]
|
44
|
-
if output.instance_of? String
|
45
|
-
nil
|
46
|
-
else
|
47
|
-
output -= 26 if output > 26
|
48
|
-
(output + 64).chr
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Shuffle the deck using the initialization number +init+ and the method +method+.
|
53
|
-
# Currently there are only two methods: <tt>:fisher_yates</tt> and <tt>naive</tt>.
|
54
|
-
def shuffle( init, method = :fisher_yates )
|
55
|
-
srand( init )
|
56
|
-
self.send( method.id2name + "_shuffle", @deck )
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
# From pleac.sf.net
|
62
|
-
def fisher_yates_shuffle( a )
|
63
|
-
(a.size-1).downto(0) { |i|
|
64
|
-
j = rand(i+1)
|
65
|
-
a[i], a[j] = a[j], a[i] if i != j
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
# From pleac.sf.net
|
70
|
-
def naive_shuffle( a )
|
71
|
-
for i in 0...a.size
|
72
|
-
j = rand(a.size)
|
73
|
-
a[i], a[j] = a[j], a[i]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Moves the index one place down while treating the used array as circular list.
|
78
|
-
def move_down( index )
|
79
|
-
if index == @deck.length - 1
|
80
|
-
@deck[1..1] = @deck[index], @deck[1]
|
81
|
-
@deck.pop
|
82
|
-
else
|
83
|
-
@deck[index], @deck[index + 1] = @deck[index + 1], @deck[index]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
# Implements the Solitaire Cipher algorithm
|
91
|
-
class SolitaireCipher
|
92
|
-
|
93
|
-
# Initialize the deck
|
94
|
-
def initialize( init = -1, method = :fisher_yates )
|
95
|
-
@deck = Deck.new
|
96
|
-
@deck.shuffle( init, method ) unless init == -1
|
97
|
-
end
|
98
|
-
|
99
|
-
# Decodes the given +msg+ using the internal deck
|
100
|
-
def decode( msg )
|
101
|
-
msgNumbers = to_numbers( msg )
|
102
|
-
cipherNumbers = to_numbers( generate_keystream( msg.length ) )
|
103
|
-
|
104
|
-
resultNumbers = []
|
105
|
-
msgNumbers.each_with_index do |item, index|
|
106
|
-
item += 26 if item <= cipherNumbers[index]
|
107
|
-
temp = item - cipherNumbers[index]
|
108
|
-
resultNumbers << temp
|
109
|
-
end
|
110
|
-
|
111
|
-
return to_chars( resultNumbers )
|
112
|
-
end
|
113
|
-
|
114
|
-
# Encodes the given +msg+ using the internal deck
|
115
|
-
def encode( msg )
|
116
|
-
msg = msg.gsub(/[^A-Za-z]/, '').upcase
|
117
|
-
msg += "X"*(5 - (msg.length % 5)) unless msg.length % 5 == 0
|
118
|
-
|
119
|
-
msgNumbers = to_numbers( msg )
|
120
|
-
cipherNumbers = to_numbers( generate_keystream( msg.length ) )
|
121
|
-
|
122
|
-
resultNumbers = []
|
123
|
-
msgNumbers.each_with_index do |item, index|
|
124
|
-
temp = item + cipherNumbers[index]
|
125
|
-
temp = temp - 26 if temp > 26
|
126
|
-
resultNumbers << temp
|
127
|
-
end
|
128
|
-
|
129
|
-
return to_chars( resultNumbers )
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
|
134
|
-
# Converts the string of uppercase letters into numbers (A=1, B=2, ...)
|
135
|
-
def to_numbers( chars )
|
136
|
-
chars.unpack("C*").collect {|x| x - 64}
|
137
|
-
end
|
138
|
-
|
139
|
-
# Converts the array of numbers to a string (1=A, 2=B, ...)
|
140
|
-
def to_chars( numbers )
|
141
|
-
numbers.collect {|x| x + 64}.pack("C*")
|
142
|
-
end
|
143
|
-
|
144
|
-
# Generates a keystream for the given +length+.
|
145
|
-
def generate_keystream( length )
|
146
|
-
deck = @deck.dup
|
147
|
-
result = []
|
148
|
-
while result.length != length
|
149
|
-
deck.move_A
|
150
|
-
deck.move_B
|
151
|
-
deck.triple_cut
|
152
|
-
deck.count_cut
|
153
|
-
letter = deck.output_letter
|
154
|
-
result << letter unless letter.nil?
|
155
|
-
end
|
156
|
-
result.join
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
options = OpenStruct.new
|
163
|
-
options.key = -1
|
164
|
-
options.shuffle = :fisher_yates
|
165
|
-
options.call_method = :decode
|
166
|
-
|
167
|
-
opts = OptionParser.new do |opts|
|
168
|
-
opts.banner = "Usage: #{File.basename($0, '.*')} [options] message"
|
169
|
-
opts.separator ""
|
170
|
-
opts.separator "Options:"
|
171
|
-
opts.on( "-d", "--decode", "Decode the message" ) do
|
172
|
-
options.call_method = :decode
|
173
|
-
end
|
174
|
-
opts.on( "-e", "--encode", "Encode the message" ) do
|
175
|
-
options.call_method = :encode
|
176
|
-
end
|
177
|
-
opts.on( "-k", "--key KEY", Integer, "Key for shuffling the deck" ) do |key|
|
178
|
-
options.key = key
|
179
|
-
end
|
180
|
-
opts.on( "-m", "--method METHOD", [:fisher_yates, :naive],
|
181
|
-
"Select the shuffling method (fisher_yates, naive" ) do |method|
|
182
|
-
options.shuffle = method
|
183
|
-
end
|
184
|
-
opts.on( "-h", "--help", "Show help" ) do
|
185
|
-
puts opts
|
186
|
-
exit
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
|
191
|
-
if ARGV.length == 0
|
192
|
-
puts opts
|
193
|
-
exit
|
194
|
-
end
|
195
|
-
|
196
|
-
message = opts.permute!( ARGV )[0]
|
197
|
-
cipher = SolitaireCipher.new( options.key, options.shuffle )
|
198
|
-
puts cipher.send( options.call_method, message )
|
data/lib/zip/stdrubyext.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
unless Enumerable.method_defined?(:inject)
|
2
|
-
module Enumerable #:nodoc:all
|
3
|
-
def inject(n = 0)
|
4
|
-
each { |value| n = yield(n, value) }
|
5
|
-
n
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
module Enumerable #:nodoc:all
|
11
|
-
# returns a new array of all the return values not equal to nil
|
12
|
-
# This implementation could be faster
|
13
|
-
def select_map(&aProc)
|
14
|
-
map(&aProc).reject { |e| e.nil? }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
unless Object.method_defined?(:object_id)
|
19
|
-
class Object #:nodoc:all
|
20
|
-
# Using object_id which is the new thing, so we need
|
21
|
-
# to make that work in versions prior to 1.8.0
|
22
|
-
alias object_id id
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
unless File.respond_to?(:read)
|
27
|
-
class File # :nodoc:all
|
28
|
-
# singleton method read does not exist in 1.6.x
|
29
|
-
def self.read(fileName)
|
30
|
-
open(fileName) { |f| f.read }
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class String #:nodoc:all
|
36
|
-
def starts_with(aString)
|
37
|
-
rindex(aString, 0) == 0
|
38
|
-
end
|
39
|
-
|
40
|
-
def ends_with(aString)
|
41
|
-
index(aString, -aString.size)
|
42
|
-
end
|
43
|
-
|
44
|
-
def ensure_end(aString)
|
45
|
-
ends_with(aString) ? self : self + aString
|
46
|
-
end
|
47
|
-
|
48
|
-
def lchop
|
49
|
-
slice(1, length)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class Time #:nodoc:all
|
54
|
-
|
55
|
-
#MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
|
56
|
-
#
|
57
|
-
# Register CX, the Time:
|
58
|
-
# Bits 0-4 2 second increments (0-29)
|
59
|
-
# Bits 5-10 minutes (0-59)
|
60
|
-
# bits 11-15 hours (0-24)
|
61
|
-
#
|
62
|
-
# Register DX, the Date:
|
63
|
-
# Bits 0-4 day (1-31)
|
64
|
-
# bits 5-8 month (1-12)
|
65
|
-
# bits 9-15 year (four digit year minus 1980)
|
66
|
-
|
67
|
-
|
68
|
-
def to_binary_dos_time
|
69
|
-
(sec/2) +
|
70
|
-
(min << 5) +
|
71
|
-
(hour << 11)
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_binary_dos_date
|
75
|
-
(day) +
|
76
|
-
(month << 5) +
|
77
|
-
((year - 1980) << 9)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Dos time is only stored with two seconds accuracy
|
81
|
-
def dos_equals(other)
|
82
|
-
to_i/2 == other.to_i/2
|
83
|
-
end
|
84
|
-
|
85
|
-
def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
|
86
|
-
second = 2 * ( 0b11111 & binaryDosTime)
|
87
|
-
minute = ( 0b11111100000 & binaryDosTime) >> 5
|
88
|
-
hour = (0b1111100000000000 & binaryDosTime) >> 11
|
89
|
-
day = ( 0b11111 & binaryDosDate)
|
90
|
-
month = ( 0b111100000 & binaryDosDate) >> 5
|
91
|
-
year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
|
92
|
-
begin
|
93
|
-
return Time.local(year, month, day, hour, minute, second)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
class Module #:nodoc:all
|
99
|
-
def forward_message(forwarder, *messagesToForward)
|
100
|
-
methodDefs = messagesToForward.map {
|
101
|
-
|msg|
|
102
|
-
"def #{msg}; #{forwarder}(:#{msg}); end"
|
103
|
-
}
|
104
|
-
module_eval(methodDefs.join("\n"))
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
110
|
-
# rubyzip is free software; you can redistribute it and/or
|
111
|
-
# modify it under the terms of the ruby license.
|