rubyzip 0.5.12 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

Files changed (43) hide show
  1. data/ChangeLog +151 -17
  2. data/NEWS +13 -0
  3. data/README +2 -0
  4. data/Rakefile +2 -3
  5. data/TODO +2 -3
  6. data/lib/download_quizzes.rb +119 -0
  7. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +205 -0
  8. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +111 -0
  9. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +111 -0
  10. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +301 -0
  11. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +268 -0
  12. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +132 -0
  13. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +13 -0
  14. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +230 -0
  15. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +24 -0
  16. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +30 -0
  17. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +19 -0
  18. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +31 -0
  19. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +66 -0
  20. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +17 -0
  21. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +2 -0
  22. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +204 -0
  23. data/lib/quiz1/t/solutions/Jim Menard/test.rb +47 -0
  24. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +97 -0
  25. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +140 -0
  26. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +14 -0
  27. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +68 -0
  28. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +146 -0
  29. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +38 -0
  30. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +5 -0
  31. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +27 -0
  32. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +151 -0
  33. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +198 -0
  34. data/lib/zip/ioextras.rb +17 -15
  35. data/lib/zip/zip.rb +394 -112
  36. data/lib/zip/zipfilesystem.rb +2 -2
  37. data/test/gentestfiles.rb +3 -1
  38. data/test/zipfilesystemtest.rb +2 -2
  39. data/test/ziptest.rb +34 -29
  40. metadata +35 -12
  41. data/samples/zipdialogui.rb +0 -80
  42. data/test/data/file2.txt.other +0 -0
  43. data/test/zlibtest.rb +0 -26
data/ChangeLog CHANGED
@@ -1,3 +1,101 @@
1
+ 2006-07-01 10:04 thomas
2
+
3
+ * Rakefile: Don't autorequire zip/zip - autorequire is deprecated.
4
+
5
+ 2006-06-30 09:28 thomas
6
+
7
+ * Rakefile: [no log message]
8
+
9
+ 2006-06-30 09:25 thomas
10
+
11
+ * NEWS, lib/zip/zip.rb: Bumped version number and reformatted NEWS
12
+ a bit.
13
+
14
+ 2006-06-29 22:49 technorama
15
+
16
+ * lib/zip/zip.rb, NEWS: documentation additions
17
+
18
+ 2006-04-30 06:25 technorama
19
+
20
+ * TODO, lib/zip/zip.rb, test/ziptest.rb: add documentation and test
21
+ for new ZipFile::extract
22
+
23
+ 2006-04-30 06:22 technorama
24
+
25
+ * lib/zip/zip.rb: add some of the API suggestions from sf.net
26
+ #1281314
27
+
28
+ 2006-04-30 05:55 technorama
29
+
30
+ * lib/zip/zip.rb: apply patch for bug #1446926
31
+
32
+ 2006-04-30 05:54 technorama
33
+
34
+ * lib/zip/zip.rb: apply patch for bug #1459902
35
+
36
+ 2006-04-26 17:17 technorama
37
+
38
+ * lib/zip/zip.rb: add ZipFile @restore_*, documentation update
39
+
40
+ 2006-04-07 21:13 technorama
41
+
42
+ * test/: gentestfiles.rb, zipfilesystemtest.rb, ziptest.rb:
43
+ additional tests
44
+
45
+ 2006-03-28 04:11 technorama
46
+
47
+ * lib/zip/zip.rb: start of unix_uid, unix_gid, restore_* support
48
+
49
+ 2006-03-28 03:49 technorama
50
+
51
+ * lib/zip/zip.rb: follow_symlinks is now optional
52
+
53
+ 2006-03-28 03:32 technorama
54
+
55
+ * lib/zip/zip.rb: add eof? methods
56
+
57
+ 2006-03-28 03:31 technorama
58
+
59
+ * test/ziptest.rb: eof? tests
60
+
61
+ 2006-02-26 09:57 technorama
62
+
63
+ * README: add to authors
64
+
65
+ 2006-02-26 09:56 technorama
66
+
67
+ * TODO: [no log message]
68
+
69
+ 2006-02-25 12:04 thomas
70
+
71
+ * lib/zip/zip.rb, test/ziptest.rb: Did away with ZipStreamableFile.
72
+
73
+ 2006-02-23 08:03 technorama
74
+
75
+ * lib/zip/zip.rb: unix file permissions. symlink support. rework
76
+ ZipEntry and delegate classes. reduce memory usage during
77
+ decompression.
78
+
79
+ 2006-02-22 23:44 technorama
80
+
81
+ * lib/zip/zipfilesystem.rb: update permissionInt for mkdir
82
+
83
+ 2006-02-04 10:42 thomas
84
+
85
+ * lib/zip/: ioextras.rb, zip.rb: Merged patch from oss-ruby.
86
+
87
+ 2005-11-19 16:17 thomas
88
+
89
+ * lib/zip/zip.rb: [no log message]
90
+
91
+ 2005-11-08 08:23 thomas
92
+
93
+ * lib/zip/ioextras.rb: Accepted patch from oss-ruby
94
+
95
+ 2005-10-07 09:54 thomas
96
+
97
+ * TODO: [no log message]
98
+
1
99
  2005-09-06 21:19 thomas
