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
34 35 36 37 38 39 40 41 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 34 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
29 30 31 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 29 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.
16 17 18 19 20 21 22 23 24 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 16 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
50 51 52 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 50 def bytes_read @read end |
#check_closed ⇒ Object
:nodoc:
43 44 45 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 43 def check_closed # :nodoc: raise IOError, "closed #{self.class}" if closed? end |
#close ⇒ Object
Closes the tar entry
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 57 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?
71 72 73 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 71 def closed? @closed end |
#directory? ⇒ Boolean
Is this tar entry a directory?
114 115 116 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 114 def directory? @header.typeflag == "5" end |
#eof? ⇒ Boolean
Are we at the end of the tar entry?
78 79 80 81 82 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 78 def eof? check_closed @read >= @header.size end |
#file? ⇒ Boolean
Is this tar entry a file?
121 122 123 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 121 def file? @header.typeflag == "0" end |
#full_name ⇒ Object
Full name of the tar entry
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 87 def full_name if @header.prefix != "" File.join @header.prefix, @header.name else @header.name end 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
102 103 104 105 106 107 108 109 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 102 def getc return nil if eof? ret = @io.getc @read += 1 if ret ret end |
#pos ⇒ Object
The position in the tar entry
135 136 137 138 139 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 135 def pos check_closed bytes_read end |
#pos=(new_pos) ⇒ Object
Seek to the position in the tar entry
144 145 146 147 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 144 def pos=(new_pos) seek(new_pos, IO::SEEK_SET) new_pos end |
#read(maxlen = nil) ⇒ Object
Reads maxlen
bytes from the tar file entry, or the rest of the entry if nil
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 158 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
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 174 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
243 244 245 246 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 243 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
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 236 237 238 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 191 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
149 150 151 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 149 def size @header.size end |
#symlink? ⇒ Boolean
Is this tar entry a symlink?
128 129 130 |
# File 'lib/rubygems/package/tar_reader/entry.rb', line 128 def symlink? @header.typeflag == "2" end |