archive-zip 0.3.0 → 0.4.0

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.
Files changed (132) hide show
  1. data/HACKING +25 -42
  2. data/NEWS +25 -0
  3. data/README +2 -2
  4. data/Rakefile +202 -0
  5. data/TODO +5 -0
  6. data/default.mspec +8 -0
  7. data/lib/archive/support/binary_stringio.rb +23 -0
  8. data/lib/archive/support/integer.rb +13 -0
  9. data/lib/archive/support/io-like.rb +3 -1
  10. data/lib/archive/support/ioextensions.rb +16 -0
  11. data/lib/archive/support/iowindow.rb +10 -18
  12. data/lib/archive/support/time.rb +2 -0
  13. data/lib/archive/support/zlib.rb +298 -71
  14. data/lib/archive/zip.rb +161 -139
  15. data/lib/archive/zip/codec.rb +2 -0
  16. data/lib/archive/zip/codec/deflate.rb +59 -11
  17. data/lib/archive/zip/codec/null_encryption.rb +75 -14
  18. data/lib/archive/zip/codec/store.rb +75 -26
  19. data/lib/archive/zip/codec/traditional_encryption.rb +146 -35
  20. data/lib/archive/zip/data_descriptor.rb +6 -4
  21. data/lib/archive/zip/entry.rb +184 -132
  22. data/lib/archive/zip/error.rb +2 -0
  23. data/lib/archive/zip/extra_field.rb +20 -6
  24. data/lib/archive/zip/extra_field/extended_timestamp.rb +141 -60
  25. data/lib/archive/zip/extra_field/raw.rb +70 -12
  26. data/lib/archive/zip/extra_field/unix.rb +58 -16
  27. data/lib/archive/zip/version.rb +6 -0
  28. data/spec/archive/zip/codec/deflate/compress/checksum_spec.rb +42 -0
  29. data/spec/archive/zip/codec/deflate/compress/close_spec.rb +44 -0
  30. data/spec/archive/zip/codec/deflate/compress/crc32_spec.rb +21 -0
  31. data/spec/archive/zip/codec/deflate/compress/data_descriptor_spec.rb +67 -0
  32. data/spec/archive/zip/codec/deflate/compress/new_spec.rb +37 -0
  33. data/spec/archive/zip/codec/deflate/compress/open_spec.rb +46 -0
  34. data/spec/archive/zip/codec/deflate/compress/write_spec.rb +109 -0
  35. data/spec/archive/zip/codec/deflate/decompress/checksum_spec.rb +18 -0
  36. data/spec/archive/zip/codec/deflate/decompress/close_spec.rb +33 -0
  37. data/spec/archive/zip/codec/deflate/decompress/crc32_spec.rb +18 -0
  38. data/spec/archive/zip/codec/deflate/decompress/data_descriptor_spec.rb +67 -0
  39. data/spec/archive/zip/codec/deflate/decompress/new_spec.rb +14 -0
  40. data/spec/archive/zip/codec/deflate/decompress/open_spec.rb +27 -0
  41. data/spec/archive/zip/codec/deflate/fixtures/classes.rb +25 -0
  42. data/spec/archive/zip/codec/deflate/fixtures/compressed_file.bin +1 -0
  43. data/spec/archive/zip/codec/deflate/fixtures/compressed_file_nocomp.bin +0 -0
  44. data/spec/archive/zip/codec/deflate/fixtures/raw_file.txt +10 -0
  45. data/spec/archive/zip/codec/null_encryption/decrypt/close_spec.rb +33 -0
  46. data/spec/archive/zip/codec/null_encryption/decrypt/new_spec.rb +14 -0
  47. data/spec/archive/zip/codec/null_encryption/decrypt/open_spec.rb +27 -0
  48. data/spec/archive/zip/codec/null_encryption/decrypt/read_spec.rb +24 -0
  49. data/spec/archive/zip/codec/null_encryption/decrypt/rewind_spec.rb +25 -0
  50. data/spec/archive/zip/codec/null_encryption/decrypt/seek_spec.rb +57 -0
  51. data/spec/archive/zip/codec/null_encryption/decrypt/tell_spec.rb +21 -0
  52. data/spec/archive/zip/codec/null_encryption/encrypt/close_spec.rb +33 -0
  53. data/spec/archive/zip/codec/null_encryption/encrypt/new_spec.rb +14 -0
  54. data/spec/archive/zip/codec/null_encryption/encrypt/open_spec.rb +27 -0
  55. data/spec/archive/zip/codec/null_encryption/encrypt/rewind_spec.rb +26 -0
  56. data/spec/archive/zip/codec/null_encryption/encrypt/seek_spec.rb +50 -0
  57. data/spec/archive/zip/codec/null_encryption/encrypt/tell_spec.rb +29 -0
  58. data/spec/archive/zip/codec/null_encryption/encrypt/write_spec.rb +29 -0
  59. data/spec/archive/zip/codec/null_encryption/fixtures/classes.rb +12 -0
  60. data/spec/archive/zip/codec/null_encryption/fixtures/raw_file.txt +10 -0
  61. data/spec/archive/zip/codec/store/compress/close_spec.rb +33 -0
  62. data/spec/archive/zip/codec/store/compress/data_descriptor_spec.rb +68 -0
  63. data/spec/archive/zip/codec/store/compress/new_spec.rb +14 -0
  64. data/spec/archive/zip/codec/store/compress/open_spec.rb +27 -0
  65. data/spec/archive/zip/codec/store/compress/rewind_spec.rb +26 -0
  66. data/spec/archive/zip/codec/store/compress/seek_spec.rb +50 -0
  67. data/spec/archive/zip/codec/store/compress/tell_spec.rb +29 -0
  68. data/spec/archive/zip/codec/store/compress/write_spec.rb +29 -0
  69. data/spec/archive/zip/codec/store/decompress/close_spec.rb +33 -0
  70. data/spec/archive/zip/codec/store/decompress/data_descriptor_spec.rb +68 -0
  71. data/spec/archive/zip/codec/store/decompress/new_spec.rb +14 -0
  72. data/spec/archive/zip/codec/store/decompress/open_spec.rb +27 -0
  73. data/spec/archive/zip/codec/store/decompress/read_spec.rb +24 -0
  74. data/spec/archive/zip/codec/store/decompress/rewind_spec.rb +25 -0
  75. data/spec/archive/zip/codec/store/decompress/seek_spec.rb +57 -0
  76. data/spec/archive/zip/codec/store/decompress/tell_spec.rb +21 -0
  77. data/spec/archive/zip/codec/store/fixtures/classes.rb +12 -0
  78. data/spec/archive/zip/codec/store/fixtures/raw_file.txt +10 -0
  79. data/spec/archive/zip/codec/traditional_encryption/decrypt/close_spec.rb +64 -0
  80. data/spec/archive/zip/codec/traditional_encryption/decrypt/new_spec.rb +18 -0
  81. data/spec/archive/zip/codec/traditional_encryption/decrypt/open_spec.rb +39 -0
  82. data/spec/archive/zip/codec/traditional_encryption/decrypt/read_spec.rb +126 -0
  83. data/spec/archive/zip/codec/traditional_encryption/decrypt/rewind_spec.rb +38 -0
  84. data/spec/archive/zip/codec/traditional_encryption/decrypt/seek_spec.rb +82 -0
  85. data/spec/archive/zip/codec/traditional_encryption/decrypt/tell_spec.rb +25 -0
  86. data/spec/archive/zip/codec/traditional_encryption/encrypt/close_spec.rb +64 -0
  87. data/spec/archive/zip/codec/traditional_encryption/encrypt/new_spec.rb +18 -0
  88. data/spec/archive/zip/codec/traditional_encryption/encrypt/open_spec.rb +39 -0
  89. data/spec/archive/zip/codec/traditional_encryption/encrypt/rewind_spec.rb +41 -0
  90. data/spec/archive/zip/codec/traditional_encryption/encrypt/seek_spec.rb +75 -0
  91. data/spec/archive/zip/codec/traditional_encryption/encrypt/tell_spec.rb +42 -0
  92. data/spec/archive/zip/codec/traditional_encryption/encrypt/write_spec.rb +127 -0
  93. data/spec/archive/zip/codec/traditional_encryption/fixtures/classes.rb +27 -0
  94. data/spec/archive/zip/codec/traditional_encryption/fixtures/encrypted_file.bin +0 -0
  95. data/spec/archive/zip/codec/traditional_encryption/fixtures/raw_file.txt +10 -0
  96. data/spec/binary_stringio/new_spec.rb +34 -0
  97. data/spec/binary_stringio/set_encoding_spec.rb +14 -0
  98. data/spec/ioextensions/read_exactly_spec.rb +50 -0
  99. data/spec/zlib/fixtures/classes.rb +65 -0
  100. data/spec/zlib/fixtures/compressed_file.bin +1 -0
  101. data/spec/zlib/fixtures/compressed_file_gzip.bin +0 -0
  102. data/spec/zlib/fixtures/compressed_file_huffman.bin +2 -0
  103. data/spec/zlib/fixtures/compressed_file_minmem.bin +0 -0
  104. data/spec/zlib/fixtures/compressed_file_minwin.bin +1 -0
  105. data/spec/zlib/fixtures/compressed_file_nocomp.bin +0 -0
  106. data/spec/zlib/fixtures/compressed_file_raw.bin +1 -0
  107. data/spec/zlib/fixtures/raw_file.txt +10 -0
  108. data/spec/zlib/zreader/checksum_spec.rb +40 -0
  109. data/spec/zlib/zreader/close_spec.rb +14 -0
  110. data/spec/zlib/zreader/compressed_size_spec.rb +18 -0
  111. data/spec/zlib/zreader/new_spec.rb +41 -0
  112. data/spec/zlib/zreader/open_spec.rb +49 -0
  113. data/spec/zlib/zreader/read_spec.rb +47 -0
  114. data/spec/zlib/zreader/rewind_spec.rb +23 -0
  115. data/spec/zlib/zreader/seek_spec.rb +55 -0
  116. data/spec/zlib/zreader/tell_spec.rb +21 -0
  117. data/spec/zlib/zreader/uncompressed_size_spec.rb +18 -0
  118. data/spec/zlib/zwriter/checksum_spec.rb +41 -0
  119. data/spec/zlib/zwriter/close_spec.rb +14 -0
  120. data/spec/zlib/zwriter/compressed_size_spec.rb +19 -0
  121. data/spec/zlib/zwriter/new_spec.rb +64 -0
  122. data/spec/zlib/zwriter/open_spec.rb +68 -0
  123. data/spec/zlib/zwriter/rewind_spec.rb +26 -0
  124. data/spec/zlib/zwriter/seek_spec.rb +54 -0
  125. data/spec/zlib/zwriter/tell_spec.rb +29 -0
  126. data/spec/zlib/zwriter/uncompressed_size_spec.rb +19 -0
  127. data/spec/zlib/zwriter/write_spec.rb +28 -0
  128. data/spec_helper.rb +49 -0
  129. metadata +296 -74
  130. data/MANIFEST +0 -27
  131. data/lib/archive/support/io.rb +0 -14
  132. data/lib/archive/support/stringio.rb +0 -22