2
100
 
3
101
  * lib/zip/zip.rb: [no log message]
@@ -204,7 +302,9 @@
204
302
  test/data/file1.txt, test/data/file1.txt.deflatedData,
205
303
  test/data/file2.txt, test/data/notzippedruby.rb,
206
304
  test/data/rubycode.zip, test/data/rubycode2.zip,
207
- test/data/testDirectory.bin, test/data/zipWithDirs.zip: Changed
305
+ test/data/testDirectory.bin, test/data/zipWithDirs.zip,
306
+ zip/ioextras.rb, zip/stdrubyext.rb, zip/tempfile_bugfixed.rb,
307
+ zip/zip.rb, zip/zipfilesystem.rb, zip/ziprequire.rb: Changed
208
308
  directory structure
209
309
 
210
310
  2005-02-13 22:44 thomas
@@ -222,8 +322,8 @@
222
322
 
223
323
  2004-12-12 11:22 thomas
224
324
 
225
- * NEWS, TODO, samples/write_simple.rb: Fixed 'version needed to
226
- extract'-field wrong in local headers
325
+ * NEWS, TODO, samples/write_simple.rb, zip/zip.rb: Fixed 'version
326
+ needed to extract'-field wrong in local headers
227
327
 
228
328
  2004-05-02 15:17 thomas
229
329
 
@@ -231,7 +331,7 @@
231
331
 
232
332
  2004-04-02 07:25 thomas
233
333
 
234
- * NEWS: Fix for FreeBSD 4.9
334
+ * NEWS, zip/zip.rb: Fix for FreeBSD 4.9
235
335
 
236
336
  2004-03-29 00:28 thomas
237
337
 
@@ -241,29 +341,51 @@
241
341
 
242
342
  * NEWS: [no log message]
243
343
 
344
+ 2004-03-28 15:23 thomas
345
+
346
+ * zip/zip.rb: Use RUBY_VERSION not VERSION constant
347
+
348
+ 2004-03-28 14:51 thomas
349
+
350
+ * zip/zip.rb: Only use bugfixed Tempfile implementation if the ruby
351
+ version hasnt been fixed (contributed by Nobu Nakada)
352
+
353
+ 2004-03-28 14:46 thomas
354
+
355
+ * zip/tempfile_bugfixed.rb: Compatibility with DelegateClass in
356
+ ruby version 1.8.1 and newer
357
+
244
358
  2004-03-27 16:09 thomas
245
359
 
246
- * test/stdrubyexttest.rb: Patch for stdrubyext.rb from Nobu Nakada
360
+ * test/stdrubyexttest.rb, zip/stdrubyext.rb: Patch for
361
+ stdrubyext.rb from Nobu Nakada
362
+
363
+ 2004-03-27 15:52 thomas
364
+
365
+ * zip/: ioextras.rb, zip.rb, zipfilesystem.rb, ziprequire.rb: [no
366
+ log message]
247
367
 
248
368
  2004-03-27 15:30 thomas
249
369
 
250
- * test/: ioextrastest.rb, stdrubyexttest.rb: converted some files
251
- to unix line-endings
370
+ * test/ioextrastest.rb, test/stdrubyexttest.rb, zip/ioextras.rb:
371
+ converted some files to unix line-endings
252
372
 
253
373
  2004-03-25 16:34 thomas
254
374
 
