summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2019-10-01 13:16:32 +0200
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-10 14:51:45 +0900
commit717b72a8af6b99ca79fd5bbe52ba4bd16b038bf6 (patch)
treed59a7942e0b7308d468b6dd65ef042c8c8451166 /lib
parent495ebd6e9555bdd220a74c96cda7a7d6fe40209b (diff)
[rubygems/rubygems] Optimize Gem::Package::TarReader#each
https://github.com/rubygems/rubygems/commit/1de8f39ac4
Diffstat (limited to 'lib')
-rw-r--r--lib/rubygems/package/tar_reader.rb24
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb
index f64915eaea..aa31ea27d4 100644
--- a/lib/rubygems/package/tar_reader.rb
+++ b/lib/rubygems/package/tar_reader.rb
@@ -55,6 +55,8 @@ class Gem::Package::TarReader
def each
return enum_for __method__ unless block_given?
+ use_seek = @io.respond_to?(:seek)
+
until @io.eof? do
header = Gem::Package::TarHeader.from @io
return if header.empty?
@@ -67,18 +69,22 @@ class Gem::Package::TarReader
skip = (512 - (size % 512)) % 512
pending = size - entry.bytes_read
- begin
- # avoid reading...
- @io.seek pending, IO::SEEK_CUR
- pending = 0
- rescue Errno::EINVAL, NameError
- while pending > 0 do
- bytes_read = @io.read([pending, 4096].min).size
- raise UnexpectedEOF if @io.eof?
- pending -= bytes_read
+ if use_seek
+ begin
+ # avoid reading if the @io supports seeking
+ @io.seek pending, IO::SEEK_CUR
+ pending = 0
+ rescue Errno::EINVAL
end
end
+ # if seeking isn't supported or failed
+ while pending > 0 do
+ bytes_read = @io.read([pending, 4096].min).size
+ raise UnexpectedEOF if @io.eof?
+ pending -= bytes_read
+ end
+
@io.read skip # discard trailing zeros
# make sure nobody can use #read, #getc or #rewind anymore