data/HACKING CHANGED
@@ -12,14 +12,15 @@ some cases, but such cases will be rare.
12
12
  === Runtime
13
13
 
14
14
  * Ruby 1.8.6 or greater
15
+ * io-like 0.3.0 or greater
15
16
 
16
17
 
17
18
  === Build
18
19
 
19
- * rubygems 0.9.0 or greater
20
- * rake 0.8.1 or greater
21
- * allison 2.0.3 (optional - used for documentation only, if available)
22
- * rsync (optional - used for publishing documentation)
20
+ * rubygems 1.8.8 or greater
21
+ * rake 0.9.2 or greater
22
+ * rdoc 3.9.2 or greater
23
+ * mspec 1.5.17 or greater
23
24
 
24
25
 
25
26
  === Install
@@ -82,41 +83,23 @@ be more easily accepted if they are consistent with the rest of the code.
82
83
  code
83
84
 
84
85
 
85
- == Generating Patches
86
-
87
- Patches should usually be generated against the <em>HEAD</em> revision of the
88
- <em>master</em> branch. When generating patches, please try to implement only
89
- a single feature or bug fix per patch. Documentation describing a patch should
90
- be included along with the patch so that the maintainer can more easily
91
- determine whether or not a patch is acceptable. Patches lacking the necessary
92
- documentation will be ignored.
93
-
94
- Patches will be much more readily accepted if test cases are provided which
95
- verify correct operation. Such test cases should be provided within the patch
96
- rather than as a separate patch. Proper documentation, especially for
97
- user-visible APIs, is highly prized; providing accurate and detailed
98
- documentation, often in the form of rubydocs, throughout new code contributions
99
- will also increase the desirability of a patch.
100
-
101
- If a series of patches is generated which cannot be applied individually, make
102
- sure to mention the dependency relationships in whatever medium is being used
103
- to distribute the patches. For instance, if a bug is discovered while
104
- implementing a new feature, create a patch which fixes the bug followed by a
105
- separate patch adding the feature. If the feature patch requires the bug fix
106
- patch in order to work, note that dependency in the comments for the feature
107
- patch by somehow referencing the bug fix patch.
108
-
109
- The patch generation process in general:
110
- $ git clone git://rubyforge.org/archive-zip.git # Clone the repo and check out
111
- # the master branch.
112
- $ cd archive-zip # Enter the workspace.
113
- (make and test changes)
114
- $ git add file1 file2 .. # Add new/modified files.
115
- $ git commit # Commit changes.
116
- $ git format-patch -C HEAD^ # Create a patch for the last
117
- # commit.
118
-
119
- Repeat as necessary until all patches are generated. Then either attach them to
120
- 1 or more email messages addressed to the maintainer or attach them to tickets
121
- in the issue tracker for the project. Remember to include a brief description
122
- of the patch and its dependencies, if any.
86
+ == Contributing Code
87
+
88
+ Making a contribution is pretty simple. Fork the project on Github
89
+ (http://github.com/javanthropus/archive-zip), make your changes, and submit a
90
+ pull request. Requests that meet the following criteria will be the most
91
+ readily accepted:
92
+
93
+ 1. Each pull request should target an individual issue and should introduce
94
+ relatively few commits.
95
+ 2. Individual commits need to be small, easily digestible units.
96
+ 3. Good descriptions of the changes introduced should be included in each commit
97
+ message.
98
+ 4. Interdependencies on existing pull requests need to be noted in the pull
99
+ request.
100
+ 5. New test cases are a major plus.
101
+ 6. Documentation for new classes, methods, etc. is also a win.
102
+ 7. The coding style of the project should be respected.
103
+
104
+ In other words, the less work necessary to bring your changes into the project,
105
+ the faster you can expect them to be pulled.
data/NEWS CHANGED
@@ -6,6 +6,31 @@ detailed information is available in the rest of the documentation.
6
6
  <b>NOTE:</b> Date stamps in the following entries are in YYYY/MM/DD format.
7
7
 
8
8
 
9
+ == v0.4.0 (2011/??/??)
10
+
11
+ === Features
12
+
13
+ * Added Ruby 1.9 support.
14
+ * Simplified arguments for Archive::Zip.new.
15
+ * Archives cannot be directly opened for modification.
16
+ * Archive::Zip.archive can still emulate modifying an archive in place.
17
+ * Added a bunch of tests (many more still needed).
18
+ * Updated and simplified rake tasks.
19
+ * Created a standalone gemspec file.
20
+
21
+ === Fixes
22
+
23
+ * Fixed a potential data loss bug in Zlib::ZReader.
24
+ * Archives larger than the maximum Fixnum for the platform don't falsely raise a
25
+ "non-integer windows position given" error.
26
+
27
+ === Notes
28
+
29
+ * Broke backward compatibility for Archive::Zip.new.
30
+ * Wrapper class methods continue to work as before.
31
+ * Broke backward compatibility for Archive::Zip::ExtraField.
32
+ * Allows separate handling of extra fields in central and local records.
33
+
9
34
  == v0.3.0 (2009/01/23)
10
35
 
11
36
  * Made a significant performance improvement for the extraction of compressed
data/README CHANGED
@@ -12,7 +12,7 @@ supported with a moderate amount of effort.
12
12
 
13
13
  == License
14
14
 
15
- Copyright © 2008 Jeremy Bopp <jeremy at bopp dot net>
15
+ Copyright © 2010 Jeremy Bopp <jeremy at bopp dot net>
16
16
 
17
17
  Licensed under the same terms as Ruby -- See the included LICENSE file for
18
18
  details
@@ -76,7 +76,7 @@ Create a few archives:
76
76
  # Create a new archive which will be written to a pipe.
77
77
  # Assume $stdout is the write end a pipe.
78
78
  # (ruby example.rb | cat >example.zip)
79
- Archive::Zip.open(nil, $stdout) do |z|
79
+ Archive::Zip.open($stdout, :w) do |z|
80
80
  z.archive('a_directory')
81
81
  end
82
82
 
data/Rakefile ADDED
@@ -0,0 +1,202 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rubygems'
4
+ gem 'rdoc'
5
+
6
+ require 'rubygems/package_task'
7
+ require 'rake/clean'
8
+ require 'rdoc/task'
9
+
10
+ # The path to the version.rb file and a string to eval to find the version.
11
+ VERSION_RB = 'lib/archive/zip/version.rb'
12
+ VERSION_REF = 'Archive::Zip::VERSION'
13
+
14
+ # Load the gemspec file for this project.
15
+ GEMSPEC = 'archive-zip.gemspec'
16
+ SPEC = eval(File.read(GEMSPEC), nil, GEMSPEC)
17
+
18
+ # Returns the value of the VERSION environment variable as a Gem::Version object
19
+ # assuming it is set and a valid Gem version string. Otherwise, raises an
20
+ # exception.
21
+ def get_version_argument
22
+ version = ENV['VERSION']
23
+ if version.nil? || version.empty?
24
+ raise "No version specified: Add VERSION=... to the command line"
25
+ end
26
+ begin
27
+ Gem::Version.create(version.dup)
28
+ rescue ArgumentError
29
+ raise "Invalid version specified in `VERSION=#{version}'"
30
+ end
31
+ end
32
+
33
+ # Performs an in place, per line edit of the file indicated by _path_ by calling
34
+ # the sub method on each line and passing _pattern_, _replacement_, and _b_ as
35
+ # arguments.
36
+ def file_sub(path, pattern, replacement = nil, &b)
37
+ tmp_path = "#{path}.tmp"
38
+ File.open(path) do |infile|
39
+ File.open(tmp_path, 'w') do |outfile|
40
+ infile.each do |line|
41
+ outfile.write(line.sub(pattern, replacement, &b))
42
+ end
43
+ end
44
+ end
45
+ File.rename(tmp_path, path)
46
+ end
47
+
48
+ # Updates the version string in the gemspec file and a version.rb file it to the
49
+ # string in _version_.
50
+ def set_version(version)
51
+ file_sub(GEMSPEC, /(\.version\s*=\s*).*/, "\\1\"#{version}\"")
52
+ file_sub(VERSION_RB, /^(\s*VERSION\s*=\s*).*/, "\\1\"#{version}\"")
53
+ end
54
+
55
+ # A dynamically generated list of files that should match the manifest (the
56
+ # combined contents of SPEC.files and SPEC.test_files). The idea is for this
57
+ # list to contain all project files except for those that have been explicitly
58
+ # excluded. This list will be compared with the manifest from the SPEC in order
59
+ # to help catch the addition or removal of files to or from the project that
60
+ # have not been accounted for either by an exclusion here or an inclusion in the
61
+ # SPEC manifest.
62
+ #
63
+ # NOTE:
64
+ # It is critical that the manifest is *not* automatically generated via globbing
65
+ # and the like; otherwise, this will yield a simple comparison between
66
+ # redundantly generated lists of files that probably will not protect the
67
+ # project from the unintentional inclusion or exclusion of files in the
68
+ # distribution.
69
+ PKG_FILES = FileList.new('**/*', '**/.[^.][^.]*') do |files|
70
+ # Exclude the gemspec file.
71
+ files.exclude('*.gemspec')
72
+ # Exclude anything that doesn't exist and directories.
73
+ files.exclude {|file| ! File.exist?(file) || File.directory?(file)}
74
+ # Exclude Vim swap files.
75
+ files.exclude('**/.*.sw?')
76
+ # Exclude Git administrative files and directories.
77
+ files.exclude(%r{(^|[/\\])\.git(ignore|modules)?([/\\]|$)})
78
+
79
+ # Exclude the top level pkg, doc, and examples directories and their contents.
80
+ files.exclude(%r{^(pkg|doc|examples)([/\\]|$)})
81
+ end
82
+
83
+ # Make sure that :clean and :clobber will not whack the repository files.
84
+ CLEAN.exclude('.git/**')
85
+ # Vim swap files are fair game for clean up.
86
+ CLEAN.include('**/.*.sw?')
87
+
88
+ desc 'Alias for build:gem'
89
+ task :build => 'build:gem'
90
+
91
+ # Build related tasks.
92
+ namespace :build do
93
+ # Create the gem and package tasks.
94
+ Gem::PackageTask.new(SPEC).define
95
+
96
+ # Ensure that the manifest is consulted after building the gem. Any
97
+ # generated/compiled files should be available at that time.
98
+ task :gem => :check_manifest
99
+
100
+ desc 'Verify the manifest'
101
+ task :check_manifest do
102
+ manifest_files = (SPEC.files + SPEC.test_files).sort.uniq
103
+ pkg_files = PKG_FILES.sort.uniq
104
+ if manifest_files != pkg_files then
105
+ common_files = manifest_files & pkg_files
106
+ manifest_files -= common_files
107
+ pkg_files -= common_files
108
+ message = ["The manifest does not match the automatic file list."]
109
+ unless manifest_files.empty? then
110
+ message << " Extraneous files:\n " + manifest_files.join("\n ")
111
+ end
112
+ unless pkg_files.empty?
113
+ message << " Missing files:\n " + pkg_files.join("\n ")
114
+ end
115
+ raise message.join("\n")
116
+ end
117
+ end
118
+ end
119
+
120
+ # Ensure that the clobber task also clobbers package files.
121
+ task :clobber => 'build:clobber_package'
122
+
123
+ # Create the rdoc task.
124
+ RDoc::Task.new do |rdoc|
125
+ rdoc.rdoc_dir = 'doc'
126
+ rdoc.title = 'Archive::Zip Documentation'
127
+ rdoc.rdoc_files = SPEC.files - SPEC.test_files
128
+ rdoc.main = 'README'
129
+ end
130
+
131
+ # Gem related tasks.
132
+ namespace :gem do
133
+ desc 'Alias for build:gem'
134
+ task :build => 'build:gem'
135
+
136
+ desc 'Publish the gemfile'
137
+ task :publish => ['version:check', :test, 'repo:tag', :build] do
138
+ sh "gem push pkg/#{SPEC.name}-#{SPEC.version}*.gem"
139
+ end
140
+ end
141
+
142
+ desc 'Run tests'
143
+ task :test do
144
+ sh "mspec"
145
+ end
146
+
147
+ # Version string management tasks.
148
+ namespace :version do
149
+ desc 'Set the version for the project to a specified version'
150
+ task :set do
151
+ set_version(get_version_argument)
152
+ end
153
+
154
+ desc 'Set the version for the project back to 0.0.0'
155
+ task :reset do
156
+ set_version('0.0.0')
157
+ end
158
+
159
+ desc 'Checks that all version strings are correctly set'
160
+ task :check do
161
+ version = get_version_argument
162
+ if version != SPEC.version
163
+ raise "The given version `#{version}' does not match the gemspec version `#{SPEC.version}'"
164
+ end
165
+
166
+ begin
167
+ load VERSION_RB
168
+ internal_version = Gem::Version.create(eval(VERSION_REF))
169
+ if version != internal_version
170
+ raise "The given version `#{version}' does not match the version.rb version `#{internal_version}'"
171
+ end
172
+ rescue ArgumentError
173
+ raise "Invalid version specified in `#{VERSION_RB}'"
174
+ end
175
+
176
+ begin
177
+ File.open('NEWS') do |news|
178
+ unless news.lines.any? {|l| l =~ /^== v#{Regexp.escape(version.to_s)} /}
179
+ raise "The NEWS file does not mention version `#{version}'"
180
+ end
181
+ end
182
+ rescue Errno::ENOENT
183
+ raise 'No NEWS file found'
184
+ end
185
+ end
186
+ end
187
+
188
+ # Repository and workspace management tasks.
189
+ namespace :repo do
190
+ desc 'Tag the current HEAD with the version string'
191
+ task :tag => :check_workspace do
192
+ version = get_version_argument
193
+ sh "git tag -s -m 'Release v#{version}' v#{version}"
194
+ end
195
+
196
+ desc 'Ensure the workspace is fully committed and clean'
197
+ task :check_workspace do
198
+ unless `git status --untracked-files=all --porcelain`.empty?
199
+ raise 'Workspace has been modified. Commit pending changes and try again.'
200
+ end
201
+ end
202
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ = Future work items (in no particular order):
2
+
3
+ * Add test cases for all classes.
4
+ * Add support for using non-seekable IO objects as archive sources.
5
+ * Add support for 0x5855 and 0x7855 extra fields.
data/default.mspec ADDED
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+ class MSpecScript
3
+ # An ordered list of the directories containing specs to run
4
+ set :files, ['spec']
5
+
6
+ # The default implementation to run the specs.
7
+ set :target, 'ruby'
8
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'stringio'
4
+
5
+ # This class is a version of StringIO that always uses the binary encoding on
6
+ # any Ruby platform that has a notion of encodings. On Ruby platforms without
7
+ # encoding support, this class is equivalent to StringIO.
8
+ class BinaryStringIO < StringIO
9
+ # Creates a new instance of this class.
10
+ #
11
+ # This takes all the arguments of StringIO.new.
12
+ def initialize(*args)
13
+ super
14
+
15
+ # Force a binary encoding when possible.
16
+ if respond_to?(:set_encoding, true)
17
+ set_encoding('binary')
18
+ end
19
+ end
20
+
21
+ # Hide #set_encoding so that the encoding cannot be changed later.
22
+ private :set_encoding if instance_methods.include?(:set_encoding)
23
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ class Integer
4
+ unless public_method_defined?('ord') then
5
+ # Returns the int itself.
6
+ #
7
+ # This method is defined here only if not already defined elsewhere, such as
8
+ # versions of Ruby prior to 1.8.7.
9
+ def ord
10
+ self
11
+ end
12
+ end
13
+ end
@@ -1,8 +1,10 @@
1
+ # encoding: UTF-8
2
+
1
3
  # Try to first load io-like from rubygems and then fall back to assuming a
2
4
  # standard installation.
3
5
  begin
4
6
  require 'rubygems'
5
- gem 'io-like', '>= 0.1.0'
7
+ gem 'io-like', '>= 0.3.0'
6
8
  rescue LoadError
7
9
  # Failed to load via rubygems.
8
10
  end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ # IOExtensions provides convenience wrappers for certain IO functionality.
4
+ module IOExtensions
5
+ # Reads and returns exactly _length_ bytes from _io_ using the read method on
6
+ # _io_. If there is insufficient data available, an EOFError is raised.
7
+ def self.read_exactly(io, length, buffer = '')
8
+ buffer.slice!(0..-1) unless buffer.empty?
9
+ while buffer.size < length do
10
+ internal = io.read(length - buffer.size)
11
+ raise EOFError, 'unexpected end of file' if internal.nil?
12
+ buffer << internal
13
+ end
14
+ buffer
15
+ end
16
+ end
@@ -1,7 +1,9 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'archive/support/io-like'
2
4
 
3
- # IOWindow represents an IO object which wraps another one allowing read access
4
- # to a subset of the data within the stream.
5
+ # IOWindow represents an IO object which wraps another one allowing read and/or
6
+ # write access to a subset of the data within the stream.
5
7
  #
6
8
  # <b>NOTE:</b> This object is NOT thread safe.
7
9
  class IOWindow
@@ -15,8 +17,6 @@ class IOWindow
15
17
  # must be an integer greater than or equal to 0. _window_size_ must be an
16
18
  # integer greater than or equal to 0.
17
19
  def initialize(io, window_position, window_size)
18
- raise ArgumentError, 'non-seekable IO object given' unless io.seekable?
19
-
20
20
  @io = io
21
21
  @unbuffered_pos = 0
22
22
  self.window_position = window_position
@@ -29,9 +29,10 @@ class IOWindow
29
29
  # Set the file position at which this window begins.
30
30
  # _window_position_ must be an integer greater than or equal to 0.
31
31
  def window_position=(window_position)
32
- unless window_position.kind_of?(Fixnum) then
33
- raise ArgumentError, 'non-integer window position given'
32
+ unless window_position.respond_to?(:to_int) then
33
+ raise TypeError, "can't convert #{window_position.class} into Integer"
34
34
  end
35
+ window_position = window_position.to_int
35
36
  if window_position < 0 then
36
37
  raise ArgumentError, 'non-positive window position given'
37
38
  end
@@ -45,9 +46,10 @@ class IOWindow
45
46
  # Set the size of the window.
46
47
  # _window_size_ must be an integer greater than or equal to 0.
47
48
  def window_size=(window_size)
48
- unless window_size.kind_of?(Fixnum) then
49
- raise ArgumentError, 'non-integer window size given'
49
+ unless window_size.respond_to?(:to_int) then
50
+ raise TypeError, "can't convert #{window_size.class} into Integer"
50
51
  end
52
+ window_size = window_size.to_int
51
53
  raise ArgumentError, 'non-positive window size given' if window_size < 0
52
54
 
53
55
  @window_size = window_size
@@ -95,16 +97,6 @@ class IOWindow
95
97
  @unbuffered_pos = new_pos
96
98
  end
97
99
 
98
- def unbuffered_write(string)
99
- restore_self
100
-
101
- # Ensure that the outputted string will not extend past the window.
102
- string = string.slice(0, @window_size - @unbuffered_pos)
103
- @io.write(string)
104
- ensure
105
- restore_delegate
106
- end
107
-
108
100
  # Restores the state of the delegate IO object to that saved by a prior call
109
101
  # to #restore_self.
110
102
  def restore_delegate