Skip to content

Commit 27569df

Browse files
committed
No unnecessary strings on POSIX header creation
The POSIX header creation methods created a new 512-byte string of NULL bytes just to see if the header was an empty header. This could be simplified with a single 512-byte constant string for comparison, but a short-circuiting comparison will be more efficient over-all. Use the #each_byte enumerator with the #any? test method on #nonzero? (data.each_byte.any?(&:nonzero?)).
1 parent a485f96 commit 27569df

File tree

8 files changed

+188
-144
lines changed

8 files changed

+188
-144
lines changed

.travis.yml

-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ rvm:
1212
- ree
1313
- ruby-head
1414
- jruby-19mode
15-
- jruby-head
1615
matrix:
1716
allow_failures:
18-
- rvm: jruby-head
1917
- rvm: ruby-head
2018
- rvm: 1.8.7
2119
- rvm: ree

Gemfile

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
# -*- ruby -*-
22

33
# NOTE: This file is present to keep Travis CI happy. Edits to it will not
4-
# be accepted.
4+
# be accepted, except to remove all of this crap later.
55

66
source 'https://rubygems.org/'
77

88
mime_version =
99
if RUBY_VERSION < '1.9'
10+
gem 'rdoc', '< 4.0'
11+
# gem 'ruby-debug'
1012
'1.25'
1113
elsif RUBY_VERSION < '2.0'
14+
# gem 'debugger' if RUBY_ENGINE == 'ruby'
1215
'2.0'
13-
else
16+
elsif RUBY_VERSION >= '2.0'
17+
if RUBY_ENGINE == 'ruby'
18+
# gem 'byebug'
19+
gem 'simplecov', '~> 0.7'
20+
gem 'coveralls', '~> 0.7'
21+
end
1422
'3.0'
1523
end
1624

1725
gem 'mime-types', "~> #{mime_version}"
1826

19-
if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
20-
gem 'byebug'
21-
gem 'simplecov', '~> 0.7'
22-
gem 'coveralls', '~> 0.7'
23-
end
24-
2527
gemspec :name => 'minitar'
2628

2729
# vim: syntax=ruby

Manifest.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ lib/archive/tar/minitar/reader.rb
1616
lib/archive/tar/minitar/writer.rb
1717
lib/minitar.rb
1818
test/minitest_helper.rb
19+
test/support/tar_test_helpers.rb
1920
test/test_tar_header.rb
2021
test/test_tar_input.rb
2122
test/test_tar_output.rb

Rakefile

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ spec = Hoe.spec 'minitar' do
2828
extra_dev_deps << ['minitest', '~> 5.3']
2929
extra_dev_deps << ['minitest-autotest', ['>= 1.0.b', '<2']]
3030
extra_dev_deps << ['rake', '~> 10.0']
31+
extra_dev_deps << ['rdoc', '>= 0.0']
3132
end
3233

3334
if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'

lib/archive/tar/minitar/posix_header.rb

+7-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ module Archive::Tar::Minitar; end
3232
# POSIX indicates that "A POSIX-compliant implementation must treat any
3333
# unrecognized typeflag value as a regular file."
3434
class Archive::Tar::Minitar::PosixHeader
35+
BLOCK_SIZE = 512
36+
3537
# Fields that must be set in a POSIX tar(1) header.
3638
REQUIRED_FIELDS = [ :name, :size, :prefix, :mode ].freeze
3739
# Fields that may be set in a POSIX tar(1) header.
@@ -46,7 +48,7 @@ class Archive::Tar::Minitar::PosixHeader
4648
FIELDS.each { |f| attr_reader f.to_sym unless f.to_sym == :name }
4749

4850
# The name of the file. By default, limited to 100 bytes. Required. May be
49-
# longer (up to 512 bytes) if using the GNU long name tar extension.
51+
# longer (up to BLOCK_SIZE bytes) if using the GNU long name tar extension.
5052
attr_accessor :name
5153

5254
# The pack format passed to Array#pack for encoding a header.
@@ -57,7 +59,7 @@ class Archive::Tar::Minitar::PosixHeader
5759
class << self
5860
# Creates a new PosixHeader from a data stream.
5961
def from_stream(stream)
60-
from_data(stream.read(512))
62+
from_data(stream.read(BLOCK_SIZE))
6163
end
6264

6365
# Creates a new PosixHeader from a data stream. Deprecated; use
@@ -67,7 +69,7 @@ def new_from_stream(stream)
6769
from_stream(stream)
6870
end
6971