255
- * NEWS, install.rb: Significantly reduced memory footprint when
256
- modifying zip files
375
+ * NEWS, install.rb, zip/tempfile_bugfixed.rb, zip/zip.rb:
376
+ Significantly reduced memory footprint when modifying zip files
257
377
 
258
378
  2004-03-16 18:20 thomas
259
379
 
260
380
  * install.rb, test/alltests.rb, test/ioextrastest.rb,
261
- test/stdrubyexttest.rb, test/ziptest.rb: IO utility classes moved
262
- to new file ioextras.rb. Tests moved to new file ioextrastest.rb
381
+ test/stdrubyexttest.rb, test/ziptest.rb, zip/ioextras.rb,
382
+ zip/zip.rb: IO utility classes moved to new file ioextras.rb.
383
+ Tests moved to new file ioextrastest.rb
263
384
 
264
385
  2004-02-27 13:21 thomas
265
386
 
266
- * NEWS: Optimization to avoid decompression and recompression
387
+ * NEWS, zip/zip.rb: Optimization to avoid decompression and
388
+ recompression
267
389
 
268
390
  2004-01-30 16:17 thomas
269
391
 
@@ -271,21 +393,31 @@
271
393
 
272
394
  2004-01-30 16:07 thomas
273
395
 
274
- * README, test/zipfilesystemtest.rb, test/ziptest.rb: Applied
396
+ * README, test/zipfilesystemtest.rb, test/ziptest.rb,
397
+ zip/stdrubyext.rb, zip/zip.rb, zip/zipfilesystem.rb: Applied
275
398
  extra-field patch
276
399
 
277
400
  2003-12-13 16:57 thomas
278
401
 
279
402
  * TODO: [no log message]
280
403
 
404
+ 2003-12-13 16:53 thomas
405
+
406
+ * zip/zip.rb: [no log message]
407
+
281
408
  2003-12-10 00:25 thomas
282
409
 
283
410
  * test/ziptest.rb: (Temporary) fix to bug reported by Takashi Sano
284
411
 
412
+ 2003-10-03 11:05 thomas
413
+
414
+ * zip/: stdrubyext.rb, zip.rb: Thanks to Clifford Heath for
415
+ noticing that Time.to_binary_dos_date and time were reversed
416
+
285
417
  2003-08-23 09:42 thomas
286
418
 
287
- * test/ziptest.rb, NEWS: Fixed ZipFile.get_ouput_stream bug - data
288
- was never written to zip
419
+ * test/ziptest.rb, zip/zip.rb, NEWS: Fixed ZipFile.get_ouput_stream
420
+ bug - data was never written to zip
289
421
 
290
422
  2003-08-21 16:05 thomas
291
423
 
@@ -305,8 +437,10 @@
305
437
  zipfilesystem.rb, zipfilesystemtest.rb, ziprequire.rb,
306
438
  ziprequiretest.rb, ziptest.rb, samples/example.rb,
307
439
  samples/example_filesystem.rb, samples/gtkRubyzip.rb,
308
- samples/zipfind.rb: Moved all production source files to zip/ so
309
- they are in the same dir as when they are installed
440
+ samples/zipfind.rb, zip/stdrubyext.rb, zip/zip.rb,
441
+ zip/zipfilesystem.rb, zip/ziprequire.rb: Moved all production
442
+ source files to zip/ so they are in the same dir as when they are
443
+ installed
310
444
 
311
445
  2003-08-21 15:31 thomas
312
446
 
data/NEWS CHANGED
@@ -1,3 +1,16 @@
1
+ = Version 0.9.1
2
+
3
+ Added symlink support and support for unix file permissions. Reduced
4
+ memory usage during decompression.
5
+
6
+ New methods ZipFile::[follow_symlinks, restore_times, restore_permissions, restore_ownership].
7
+ New methods ZipEntry::unix_perms, ZipInputStream::eof?.
8
+ Added documentation and test for new ZipFile::extract.
9
+ Added some of the API suggestions from sf.net #1281314.
10
+ Applied patch for sf.net bug #1446926.
11
+ Applied patch for sf.net bug #1459902.
12
+ Rework ZipEntry and delegate classes.
13
+
1
14
  = Version 0.5.12
2
15
 
3
16
  Fixed problem with writing binary content to a ZipFile in MS Windows.
