zippo 0.2.0 → 0.2.1

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 (46) hide show
  1. checksums.yaml +6 -14
  2. data/.rubocop.yml +35 -0
  3. data/.travis.yml +3 -0
  4. data/README.md +4 -0
  5. data/Rakefile +8 -2
  6. data/lib/zippo.rb +1 -1
  7. data/lib/zippo/binary_structure/base.rb +10 -8
  8. data/lib/zippo/binary_structure/binary_packer.rb +2 -2
  9. data/lib/zippo/binary_structure/meta.rb +9 -11
  10. data/lib/zippo/binary_structure/structure.rb +6 -4
  11. data/lib/zippo/binary_structure/structure_member.rb +1 -1
  12. data/lib/zippo/cd_file_header.rb +14 -14
  13. data/lib/zippo/central_directory_entries_unpacker.rb +3 -2
  14. data/lib/zippo/central_directory_reader.rb +4 -3
  15. data/lib/zippo/end_cd_record.rb +6 -6
  16. data/lib/zippo/filter/base.rb +3 -2
  17. data/lib/zippo/filter/compressor.rb +4 -4
  18. data/lib/zippo/filter/compressor/deflate.rb +1 -0
  19. data/lib/zippo/filter/null_filters.rb +1 -0
  20. data/lib/zippo/filter/uncompressor.rb +3 -5
  21. data/lib/zippo/filter/uncompressor/deflate.rb +1 -0
  22. data/lib/zippo/io_zip_member.rb +1 -1
  23. data/lib/zippo/local_file_header.rb +8 -8
  24. data/lib/zippo/version.rb +1 -1
  25. data/lib/zippo/zip_directory.rb +15 -12
  26. data/lib/zippo/zip_file.rb +8 -6
  27. data/lib/zippo/zip_file_writer.rb +4 -4
  28. data/lib/zippo/zip_member.rb +4 -3
  29. data/spec/binary_structure_spec.rb +26 -28
  30. data/spec/central_directory_entries_unpacker_spec.rb +2 -3
  31. data/spec/central_directory_parser_spec.rb +4 -4
  32. data/spec/central_directory_unpacker_spec.rb +0 -1
  33. data/spec/deflate_compressor_spec.rb +4 -4
  34. data/spec/deflate_uncompressor_spec.rb +5 -6
  35. data/spec/integration/compressors_spec.rb +1 -1
  36. data/spec/integration/zippo_spec.rb +4 -3
  37. data/spec/spec_helper.rb +9 -0
  38. data/spec/store_compressor_spec.rb +3 -3
  39. data/spec/store_uncompressor_spec.rb +1 -1
  40. data/spec/zip_directory_spec.rb +15 -15
  41. data/spec/zip_file_spec.rb +1 -1
  42. data/spec/zip_file_writer_spec.rb +0 -1
  43. data/spec/zip_member_spec.rb +4 -6
  44. data/yard_extensions.rb +1 -1
  45. data/zippo.gemspec +7 -6
  46. metadata +59 -19
@@ -27,7 +27,7 @@ module Zippo::Filter
27
27
  @remaining = @compressed_size
28
28
  end
29
29
 
30
- def read n, buf = nil
30
+ def read(n, buf = nil)
31
31
  if @remaining >= n
32
32
  @remaining -= n
33
33
  elsif (n = @remaining) > 0
@@ -43,11 +43,9 @@ module Zippo::Filter
43
43
  # Uncompresses the data to the specified IO
44
44
  #
45
45
  # @param [IO] io the object to uncompress to, must respond to #<<
46
- def uncompress_to io
46
+ def uncompress_to(io)
47
47
  buf = ""
48
- while (read BLOCK_SIZE, buf)
49
- io << buf
50
- end
48
+ io << buf while read BLOCK_SIZE, buf
51
49
  io << tail_filter
52
50
  end
53
51
 
@@ -14,6 +14,7 @@ module Zippo::Filter
14
14
  end
15
15
 
16
16
  private
17
+
17
18
  def filter(buf)
18
19
  @zlib.inflate(buf)
19
20
  end
@@ -17,7 +17,7 @@ module Zippo
17
17
  @source.rewind
18
18
  end
19
19
 
20
- def write_to out, preferred_compression_method = Filter::DeflateCompressor::METHOD, recompress = nil
20
+ def write_to(out, preferred_compression_method = Filter::DeflateCompressor::METHOD, _recompress = nil)
21
21
  Filter::Compressor.for(preferred_compression_method).new(@source).compress_to(out)
22
22
  end
