archive-zip 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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