data/README CHANGED
@@ -67,4 +67,6 @@ http://sourceforge.net/project/showfiles.php?group_id=43107&package_id=35377
67
67
 
68
68
  Thomas Sondergaard (thomas at sondergaard.cc)
69
69
 
70
+ Technorama Ltd. (oss-ruby-zip at technorama.net)
71
+
70
72
  extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)
data/Rakefile CHANGED
@@ -50,9 +50,8 @@ spec = Gem::Specification.new do |s|
50
50
  s.homepage = "http://rubyzip.sourceforge.net/"
51
51
  s.platform = Gem::Platform::RUBY
52
52
  s.summary = "rubyzip is a ruby module for reading and writing zip files"
53
- s.files = PKG_FILES.to_a #Dir.glob("{samples,lib,test,docs}/**/*").delete_if {|item| item.include?("CVS") || item.include?("rdoc") || item =~ /~$/ }
53
+ s.files = PKG_FILES.to_a
54
54
  s.require_path = 'lib'
55
- s.autorequire = 'zip/zip'
56
55
  end
57
56
 
58
57
  Rake::GemPackageTask.new(spec) do |pkg|
@@ -70,7 +69,7 @@ end
70
69
  desc "Publish documentation"
71
70
  task :pdoc => [:rdoc] do
72
71
  Rake::SshFreshDirPublisher.
73
- new("thomas@rubyzip.sourceforge.net", "rubyzip/htdocs", "html").upload
72
+ new("thomas@rubyzip.sourceforge.net", "/home/groups/r/ru/rubyzip/htdocs", "html").upload
74
73
  end
75
74
 
76
75
  desc "Publish package"
data/TODO CHANGED
@@ -1,12 +1,11 @@
1
1
 
2
+ * ZipInputStream: Support zip-files with trailing data descriptors
2
3
  * Adjust rdoc stylesheet to advertise inherited methods if possible
3
4
  * Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
4
5
  * Suggestion: ZipFile#extract destination should default to "."
5
6
  * Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
6
- * rename write to syswrite
7
- * provide alias for write -> syswrite in ioextras.rb
7
+ * SUggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
8
8
  * (is buffering used anywhere with write?)
9
- * produce_input should take an optional buffer parameter.
10
9
  * Inflater.sysread should pass the buffer to produce_input.
11
10
  * Implement ZipFsDir.glob
12
11
  * ZipFile.checkIntegrity method