23
23
  end
@@ -8,21 +8,21 @@ module Zippo
8
8
  binary_structure do
9
9
  # @!macro [attach] bs.field
10
10
  # @!attribute [rw] $1
11
- field :signature, 'L', :signature => SIGNATURE
12
- field :version_extractable_by, 'S', :default => 20
13
- field :bit_flags, 'S', :default => 0
11
+ field :signature, 'L', signature: SIGNATURE
12
+ field :version_extractable_by, 'S', default: 20
13
+ field :bit_flags, 'S', default: 0
14
14
  field :compression_method, 'S'
15
- field :last_modified_time, 'S', :default => 0 # XXX
16
- field :last_modified_date, 'S', :default => 0 # XXX
15
+ field :last_modified_time, 'S', default: 0 # XXX
16
+ field :last_modified_date, 'S', default: 0 # XXX
17
17
  field :crc32, 'L'
18
18
  field :compressed_size, 'L'
19
19
  field :uncompressed_size, 'L'
20
20
  # set when name is set
21
21
  field :file_name_length, 'S'
22
22
  # set when extra_field is set
23
- field :extra_field_length, 'S', :default => 0
24
- field :name, 'a*', :size => :file_name_length
25
- field :extra_field, 'a*', :default => '', :size => :extra_field_length
23
+ field :extra_field_length, 'S', default: 0
24
+ field :name, 'a*', size: :file_name_length
25
+ field :extra_field, 'a*', default: '', size: :extra_field_length
26
26
  end
27
27
  end
28
28
  end
data/lib/zippo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Zippo
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -13,7 +13,7 @@ module Zippo
13
13
  def_delegators :entries_hash, :empty?
14
14
  def_delegators :entries, :each, :map
15
15
 
16
- def initialize io = nil
16
+ def initialize(io = nil)
17
17
  @io = io
18
18
  end
19
19
 
@@ -48,23 +48,25 @@ module Zippo
48
48
  # - another ZipMember (allowing direct stream copy)
49
49
  def insert(name, source)
50
50
  set name,
51
- case source
52
- when ZipMember then source.with_name name
53
- when String then IOZipMember.new name, File.open(source, 'r:BINARY')
54
- else IOZipMember.new name, source
55
- end
51
+ case source
52
+ when ZipMember then source.with_name name
53
+ when String then IOZipMember.new name, File.open(source, 'r:BINARY')
54
+ else IOZipMember.new name, source
55
+ end
56
56
  end
57
57
 
58
58
  # @return [Hash] the hash of ZipMembers, the hash key is the
59
59
  # member's name
60
60
  def entries_hash
61
- @entries_hash ||= if @io
62
- CentralDirectoryReader.new(@io).cd_file_headers.each_with_object({}) do |header, hash|
63
- hash[header.name] = ZipMember.new @io, header
61
+ @entries_hash ||=
62
+ if @io
63
+ CentralDirectoryReader.new(@io)
64
+ .cd_file_headers.each_with_object({}) do |header, hash|
65
+ hash[header.name] = ZipMember.new @io, header
66
+ end
67
+ else
68
+ {}
64
69
  end
65
- else
66
- {}
67
- end
68
70
  end
69
71
 
70
72
  # @return [Array] the members of the ZipFile
@@ -73,6 +75,7 @@ module Zippo
73
75
  end
74
76
 
75
77
  private
78
+
76
79
  def set(name, member)
77
80
  entries_hash[name] = member
78
81
  end
@@ -87,14 +87,16 @@ module Zippo
87
87
 
88
88
  # @return [ZipDirectory] the ZipDirectory
89
89
  def directory
90
- @directory ||= if read?
91
- ZipDirectory.new io
92
- else
93
- ZipDirectory.new
94
- end
90
+ @directory ||=
91
+ if read?
92
+ ZipDirectory.new io
93
+ else
94
+ ZipDirectory.new
95
+ end
95
96
  end
96
97
 
97
98
  private
99
+
98
100
  def read?
99
101
  File.exist? @filename and @mode.include? 'r'
100
102
  end
@@ -104,7 +106,7 @@ module Zippo
104
106
  end
105
107
 
106
108
  def update?
107
- read? and write?
109
+ read? && write?
108
110
  end
109
111
 
110
112
  def io
@@ -10,10 +10,10 @@ module Zippo
10
10
 
11
11
  # Writes the directory to the file.
12
12
  def write
13
- File.open(@filename,'wb:ASCII-8BIT') do |io|
13
+ File.open(@filename, 'wb:ASCII-8BIT') do |io|
14
14
  packer = LocalFileHeader::Packer.new io