70-
# Creates a new PosixHeader from a 512-byte data buffer.
72+
# Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
7173
def from_data(data)
7274
fields = data.unpack(HEADER_UNPACK_FORMAT)
7375
name = fields.shift
@@ -87,7 +89,7 @@ def from_data(data)
8789
devminor = fields.shift.oct
8890
prefix = fields.shift
8991

90-
empty = (data == "\0" * 512)
92+
empty = !data.each_byte.any?(&:nonzero?)
9193

9294
new(
9395
:name => name,
@@ -171,7 +173,7 @@ def header(chksum)
171173
oct(mtime, 11), chksum, " ", typeflag, linkname, magic, version,
172174
uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
173175
str = arr.pack(HEADER_PACK_FORMAT)
174-
str + "\0" * ((512 - str.size) % 512)
176+
str + "\0" * ((BLOCK_SIZE - str.size) % BLOCK_SIZE)
175177
end
176178

177179
##

minitar.gemspec

+45-45
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,60 @@
22
# stub: minitar 0.6 ruby lib
33

44
Gem::Specification.new do |s|
5-
s.name = "minitar".freeze
5+
s.name = "minitar"
66
s.version = "0.6"
77

8-
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9-
s.require_paths = ["lib".freeze]
10-
s.authors = ["Austin Ziegler".freeze]
11-
s.date = "2016-11-04"
12-
s.description = "The minitar library is a pure-Ruby library that provides the ability to deal\nwith POSIX tar(1) archive files.\n\nThis is release 0.6, \u{2026}\n\nminitar (previously called Archive::Tar::Minitar) is based heavily on code\noriginally written by Mauricio Julio Fern\u{e1}ndez Pradier for the rpa-base\nproject.".freeze
13-
s.email = ["[email protected]".freeze]
14-
s.extra_rdoc_files = ["Contributing.md".freeze, "History.md".freeze, "Licence.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "docs/bsdl.txt".freeze, "docs/ruby.txt".freeze]
15-
s.files = ["Contributing.md".freeze, "History.md".freeze, "Licence.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "docs/bsdl.txt".freeze, "docs/ruby.txt".freeze, "lib/archive-tar-minitar.rb".freeze, "lib/archive/tar/minitar.rb".freeze, "lib/archive/tar/minitar/input.rb".freeze, "lib/archive/tar/minitar/output.rb".freeze, "lib/archive/tar/minitar/posix_header.rb".freeze, "lib/archive/tar/minitar/reader.rb".freeze, "lib/archive/tar/minitar/writer.rb".freeze, "lib/minitar.rb".freeze, "test/minitest_helper.rb".freeze, "test/test_tar_header.rb".freeze, "test/test_tar_input.rb".freeze, "test/test_tar_output.rb".freeze, "test/test_tar_reader.rb".freeze, "test/test_tar_writer.rb".freeze]
16-
s.homepage = "https://github.com/halostatue/minitar/".freeze
17-
s.licenses = ["Ruby".freeze, "BSD-2-Clause".freeze]
18-
s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]
19-
s.required_ruby_version = Gem::Requirement.new(">= 1.8".freeze)
20-
s.rubygems_version = "2.6.6".freeze
21-
s.summary = "The minitar library is a pure-Ruby library that provides the ability to deal with POSIX tar(1) archive files".freeze
8+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9+
s.require_paths = ["lib"]
10+
s.authors = ["Austin Ziegler"]
11+
s.date = "2016-11-08"
12+
s.description = "The minitar library is a pure-Ruby library that provides the ability to deal\nwith POSIX tar(1) archive files.\n\nThis is release 0.6, \u{2026}\n\nminitar (previously called Archive::Tar::Minitar) is based heavily on code\noriginally written by Mauricio Julio Fern\u{e1}ndez Pradier for the rpa-base\nproject."
13+
s.email = ["[email protected]"]
14+
s.extra_rdoc_files = ["Code-of-Conduct.md", "Contributing.md", "History.md", "Licence.md", "Manifest.txt", "README.rdoc", "docs/bsdl.txt", "docs/ruby.txt"]
15+
s.files = ["Code-of-Conduct.md", "Contributing.md", "History.md", "Licence.md", "Manifest.txt", "README.rdoc", "Rakefile", "docs/bsdl.txt", "docs/ruby.txt", "lib/archive-tar-minitar.rb", "lib/archive/tar/minitar.rb", "lib/archive/tar/minitar/input.rb", "lib/archive/tar/minitar/output.rb", "lib/archive/tar/minitar/posix_header.rb", "lib/archive/tar/minitar/reader.rb", "lib/archive/tar/minitar/writer.rb", "lib/minitar.rb", "test/minitest_helper.rb", "test/support/tar_test_helpers.rb", "test/test_tar_header.rb", "test/test_tar_input.rb", "test/test_tar_output.rb", "test/test_tar_reader.rb", "test/test_tar_writer.rb"]
16+
s.homepage = "https://github.com/halostatue/minitar/"
17+
s.licenses = ["Ruby", "BSD-2-Clause"]
18+
s.rdoc_options = ["--main", "README.rdoc"]
19+
s.required_ruby_version = Gem::Requirement.new(">= 1.8")
20+
s.rubygems_version = "2.5.1"
21+
s.summary = "The minitar library is a pure-Ruby library that provides the ability to deal with POSIX tar(1) archive files"
2222

2323
if s.respond_to? :specification_version then
2424
s.specification_version = 4
2525

2626
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27-
s.add_development_dependency(%q<minitest>.freeze, ["~> 5.9"])
28-
s.add_development_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
29-
s.add_development_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
30-
s.add_development_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
31-
s.add_development_dependency(%q<hoe-rubygems>.freeze, ["~> 1.0"])
32-
s.add_development_dependency(%q<hoe-travis>.freeze, ["~> 1.2"])
33-
s.add_development_dependency(%q<minitest-autotest>.freeze, ["< 2", ">= 1.0.b"])
34-
s.add_development_dependency(%q<rake>.freeze, ["~> 10.0"])
35-
s.add_development_dependency(%q<rdoc>.freeze, ["~> 4.0"])
36-
s.add_development_dependency(%q<hoe>.freeze, ["~> 3.15"])
27+
s.add_development_dependency(%q<minitest>, ["~> 5.9"])
28+
s.add_development_dependency(%q<hoe-doofus>, ["~> 1.0"])
29+
s.add_development_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
30+
s.add_development_dependency(%q<hoe-git>, ["~> 1.6"])
31+
s.add_development_dependency(%q<hoe-rubygems>, ["~> 1.0"])
32+
s.add_development_dependency(%q<hoe-travis>, ["~> 1.2"])
33+
s.add_development_dependency(%q<minitest-autotest>, ["< 2", ">= 1.0.b"])
34+
s.add_development_dependency(%q<rake>, ["~> 10.0"])
35+
s.add_development_dependency(%q<rdoc>, [">= 0.0"])
36+
s.add_development_dependency(%q<hoe>, ["~> 3.15"])
3737
else
38-
s.add_dependency(%q<minitest>.freeze, ["~> 5.9"])
39-
s.add_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
40-
s.add_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
41-
s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
42-
s.add_dependency(%q<hoe-rubygems>.freeze, ["~> 1.0"])
43-
s.add_dependency(%q<hoe-travis>.freeze, ["~> 1.2"])
44-
s.add_dependency(%q<minitest-autotest>.freeze, ["< 2", ">= 1.0.b"])
45-
s.add_dependency(%q<rake>.freeze, ["~> 10.0"])
46-
s.add_dependency(%q<rdoc>.freeze, ["~> 4.0"])
47-
s.add_dependency(%q<hoe>.freeze, ["~> 3.15"])
38+
s.add_dependency(%q<minitest>, ["~> 5.9"])
39+
s.add_dependency(%q<hoe-doofus>, ["~> 1.0"])
40+
s.add_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
41+
s.add_dependency(%q<hoe-git>, ["~> 1.6"])
42+
s.add_dependency(%q<hoe-rubygems>, ["~> 1.0"])
43+
s.add_dependency(%q<hoe-travis>, ["~> 1.2"])
44+
s.add_dependency(%q<minitest-autotest>, ["< 2", ">= 1.0.b"])
45+
s.add_dependency(%q<rake>, ["~> 10.0"])
46+
s.add_dependency(%q<rdoc>, [">= 0.0"])
47+
s.add_dependency(%q<hoe>, ["~> 3.15"])
4848
end
4949
else
50-
s.add_dependency(%q<minitest>.freeze, ["~> 5.9"])
51-
s.add_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
52-
s.add_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
53-
s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
54-
s.add_dependency(%q<hoe-rubygems>.freeze, ["~> 1.0"])
55-
s.add_dependency(%q<hoe-travis>.freeze, ["~> 1.2"])
56-
s.add_dependency(%q<minitest-autotest>.freeze, ["< 2", ">= 1.0.b"])
57-
s.add_dependency(%q<rake>.freeze, ["~> 10.0"])
58-
s.add_dependency(%q<rdoc>.freeze, ["~> 4.0"])
59-
s.add_dependency(%q<hoe>.freeze, ["~> 3.15"])
50+
s.add_dependency(%q<minitest>, ["~> 5.9"])
51+
s.add_dependency(%q<hoe-doofus>, ["~> 1.0"])
52+
s.add_dependency(%q<hoe-gemspec2>, ["~> 1.1"])
53+
s.add_dependency(%q<hoe-git>, ["~> 1.6"])
54+
s.add_dependency(%q<hoe-rubygems>, ["~> 1.0"])
55+
s.add_dependency(%q<hoe-travis>, ["~> 1.2"])
56+
s.add_dependency(%q<minitest-autotest>, ["< 2", ">= 1.0.b"])
57+
s.add_dependency(%q<rake>, ["~> 10.0"])
58+
s.add_dependency(%q<rdoc>, [">= 0.0"])
59+
s.add_dependency(%q<hoe>, ["~> 3.15"])
6060
end
6161
end

test/minitest_helper.rb

+4-84
Original file line numberDiff line numberDiff line change
@@ -6,89 +6,9 @@
66
gem 'minitest'
77
require 'minitest/autorun'
88

9-
module TarTester
10-
private
11-
def assert_headers_equal(h1, h2)
12-
fields = %w(name 100 mode 8 uid 8 gid 8 size 12 mtime 12 checksum 8
13-
typeflag 1 linkname 100 magic 6 version 2 uname 32 gname 32
14-
devmajor 8 devminor 8 prefix 155)
15-
offset = 0
16-
until fields.empty?
17-
name = fields.shift
18-
length = fields.shift.to_i
19-
if name == "checksum"
20-
chksum_off = offset
21-
offset += length
22-
next
23-
end
24-
assert_equal(h1[offset, length], h2[offset, length],
25-
"Field #{name} of the tar header differs.")
26-
offset += length
27-
end
28-
assert_equal(h1[chksum_off, 8], h2[chksum_off, 8], "Checksumes differ.")
29-
end
30-
31-
def assert_modes_equal(expected, actual, name)
32-
unless Minitar.windows?
33-
expected = "%04o" % (expected & 0777)
34-
actual = "%04o" % (actual & 0777)
35-
36-
assert_equal(expected, actual, "Mode for #{name} does not match")
37-
end
38-
end
39-
40-
def tar_file_header(fname, dname, mode, length)
41-
h = header("0", fname, dname, length, mode)
42-
checksum = calc_checksum(h)
43-
header("0", fname, dname, length, mode, checksum)
44-
end
45-
46-
def tar_dir_header(name, prefix, mode)
47-
h = header("5", name, prefix, 0, mode)
48-
checksum = calc_checksum(h)
49-
header("5", name, prefix, 0, mode, checksum)
50-
end
51-
52-
def header(type, fname, dname, length, mode, checksum = nil)
53-
checksum ||= " " * 8
54-
arr = [ASCIIZ(fname, 100), Z(to_oct(mode, 7)), Z(to_oct(nil, 7)),
55-
Z(to_oct(nil, 7)), Z(to_oct(length, 11)), Z(to_oct(0, 11)),
56-
checksum, type, "\0" * 100, "ustar\0", "00", ASCIIZ("", 32),
57-
ASCIIZ("", 32), Z(to_oct(nil, 7)), Z(to_oct(nil, 7)),
58-
ASCIIZ(dname, 155) ]
59-
arr = arr.join.bytes.to_a
60-
h = arr.pack("C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155")
61-
ret = h + "\0" * (512 - h.size)
62-
assert_equal(512, ret.size)
63-
ret
64-
end
65-
66-
def calc_checksum(header)
67-
sum = header.unpack("C*").inject { |s, a| s + a }
68-
SP(Z(to_oct(sum, 6)))
69-
end
70-
71-
def to_oct(n, pad_size)
72-
if n.nil?
73-
"\0" * pad_size
74-
else
75-
"%0#{pad_size}o" % n
76-
end
77-
end
78-
79-
def ASCIIZ(str, length)
80-
str + "\0" * (length - str.length)
81-
end
82-
83-
def SP(s)
84-
s + " "
85-
end
86-
87-
def Z(s)
88-
s + "\0"
89-
end
9+
Dir.glob(File.join(File.dirname(__FILE__), 'support/*.rb')).each do |support|
10+
require support
11+
end
9012

91-
def SP_Z(s)
92-
s + " \0"
93-
end
13+
module TarTester
9414
end

0 commit comments

Comments
 (0)