@@ -0,0 +1,119 @@
1
+ #!/bin/env ruby
2
+
3
+ rubygems = false
4
+ begin
5
+ require 'rubygems'
6
+ rubygems = true
7
+ rescue LoadError
8
+ end
9
+
10
+ require 'open-uri'
11
+ require 'fileutils'
12
+
13
+ rubyzip = false
14
+ begin
15
+ require 'zip/zipfilesystem'
16
+ rubyzip = true
17
+ rescue LoadError
18
+ end
19
+
20
+
21
+ @address = "www.rubyquiz.com"
22
+ first = last = nil
23
+
24
+ first = ARGV[0].to_i if ARGV.size > 1
25
+ last = ARGV[1].to_i if ARGV.size > 2
26
+
27
+
28
+
29
+ #
30
+ # Download a binary file from the rubyquiz url
31
+ #
32
+ def download(file, todir = '.')
33
+ begin
34
+ puts "Downloading file #{file} from #{@address}"
35
+ c = open("http://#{@address}/#{file}").read
36
+ Dir.mkdir(todir) if not File.directory?(todir)
37
+ f = open("#{todir}/#{file}", 'wb')
38
+ f.puts c
39
+ f.close
40
+ rescue => e
41
+ if not File.exists?(fullfile)
42
+ $stderr.puts "Could not download file #{file} form #{@address}."
43
+ $stderr.puts e.to_s
44
+ end
45
+ end
46
+ end
47
+
48
+
49
+ #
50
+ # Unzip the file using GNU's stand-alone unzip utility.
51
+ #
52
+ def unzip_gnu(file)
53
+ puts `unzip -o #{file}`
54
+ end
55
+
56
+
57
+ #
58
+ # Unzip the file using rubyzip library.
59
+ #
60
+ def unzip(x)
61
+ outdir = x.sub(/.*\//, '')
62
+ outdir = '.' if outdir == ""
63
+ Zip::ZipFile::open(x) { |zf|
64
+ zf.each { |e|
65
+ fpath = File.join(outdir, e.name)
66
+ FileUtils.mkdir_p(File.dirname(fpath))
67
+ zf.extract(e, fpath)
68
+ }
69
+ }
70
+ end
71
+
72
+
73
+
74
+ def get_index
75
+ c = open("http://#{@address}/").read
76
+ quizzes = c.scan /quiz(\d+).html/
77
+ return [ quizzes[0][0], quizzes[-1][0] ]
78
+ end
79
+
80
+ if not first or not last
81
+ f, l = get_index()
82
+ last = l unless last
83
+ first = f unless first
84
+ end
85
+
86
+ first = first.to_i
87
+ last = last.to_i
88
+
89
+
90
+ puts "Downloading quizzess #{first} to #{last}"
91
+ quizzes = (first..last)
92
+ quizzes.each { |q|
93
+ dir = "quiz#{q}"
94
+
95
+ #### Download HTML description
96
+ file = "quiz#{q}.html"
97
+ fullfile = "#{dir}/#{file}"
98
+ if not File.exists?(fullfile)
99
+ download( file, dir )
100
+ end
101
+
102
+ #### Download zip file
103
+ file = "quiz#{q}_sols.zip"
104
+ fullfile = "#{dir}/#{file}"
105
+
106
+ if not File.exists?(fullfile)
107
+ download( file, dir )
108
+ end
109
+
110
+ # Unzip and remove .zip file
111
+ Dir.chdir dir
112
+ if rubyzip
113
+ unzip file
114
+ else
115
+ unzip_gnu file
116
+ end
117
+ FileUtils.rm file
118
+ Dir.chdir '..'
119
+ }
@@ -0,0 +1,205 @@
1
+ # bail if you have nothing to do.
2
+ unless ARGV[0]
3
+ print <<-STOP_PRINT
4
+ Encrypts/decrypts a string of text.
5
+ Usage: Give it some text!
6
+ STOP_PRINT
7
+ exit
8
+ end
9
+
10
+ # the obligatory deck of cards.
11
+ ###############################################################################
12
+ class Deck
13
+ attr_reader :cards, :order
14
+
15
+ def initialize
16
+ @cards = []
17
+ @order = []
18
+ build_deck
19
+ end
20
+
21
+ def to_s
22
+ return @cards.to_s
23
+ end
24
+
25
+ def build_deck
26
+ [:Clubs, :Diamonds, :Hearts, :Spades].each do |suit|
27
+ rank = 0
28
+ 'A23456789TJQK'.each_byte do |name|
29
+ # 'real' cards have a rank value
30
+ rank += 1
31
+ add_card(name.chr, suit, rank)
32
+ end
33
+ end
34
+
35
+ # Jokers have no rank value
36
+ 'AB'.each_byte {|name| add_card(name.chr, :Joker, 0)}
37
+ end
38
+
39
+ # build order while adding.
40
+ def add_card(name, suit, rank)
41
+ card = Card.new(name, suit, rank)
42
+ @cards << card
43
+ @order << card.to_s
44
+ end
45
+
46
+ # Uses order to hunt for cards (Joker searches).
47
+ def find_card(name, suit)
48
+ return @order.index(Card.to_s(name, suit))
49
+ end
50
+
51
+ # does as many cuts as you give it.
52
+ def cut_cards(cuts)
53
+ cards = []
54
+ loc = 0
55
+ [cuts].flatten.each_with_index do |cut, idx|
56
+ cards[idx] = @cards[loc...cut]
57
+ loc = cut
58
+ end
59
+ cards << @cards[loc...@cards.length]
60
+ end
61
+
62
+ def cards=(cards)
63
+ # flatten to handle cut results.
64
+ @cards = cards.flatten
65
+ # rebuild @order each time the deck changes.
66
+ update_order
67
+ end
68
+
69
+ # simple, but not very efficient.
70
+ def update_order
71
+ @order = @cards.collect {|card| card.to_s}
72
+ end
73
+
74
+ end
75
+
76
+ # the above deck is made up of...
77
+ ###############################################################################
78
+ class Card
79
+ @@SUITS = {
80
+ :Clubs => 0,
81
+ :Diamonds => 13,
82
+ :Hearts => 26,
83
+ :Spades => 39,
84
+ :Joker => 53
85
+ }
86
+
87
+ def self.to_s(name, suit)
88
+ return name + ' ' + suit.to_s + "\n"
89
+ end
90
+
91
+ attr_reader :name, :suit, :rank
92
+
93
+ def initialize(name, suit, rank)
94
+ @name = name
95
+ @suit = suit
96
+ @rank = rank + @@SUITS[suit]
97
+ end
98
+
99
+ def to_s
100
+ Card.to_s(@name, @suit)
101
+ end
102
+ end
103
+
104
+ ###############################################################################
105
+ class Solitaire
106
+
107
+ attr_reader :deck
108
+
109
+ def initialize(text)
110
+ @deck = Deck.new
111
+ @text = text.to_s
112
+ end
113
+
114
+ def process
115
+ # does it look encrypted? 5 letter blocks all uppercase?
116
+ looks_encrypted = @text.gsub(/[A-Z]{5}\s?/, '').empty?
117
+ results = ''
118
+
119
+ # prep the text for parsing.
120
+ if looks_encrypted
121
+ # strip off the blanks for consistency
122
+ text = @text.gsub(/\s/, '')
123
+ else
124
+ # Discard any non A to Z characters, and uppercase all remaining
125
+ text = @text.upcase.gsub!(/[^A-Z]/, '')
126
+ # Split the message into five character groups,
127
+ words, padding = word_count(text, 5)
128
+ # using Xs to pad the last group
129
+ text += padding
130
+ end
131
+
132
+ # parse it, and build up results.
133
+ text.each_byte do |char|
134
+ if looks_encrypted
135
+ char -= next_key
136
+ char += 26 if char < 65
137
+ else
138
+ char += next_key
139
+ char -= 26 if char > 90
140
+ end
141
+ results += char.chr
142
+ end
143
+
144
+ return space_text(results, 5)
145
+ end
146
+
147
+ # counts words as 5 char blocks
148
+ def word_count(text, len)
149
+ words, strays = text.length.divmod(len)
150
+ words += 1 if strays > 0
151
+ pad = "X" * (len - strays)
152
+ return [words, pad]
153
+ end
154
+
155
+ def space_text(text, len)
156
+ # adds a space every 5 letters.
157
+ # not sure how efficient this is.
158
+ return text.unpack(('A' + len.to_s) * word_count(text, len)[0]).join(' ')
159
+ end
160
+
161
+ def shift_card(name, suit, count)
162
+ # find the card
163
+ idx = @deck.find_card(name, suit)
164
+ # remove it from the deck.
165
+ card = @deck.cards.slice!(idx)
166
+ # calculate new placement.
167
+ idx += count
168
+ # the slice above makes length 'look' zero-based
169
+ idx -= @deck.cards.length if idx > @deck.cards.length
170
+
171
+ # glue the deck together as cards before, card, cards after.
172
+ @deck.cards = @deck.cards[0...idx] + [card] +
173
+ @deck.cards[idx...@deck.cards.length]
174
+ end
175
+
176
+ def next_key
177
+ shift_card('A', :Joker, 1)
178
+ shift_card('B', :Joker, 2)
179
+
180
+ # find the 2 jokers, and sort them for the cut.
181
+ jokers = [@deck.find_card('A', :Joker), @deck.find_card('B', :Joker)].sort
182
+ # increment the 2nd joker pos -- cut uses 'up to, but not including'
183
+ jokers[1] += 1
184
+ # reverse works nicely for the triple cut.
185
+ @deck.cards = @deck.cut_cards(jokers).reverse
186
+
187
+ # get the value from the last card, and cut up to it.
188
+ cuts = @deck.cut_cards([@deck.cards.last.rank, @deck.cards.length - 1])
189
+ @deck.cards = cuts[1] + cuts[0] + cuts[2]
190
+
191
+ # read top card value, count down that many cards + 1
192
+ key = @deck.cards[@deck.cards[0].rank].rank
193
+ # convert it to a letter, adjust if needed.
194
+ key -= 26 if key > 26
195
+
196
+ # if key is still > 26, then it's a joker!
197
+ return (key) unless key > 26
198
+ # try again if it's a joker!
199
+ next_key
200
+ end
201
+ end
202
+
203
+ test = Solitaire.new(ARGV[0])
204
+ puts test.process
205
+ puts test.deck