15
15
  headers = []
16
- for member in @directory
16
+ @directory.each do |member|
17
17
  header = CdFileHeader.default
18
18
  header.compression_method = 8 # XXX configurable
19
19
  # XXX hack fix for maintaining method in zipped data copies
@@ -36,7 +36,7 @@ module Zippo
36
36
 
37
37
  # write the completed header, returning to the current position
38
38
  io.seek header.local_file_header_offset
39
- #packer.pack LocalFileHeader.from header.convert_to LocalHileHeader
39
+ # packer.pack LocalFileHeader.from header.convert_to LocalHileHeader
40
40
  packer.pack header.convert_to LocalFileHeader
41
41
  io.seek header.compressed_size, IO::SEEK_CUR
42
42
  headers << header
@@ -45,7 +45,7 @@ module Zippo
45
45
  eocdr = EndCdRecord.default
46
46
  eocdr.cd_offset = io.pos
47
47
  packer = CdFileHeader::Packer.new io
48
- for header in headers
48
+ headers.each do |header|
49
49
  packer.pack header
50
50
  end
51
51
  eocdr.cd_size = io.pos - eocdr.cd_offset
@@ -7,7 +7,7 @@ require 'forwardable'
7
7
  module Zippo
8
8
  # A member of a Zip archive file.
9
9
  class ZipMember
10
- def initialize io, header
10
+ def initialize(io, header)
11
11
  @io = io
12
12
  @header = header
13
13
  end
@@ -38,7 +38,7 @@ module Zippo
38
38
  #
39
39
  # @param [String] name the name to use
40
40
  # @return [ZipMember] the new ZipMember
41
- def with_name name
41
+ def with_name(name)
42
42
  dup.tap do |obj|
43
43
  obj.instance_variable_set :@name, name
44
44
  end
@@ -53,7 +53,7 @@ module Zippo
53
53
  #
54
54
  # @return [Integer, Integer, Integer] the amount written, the
55
55
  # original size of the data, the crc32 of the data
56
- def write_to out, preferred_method = Filter::DeflateCompressor::METHOD, recompress = false
56
+ def write_to(out, preferred_method = Filter::DeflateCompressor::METHOD, recompress = false)
57
57
  seek_to_compressed_data
58
58
  if recompress
59
59
  Filter::Compressor.for(preferred_method).new(uncompressor).compress_to(out)
@@ -64,6 +64,7 @@ module Zippo
64
64
  end
65
65
 
66
66
  private
67
+
67
68
  def local_file_header
68
69
  @io.seek @header.local_file_header_offset
69
70
  LocalFileHeader::Unpacker.new(@io).unpack
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- # TODO - spec that unpackers can take strings
3
+ # TODO: - spec that unpackers can take strings
4
4
 
5
5
  require 'zippo/binary_structure'
6
6
 
@@ -17,14 +17,14 @@ module Zippo
17
17
  klass.class_eval do
18
18
  binary_structure do
19
19
  field :foo, 'L'
20
- field :yay, 'a4', :signature => "baz"
20
+ field :yay, 'a4', signature: "baz"
21
21
  field :bar, 'S'
22
- field :quux, 'a*', :size => :foo
22
+ field :quux, 'a*', size: :foo
23
23
  end
24
24
  end
25
25
  end
26
26
  it "should store field information in the class" do
27
- klass.structure.should have(4).fields
27
+ klass.structure.fields.size.should eq 4
28
28
  klass.structure.fields[0].name.should eq :foo
29
29
  klass.structure.fields[3].options[:size].should eq :foo
30
30
  klass.structure.fields[1].should be_signature
@@ -42,7 +42,7 @@ module Zippo
42
42
  obj.bar.should eq 10
43
43
  end
44
44
  it "should have an unpacker" do
45
- array = [10,"baz", 42,"foobar baz"]
45
+ array = [10, "baz", 42, "foobar baz"]
46
46
  packed = array.pack 'La4Sa*'
47
47
  io = StringIO.new packed
48
48
  obj = klass::Unpacker.new(io).unpack
@@ -51,14 +51,14 @@ module Zippo
51
51
  obj.quux.should eq "foobar baz"
52
52
  end
53
53
  it "should unpack oversized strings correctly" do
54
- array = [3,"baz", 42,"foobar baz"]
54
+ array = [3, "baz", 42, "foobar baz"]
55
55
  packed = array.pack 'La4Sa*'
56
56
  io = StringIO.new packed
