Class: Gem::Package::TarReader::Entry
- Inherits:
-
Object
- Object
- Gem::Package::TarReader::Entry
- Defined in:
- lib/rubygems/package/tar_reader/entry.rb
Overview
Class for reading entries out of a tar file
Instance Attribute Summary collapse
-
#header ⇒ Object
readonly
Header for this tar entry.
Class Method Summary collapse
-
.open(header, io, &block) ⇒ Object
Creates a new tar entry for
header
that will be read fromio
If a block is given, the entry is yielded and then closed.
Instance Method Summary collapse
-
#bytes_read ⇒ Object
Number of bytes read out of the tar entry.
-
#check_closed ⇒ Object
:nodoc:.
-
#close ⇒ Object
Closes the tar entry.
-
#closed? ⇒ Boolean
Is the tar entry closed?.
-
#directory? ⇒ Boolean
Is this tar entry a directory?.
-
#eof? ⇒ Boolean
Are we at the end of the tar entry?.
-
#file? ⇒ Boolean
Is this tar entry a file?.
-
#full_name ⇒ Object
Full name of the tar entry.
-
#getc ⇒ Object
Read one byte from the tar entry.
-
#initialize(header, io) ⇒ Entry
constructor
Creates a new tar entry for
header
that will be read fromio
. -
#pos ⇒ Object
The position in the tar entry.
-
#pos=(new_pos) ⇒ Object
Seek to the position in the tar entry.
-
#read(maxlen = nil) ⇒ Object
Reads
maxlen
bytes from the tar file entry, or the rest of the entry if nil. - #readpartial(maxlen, outbuf = "".b) ⇒ Object
-
#rewind ⇒ Object
Rewinds to the beginning of the tar file entry.
-
#seek(offset, whence = IO::SEEK_SET) ⇒ Object
Seeks to
offset
bytes into the tar file entrywhence
can be IO::SEEK_SET, IO::SEEK_CUR, or IO::SEEK_END. - #size ⇒ Object (also: #length)
-
#symlink? ⇒ Boolean
Is this tar entry a symlink?.
Constructor Details
#initialize(header, io) ⇒ Entry
Creates a new tar entry for header
that will be read from io
36 37 38 39 40 41 42 43 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 36 def initialize(header, io) @closed = false @header = header @io = io @orig_pos = @io.pos @end_pos = @orig_pos + @header.size @read = 0 end |
Instance Attribute Details
#header ⇒ Object (readonly)
Header for this tar entry
31 32 33 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 31 def header @header end |
Class Method Details
.open(header, io, &block) ⇒ Object
Creates a new tar entry for header
that will be read from io
If a block is given, the entry is yielded and then closed.
18 19 20 21 22 23 24 25 26 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 18 def self.open(header, io, &block) entry = new header, io return entry unless block_given? begin yield entry ensure entry.close end end |
Instance Method Details
#bytes_read ⇒ Object
Number of bytes read out of the tar entry
52 53 54 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 52 def bytes_read @read end |
#check_closed ⇒ Object
:nodoc:
45 46 47 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 45 def check_closed # :nodoc: raise IOError, "closed #{self.class}" if closed? end |
#close ⇒ Object
Closes the tar entry
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 59 def close return if closed? # Seek to the end of the entry if it wasn't fully read seek(0, IO::SEEK_END) # discard trailing zeros skip = (512 - (@header.size % 512)) % 512 @io.read(skip) @closed = true nil end |
#closed? ⇒ Boolean
Is the tar entry closed?
73 74 75 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 73 def closed? @closed end |
#directory? ⇒ Boolean
Is this tar entry a directory?
112 113 114 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 112 def directory? @header.typeflag == "5" end |
#eof? ⇒ Boolean
Are we at the end of the tar entry?
80 81 82 83 84 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 80 def eof? check_closed @read >= @header.size end |
#file? ⇒ Boolean
Is this tar entry a file?
119 120 121 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 119 def file? @header.typeflag == "0" end |
#full_name ⇒ Object
Full name of the tar entry
89 90 91 92 93 94 95 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 89 def full_name @header.full_name.force_encoding(Encoding::UTF_8) rescue ArgumentError => e raise unless e. == "string contains null byte" raise Gem::Package::TarInvalidError, "tar is corrupt, name contains null byte" end |
#getc ⇒ Object
Read one byte from the tar entry
100 101 102 103 104 105 106 107 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 100 def getc return nil if eof? ret = @io.getc @read += 1 if ret ret end |
#pos ⇒ Object
The position in the tar entry
133 134 135 136 137 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 133 def pos check_closed bytes_read end |
#pos=(new_pos) ⇒ Object
Seek to the position in the tar entry
142 143 144 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 142 def pos=(new_pos) seek(new_pos, IO::SEEK_SET) end |
#read(maxlen = nil) ⇒ Object
Reads maxlen
bytes from the tar file entry, or the rest of the entry if nil
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 155 def read(maxlen = nil) if eof? return maxlen.to_i.zero? ? "" : nil end max_read = [maxlen, @header.size - @read].compact.min ret = @io.read max_read if ret.nil? return maxlen ? nil : "" # IO.read returns nil on EOF with len argument end @read += ret.size ret end |
#readpartial(maxlen, outbuf = "".b) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 171 def readpartial(maxlen, outbuf = "".b) if eof? && maxlen > 0 raise EOFError, "end of file reached" end max_read = [maxlen, @header.size - @read].min @io.readpartial(max_read, outbuf) @read += outbuf.size outbuf end |
#rewind ⇒ Object
Rewinds to the beginning of the tar file entry
240 241 242 243 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 240 def rewind check_closed seek(0, IO::SEEK_SET) end |
#seek(offset, whence = IO::SEEK_SET) ⇒ Object
Seeks to offset
bytes into the tar file entry whence
can be IO::SEEK_SET, IO::SEEK_CUR, or IO::SEEK_END
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 188 def seek(offset, whence = IO::SEEK_SET) check_closed new_pos = case whence when IO::SEEK_SET then @orig_pos + offset when IO::SEEK_CUR then @io.pos + offset when IO::SEEK_END then @end_pos + offset else raise ArgumentError, "invalid whence" end if new_pos < @orig_pos new_pos = @orig_pos elsif new_pos > @end_pos new_pos = @end_pos end pending = new_pos - @io.pos return 0 if pending == 0 if @io.respond_to?(:seek) begin # avoid reading if the @io supports seeking @io.seek new_pos, IO::SEEK_SET pending = 0 rescue Errno::EINVAL end end # if seeking isn't supported or failed # negative seek requires that we rewind and read if pending < 0 @io.rewind pending = new_pos end while pending > 0 do size_read = @io.read([pending, 4096].min)&.size raise(EOFError, "end of file reached") if size_read.nil? pending -= size_read end @read = @io.pos - @orig_pos 0 end |
#size ⇒ Object Also known as: length
146 147 148 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 146 def size @header.size end |
#symlink? ⇒ Boolean
Is this tar entry a symlink?
126 127 128 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 126 def symlink? @header.typeflag == "2" end |