57
57
  obj = klass::Unpacker.new(io).unpack
58
58
  obj.quux.should eq "foo"
59
59
  end
60
60
  it "should have a packer" do
61
- array = [10,"baz", 42,"foobar baz"]
61
+ array = [10, "baz", 42, "foobar baz"]
62
62
  packed = array.pack 'La4Sa*'
63
63
  io = StringIO.new
64
64
  obj.bar = 42
@@ -79,7 +79,7 @@ module Zippo
79
79
  other_klass.class_eval do
80
80
  binary_structure do
81
81
  field :bar, 'S'
82
- field :yay, 'a4', :signature => "quux"
82
+ field :yay, 'a4', signature: "quux"
83
83
  end
84
84
  end
85
85
  end
@@ -108,25 +108,23 @@ module Zippo
108
108
  # need to test a few fixed fields, followed by a
109
109
  # variable length field, then a few more fixed
110
110
  # fields
111
- =begin
112
- it "should complain if the order is bad" do
113
- pending
114
- klass = Class.new BinaryStructure
115
- lambda { klass.class_eval do
116
- field :foo, 'S'
117
- field :bar, 'a*', :size => :baz
118
- field :baz, 'S'
119
- end }.should raise_error "size not found"
120
- end
121
- it "should remain silent if the order is ok" do
122
- pending
123
- klass = Class.new BinaryStructure
124
- lambda { klass.class_eval do
125
- field :foo, 'S'
126
- field :baz, 'S'
127
- field :bar, 'a*', :size => :baz
128
- end }.should_not raise_error
129
- end
130
- =end
111
+ # it "should complain if the order is bad" do
112
+ # pending
113
+ # klass = Class.new BinaryStructure
114
+ # lambda { klass.class_eval do
115
+ # field :foo, 'S'
116
+ # field :bar, 'a*', :size => :baz
117
+ # field :baz, 'S'
118
+ # end }.should raise_error "size not found"
119
+ # end
120
+ # it "should remain silent if the order is ok" do
121
+ # pending
122
+ # klass = Class.new BinaryStructure
123
+ # lambda { klass.class_eval do
124
+ # field :foo, 'S'
125
+ # field :baz, 'S'
126
+ # field :bar, 'a*', :size => :baz
127
+ # end }.should_not raise_error
128
+ # end
131
129
  end
132
130
  end
@@ -11,7 +11,7 @@ module Zippo
11
11
  let(:offset) { 112 }
12
12
  let(:size) { 79 }
13
13
 
14
- specify { subject.should have(1).items }
14
+ specify { subject.size.should eq 1 }
15
15
  specify { subject.first.name.should eq "test.file" }
16
16
  end
17
17
 
@@ -20,10 +20,9 @@ module Zippo
20
20
  let(:offset) { 242 }
21
21
  let(:size) { 158 }
22
22
 
23
- specify { subject.should have(2).items }
23
+ specify { subject.size.should eq 2 }
24
24
  specify { subject[0].name.should eq "test.file" }
25
25
  specify { subject[1].name.should eq "other.test" }
26
26
  end
27
-
28
27
  end
29
28
  end
@@ -6,7 +6,7 @@ require "zippo/zip_file"
6
6
  module Zippo
7
7
  describe CentralDirectoryReader do
8
8
  let(:io) { File.open(file, "rb:ASCII-8BIT") }
9
- let(:file) { test_file "test.zip" }
9
+ let(:file) { test_file "test.zip" }
10
10
  let(:parser) { CentralDirectoryReader.new(io) }
11
11
  after(:each) { io.close }
12
12
 
@@ -17,7 +17,7 @@ module Zippo
17
17
  end
18
18
 
19
19
  specify { parser.end_of_cd_record_position.should eq 0xbf }
20
- specify { parser.should have(1).cd_file_headers }
20
+ specify { parser.cd_file_headers.size.should eq 1 }
21
21
  end
22
22
 
23
23
  context "when parsing a file with a comment" do
@@ -33,7 +33,7 @@ module Zippo
33
33
 
34
34
  context "when parsing a file that is not a zip" do
35
35
  let(:file) { test_file "not_a.zip" }
36
- specify { -> {parser.end_of_cd_record_position}.should raise_error(/not found/) }
36
+ specify { -> { parser.end_of_cd_record_position }.should raise_error(/not found/) }
37
37
  end
38
38
 
39
39
  context "when parsing a zip file larger than the maximum comment size" do
@@ -42,7 +42,7 @@ module Zippo
42
42
  Zippo::ZipFile.open("large.zip", "w") do |v|
43
43
  v["test.file"] = "a" * 65535
44
44
  end
45
- Zippo::ZipFile.open("large.zip") {|v| v["test.file"].read }.should eq "a" * 65535
45
+ Zippo::ZipFile.open("large.zip") { |v| v["test.file"].read }.should eq "a" * 65535
46
46
  end
47
47
  end
48
48
  end
@@ -26,6 +26,5 @@ module Zippo
26
26
  specify { subject.total_records.should eq 1 }
27
27
  specify { subject.comment.should eq "this is a comment to make things tricky" }
28
28
  end
29
-
30
29
  end
31
30
  end
@@ -5,10 +5,10 @@ require "zippo/filter/compressor/deflate"
5
5
 
6
6
  module Zippo::Filter
7
7
  describe DeflateCompressor do
8
- let (:data) { "a" * 20 }
9
- let (:zdata) { "KL\xC4\u0004\u0000" }
10
- let (:io) { StringIO.new data }
11
- let (:out) { StringIO.new "" }
8
+ let(:data) { "a" * 20 }
9
+ let(:zdata) { "KL\xC4\u0004\u0000" }
10
+ let(:io) { StringIO.new data }
11
+ let(:out) { StringIO.new "" }
12
12
  it "should write the data" do
13
13
  compressor = DeflateCompressor.new(io)
14
14
  csize, size, crc32 = compressor.compress_to out
@@ -4,12 +4,11 @@ require "zippo/filter/uncompressor/deflate"
4
4
 
5
5
  module Zippo::Filter
6
6
  describe DeflateUncompressor do
7
-
8
- let (:zstring) { Zlib::Deflate.new(Zlib::BEST_COMPRESSION, -Zlib::MAX_WBITS).deflate("a" * 20, Zlib::FINISH) }
9
- let (:size) { zstring.size }
10
- let (:string) { "aaa" + zstring + "bbb" }
11
- let (:out) { StringIO.new }
12
- let (:io) { StringIO.new string }
7
+ let(:zstring) { Zlib::Deflate.new(Zlib::BEST_COMPRESSION, -Zlib::MAX_WBITS).deflate("a" * 20, Zlib::FINISH) }
8
+ let(:size) { zstring.size }
9
+ let(:string) { "aaa" + zstring + "bbb" }
10
+ let(:out) { StringIO.new }
11
+ let(:io) { StringIO.new string }
13
12
  it "should deflate only the compressed string" do
14
13
  io.seek 3
15
14
  DeflateUncompressor.new(io, size).uncompress.should eq "a" * 20
@@ -7,7 +7,7 @@ require 'zippo/filter/compressors'
7
7
 
8
8
  module Zippo::Filter
9
9
  describe Uncompressor do
10
- let (:zstring) { Zlib::Deflate.new(Zlib::BEST_COMPRESSION, -Zlib::MAX_WBITS).deflate("a" * 20, Zlib::FINISH) }
10
+ let(:zstring) { Zlib::Deflate.new(Zlib::BEST_COMPRESSION, -Zlib::MAX_WBITS).deflate("a" * 20, Zlib::FINISH) }
11
11
  it "should allow uncompressors to work with compressors" do
12
12
  stream = StringIO.new zstring
13
13
  deflater = DeflateUncompressor.new(stream, zstring.size)
@@ -24,7 +24,8 @@ module Zippo
24
24
 
25
25
  it "should work like File.open" do
26
26
  io = File.open(file)
27
- File.should_receive(:open).with(file, 'r:ASCII-8BIT').and_return(io)
27
+ expect(File).to receive(:open)
28
+ .with(file, 'r:ASCII-8BIT').and_return(io)
28
29
  s = Zippo.open(file) { |v| v['test.file'].read }
29
30
  s.should eq member_data
30
31
  io.should be_closed
@@ -33,9 +34,9 @@ module Zippo
33
34
  it "should create zip files" do
34
35
  in_working_directory do
35
36
  File.write "xyzzy.txt", "plugh"
36
- Zippo.open("new.zip", "w") {|v| v['xyzzy.txt'] = "plugh" }
37
+ Zippo.open("new.zip", "w") { |v| v['xyzzy.txt'] = "plugh" }
37
38
  Pathname.new("new.zip").should exist
38
- Zippo.open("new.zip") {|v| v['xyzzy.txt'].read }.should eq "plugh"
39
+ Zippo.open("new.zip") { |v| v['xyzzy.txt'].read }.should eq "plugh"
39
40
  end
40
41
  end
41
42