Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK!a  tar_reader/entry.rbnu[# frozen_string_literal: true #++ # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. #-- ## # Class for reading entries out of a tar file class Gem::Package::TarReader::Entry ## # Header for this tar entry attr_reader :header ## # Creates a new tar entry for +header+ that will be read from +io+ def initialize(header, io) @closed = false @header = header @io = io @orig_pos = @io.pos @read = 0 end def check_closed # :nodoc: raise IOError, "closed #{self.class}" if closed? end ## # Number of bytes read out of the tar entry def bytes_read @read end ## # Closes the tar entry def close @closed = true end ## # Is the tar entry closed? def closed? @closed end ## # Are we at the end of the tar entry? def eof? check_closed @read >= @header.size end ## # Full name of the tar entry def full_name if @header.prefix != "" File.join @header.prefix, @header.name else @header.name end rescue ArgumentError => e raise unless e.message == 'string contains null byte' raise Gem::Package::TarInvalidError, 'tar is corrupt, name contains null byte' end ## # Read one byte from the tar entry def getc check_closed return nil if @read >= @header.size ret = @io.getc @read += 1 if ret ret end ## # Is this tar entry a directory? def directory? @header.typeflag == "5" end ## # Is this tar entry a file? def file? @header.typeflag == "0" end ## # Is this tar entry a symlink? def symlink? @header.typeflag == "2" end ## # The position in the tar entry def pos check_closed bytes_read end def size @header.size end alias length size ## # Reads +len+ bytes from the tar file entry, or the rest of the entry if # nil def read(len = nil) check_closed return nil if @read >= @header.size len ||= @header.size - @read max_read = [len, @header.size - @read].min ret = @io.read max_read @read += ret.size ret end def readpartial(maxlen = nil, outbuf = "".b) check_closed raise EOFError if @read >= @header.size maxlen ||= @header.size - @read max_read = [maxlen, @header.size - @read].min @io.readpartial(max_read, outbuf) @read += outbuf.size outbuf end ## # Rewinds to the beginning of the tar file entry def rewind check_closed @io.pos = @orig_pos @read = 0 end end PK!dyfftar_test_case.rbnu[# frozen_string_literal: true require 'rubygems/test_case' require 'rubygems/package' ## # A test case for Gem::Package::Tar* classes class Gem::Package::TarTestCase < Gem::TestCase def ASCIIZ(str, length) str + "\0" * (length - str.length) end def SP(s) s + " " end def SP_Z(s) s + " \0" end def Z(s) s + "\0" end def assert_headers_equal(expected, actual) expected = expected.to_s unless String === expected actual = actual.to_s unless String === actual fields = %w[ name 100 mode 8 uid 8 gid 8 size 12 mtime 12 checksum 8 typeflag 1 linkname 100 magic 6 version 2 uname 32 gname 32 devmajor 8 devminor 8 prefix 155 ] offset = 0 until fields.empty? do name = fields.shift length = fields.shift.to_i if name == "checksum" then chksum_off = offset offset += length next end assert_equal expected[offset, length], actual[offset, length], "Field #{name} of the tar header differs." offset += length end assert_equal expected[chksum_off, 8], actual[chksum_off, 8] end def calc_checksum(header) sum = header.unpack("C*").inject{|s,a| s + a} SP(Z(to_oct(sum, 6))) end def header(type, fname, dname, length, mode, mtime, checksum = nil, linkname = "") checksum ||= " " * 8 arr = [ # struct tarfile_entry_posix ASCIIZ(fname, 100), # char name[100]; ASCII + (Z unless filled) Z(to_oct(mode, 7)), # char mode[8]; 0 padded, octal null Z(to_oct(0, 7)), # char uid[8]; ditto Z(to_oct(0, 7)), # char gid[8]; ditto Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null Z(to_oct(mtime, 11)), # char mtime[12]; 0 padded, octal, null checksum, # char checksum[8]; 0 padded, octal, null, space type, # char typeflag[1]; file: "0" dir: "5" ASCIIZ(linkname, 100), # char linkname[100]; ASCII + (Z unless filled) "ustar\0", # char magic[6]; "ustar\0" "00", # char version[2]; "00" ASCIIZ("wheel", 32), # char uname[32]; ASCIIZ ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null ASCIIZ(dname, 155) # char prefix[155]; ASCII + (Z unless filled) ] format = "C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155" h = if RUBY_VERSION >= "1.9" then arr.join else arr = arr.join("").split(//).map{|x| x[0]} arr.pack format end ret = h + "\0" * (512 - h.size) assert_equal(512, ret.size) ret end def tar_dir_header(name, prefix, mode, mtime) h = header("5", name, prefix, 0, mode, mtime) checksum = calc_checksum(h) header("5", name, prefix, 0, mode, mtime, checksum) end def tar_file_header(fname, dname, mode, length, mtime) h = header("0", fname, dname, length, mode, mtime) checksum = calc_checksum(h) header("0", fname, dname, length, mode, mtime, checksum) end def tar_symlink_header(fname, prefix, mode, mtime, linkname) h = header("2", fname, prefix, 0, mode, mtime, nil, linkname) checksum = calc_checksum(h) header("2", fname, prefix, 0, mode, mtime, checksum, linkname) end def to_oct(n, pad_size) "%0#{pad_size}o" % n end def util_entry(tar) io = TempIO.new tar header = Gem::Package::TarHeader.from io Gem::Package::TarReader::Entry.new header, io end def util_dir_entry util_entry tar_dir_header("foo", "bar", 0, Time.now) end def util_symlink_entry util_entry tar_symlink_header("foo", "bar", 0, Time.now, "link") end end PK!9&b b tar_reader.rbnu[# frozen_string_literal: true #-- # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. #++ ## # TarReader reads tar files and allows iteration over their items class Gem::Package::TarReader include Enumerable ## # Raised if the tar IO is not seekable class UnexpectedEOF < StandardError; end ## # Creates a new TarReader on +io+ and yields it to the block, if given. def self.new(io) reader = super return reader unless block_given? begin yield reader ensure reader.close end nil end ## # Creates a new tar file reader on +io+ which needs to respond to #pos, # #eof?, #read, #getc and #pos= def initialize(io) @io = io @init_pos = io.pos end ## # Close the tar file def close end ## # Iterates over files in the tarball yielding each entry 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? entry = Gem::Package::TarReader::Entry.new header, @io size = entry.header.size yield entry skip = (512 - (size % 512)) % 512 pending = size - entry.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 entry.close end end alias each_entry each ## # NOTE: Do not call #rewind during #each def rewind if @init_pos == 0 @io.rewind else @io.pos = @init_pos end end ## # Seeks through the tar file until it finds the +entry+ with +name+ and # yields it. Rewinds the tar file to the beginning when the block # terminates. def seek(name) # :yields: entry found = find do |entry| entry.full_name == name end return unless found return yield found ensure rewind end end require_relative 'tar_reader/entry' PK!   tar_writer.rbnu[# frozen_string_literal: true #-- # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. #++ ## # Allows writing of tar files class Gem::Package::TarWriter class FileOverflow < StandardError; end ## # IO wrapper that allows writing a limited amount of data class BoundedStream ## # Maximum number of bytes that can be written attr_reader :limit ## # Number of bytes written attr_reader :written ## # Wraps +io+ and allows up to +limit+ bytes to be written def initialize(io, limit) @io = io @limit = limit @written = 0 end ## # Writes +data+ onto the IO, raising a FileOverflow exception if the # number of bytes will be more than #limit def write(data) if data.bytesize + @written > @limit raise FileOverflow, "You tried to feed more data than fits in the file." end @io.write data @written += data.bytesize data.bytesize end end ## # IO wrapper that provides only #write class RestrictedStream ## # Creates a new RestrictedStream wrapping +io+ def initialize(io) @io = io end ## # Writes +data+ onto the IO def write(data) @io.write data end end ## # Creates a new TarWriter, yielding it if a block is given def self.new(io) writer = super return writer unless block_given? begin yield writer ensure writer.close end nil end ## # Creates a new TarWriter that will write to +io+ def initialize(io) @io = io @closed = false end ## # Adds file +name+ with permissions +mode+, and yields an IO for writing the # file to def add_file(name, mode) # :yields: io check_closed name, prefix = split_name name init_pos = @io.pos @io.write Gem::Package::TarHeader::EMPTY_HEADER # placeholder for the header yield RestrictedStream.new(@io) if block_given? size = @io.pos - init_pos - 512 remainder = (512 - (size % 512)) % 512 @io.write "\0" * remainder final_pos = @io.pos @io.pos = init_pos header = Gem::Package::TarHeader.new :name => name, :mode => mode, :size => size, :prefix => prefix, :mtime => Gem.source_date_epoch @io.write header @io.pos = final_pos self end ## # Adds +name+ with permissions +mode+ to the tar, yielding +io+ for writing # the file. The +digest_algorithm+ is written to a read-only +name+.sum # file following the given file contents containing the digest name and # hexdigest separated by a tab. # # The created digest object is returned. def add_file_digest(name, mode, digest_algorithms) # :yields: io digests = digest_algorithms.map do |digest_algorithm| digest = digest_algorithm.new digest_name = if digest.respond_to? :name digest.name else digest_algorithm.class.name[/::([^:]+)\z/, 1] end [digest_name, digest] end digests = Hash[*digests.flatten] add_file name, mode do |io| Gem::Package::DigestIO.wrap io, digests do |digest_io| yield digest_io end end digests end ## # Adds +name+ with permissions +mode+ to the tar, yielding +io+ for writing # the file. The +signer+ is used to add a digest file using its # digest_algorithm per add_file_digest and a cryptographic signature in # +name+.sig. If the signer has no key only the checksum file is added. # # Returns the digest. def add_file_signed(name, mode, signer) digest_algorithms = [ signer.digest_algorithm, Gem::Security.create_digest('SHA512'), ].compact.uniq digests = add_file_digest name, mode, digest_algorithms do |io| yield io end signature_digest = digests.values.compact.find do |digest| digest_name = if digest.respond_to? :name digest.name else digest.class.name[/::([^:]+)\z/, 1] end digest_name == signer.digest_name end raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest if signer.key signature = signer.sign signature_digest.digest add_file_simple "#{name}.sig", 0444, signature.length do |io| io.write signature end end digests end ## # Add file +name+ with permissions +mode+ +size+ bytes long. Yields an IO # to write the file to. def add_file_simple(name, mode, size) # :yields: io check_closed name, prefix = split_name name header = Gem::Package::TarHeader.new(:name => name, :mode => mode, :size => size, :prefix => prefix, :mtime => Gem.source_date_epoch).to_s @io.write header os = BoundedStream.new @io, size yield os if block_given? min_padding = size - os.written @io.write("\0" * min_padding) remainder = (512 - (size % 512)) % 512 @io.write("\0" * remainder) self end ## # Adds symlink +name+ with permissions +mode+, linking to +target+. def add_symlink(name, target, mode) check_closed name, prefix = split_name name header = Gem::Package::TarHeader.new(:name => name, :mode => mode, :size => 0, :typeflag => "2", :linkname => target, :prefix => prefix, :mtime => Gem.source_date_epoch).to_s @io.write header self end ## # Raises IOError if the TarWriter is closed def check_closed raise IOError, "closed #{self.class}" if closed? end ## # Closes the TarWriter def close check_closed @io.write "\0" * 1024 flush @closed = true end ## # Is the TarWriter closed? def closed? @closed end ## # Flushes the TarWriter's IO def flush check_closed @io.flush if @io.respond_to? :flush end ## # Creates a new directory in the tar file +name+ with +mode+ def mkdir(name, mode) check_closed name, prefix = split_name(name) header = Gem::Package::TarHeader.new :name => name, :mode => mode, :typeflag => "5", :size => 0, :prefix => prefix, :mtime => Gem.source_date_epoch @io.write header self end ## # Splits +name+ into a name and prefix that can fit in the TarHeader def split_name(name) # :nodoc: if name.bytesize > 256 raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)") end prefix = '' if name.bytesize > 100 parts = name.split('/', -1) # parts are never empty here name = parts.pop # initially empty for names with a trailing slash ("foo/.../bar/") prefix = parts.join('/') # if empty, then it's impossible to split (parts is empty too) while !parts.empty? && (prefix.bytesize > 155 || name.empty?) name = parts.pop + '/' + name prefix = parts.join('/') end if name.bytesize > 100 or prefix.empty? raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)") end if prefix.bytesize > 155 raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)") end end return name, prefix end end PK!&-GG source.rbnu[# frozen_string_literal: true class Gem::Package::Source # :nodoc: end PK!Waafile_source.rbnu[# frozen_string_literal: true ## # The primary source of gems is a file on disk, including all usages # internal to rubygems. # # This is a private class, do not depend on it directly. Instead, pass a path # object to `Gem::Package.new`. class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all attr_reader :path def initialize(path) @path = path end def start @start ||= File.read path, 20 end def present? File.exist? path end def with_write_io(&block) File.open path, 'wb', &block end def with_read_io(&block) File.open path, 'rb', &block end end PK!>d tar_header.rbnu[# frozen_string_literal: true #-- # Copyright (C) 2004 Mauricio Julio Fernández Pradier # See LICENSE.txt for additional licensing information. #++ ## #-- # struct tarfile_entry_posix { # char name[100]; # ASCII + (Z unless filled) # char mode[8]; # 0 padded, octal, null # char uid[8]; # ditto # char gid[8]; # ditto # char size[12]; # 0 padded, octal, null # char mtime[12]; # 0 padded, octal, null # char checksum[8]; # 0 padded, octal, null, space # char typeflag[1]; # file: "0" dir: "5" # char linkname[100]; # ASCII + (Z unless filled) # char magic[6]; # "ustar\0" # char version[2]; # "00" # char uname[32]; # ASCIIZ # char gname[32]; # ASCIIZ # char devmajor[8]; # 0 padded, octal, null # char devminor[8]; # o padded, octal, null # char prefix[155]; # ASCII + (Z unless filled) # }; #++ # A header for a tar file class Gem::Package::TarHeader ## # Fields in the tar header FIELDS = [ :checksum, :devmajor, :devminor, :gid, :gname, :linkname, :magic, :mode, :mtime, :name, :prefix, :size, :typeflag, :uid, :uname, :version, ].freeze ## # Pack format for a tar header PACK_FORMAT = 'a100' + # name 'a8' + # mode 'a8' + # uid 'a8' + # gid 'a12' + # size 'a12' + # mtime 'a7a' + # chksum 'a' + # typeflag 'a100' + # linkname 'a6' + # magic 'a2' + # version 'a32' + # uname 'a32' + # gname 'a8' + # devmajor 'a8' + # devminor 'a155' # prefix ## # Unpack format for a tar header UNPACK_FORMAT = 'A100' + # name 'A8' + # mode 'A8' + # uid 'A8' + # gid 'A12' + # size 'A12' + # mtime 'A8' + # checksum 'A' + # typeflag 'A100' + # linkname 'A6' + # magic 'A2' + # version 'A32' + # uname 'A32' + # gname 'A8' + # devmajor 'A8' + # devminor 'A155' # prefix attr_reader(*FIELDS) EMPTY_HEADER = ("\0" * 512).freeze # :nodoc: ## # Creates a tar header from IO +stream+ def self.from(stream) header = stream.read 512 empty = (EMPTY_HEADER == header) fields = header.unpack UNPACK_FORMAT new :name => fields.shift, :mode => strict_oct(fields.shift), :uid => oct_or_256based(fields.shift), :gid => oct_or_256based(fields.shift), :size => strict_oct(fields.shift), :mtime => strict_oct(fields.shift), :checksum => strict_oct(fields.shift), :typeflag => fields.shift, :linkname => fields.shift, :magic => fields.shift, :version => strict_oct(fields.shift), :uname => fields.shift, :gname => fields.shift, :devmajor => strict_oct(fields.shift), :devminor => strict_oct(fields.shift), :prefix => fields.shift, :empty => empty end def self.strict_oct(str) return str.strip.oct if str.strip =~ /\A[0-7]*\z/ raise ArgumentError, "#{str.inspect} is not an octal string" end def self.oct_or_256based(str) # \x80 flags a positive 256-based number # \ff flags a negative 256-based number # In case we have a match, parse it as a signed binary value # in big-endian order, except that the high-order bit is ignored. return str.unpack('N2').last if str =~ /\A[\x80\xff]/n strict_oct(str) end ## # Creates a new TarHeader using +vals+ def initialize(vals) unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] raise ArgumentError, ":name, :size, :prefix and :mode required" end vals[:uid] ||= 0 vals[:gid] ||= 0 vals[:mtime] ||= 0 vals[:checksum] ||= "" vals[:typeflag] = "0" if vals[:typeflag].nil? || vals[:typeflag].empty? vals[:magic] ||= "ustar" vals[:version] ||= "00" vals[:uname] ||= "wheel" vals[:gname] ||= "wheel" vals[:devmajor] ||= 0 vals[:devminor] ||= 0 FIELDS.each do |name| instance_variable_set "@#{name}", vals[name] end @empty = vals[:empty] end ## # Is the tar entry empty? def empty? @empty end def ==(other) # :nodoc: self.class === other and @checksum == other.checksum and @devmajor == other.devmajor and @devminor == other.devminor and @gid == other.gid and @gname == other.gname and @linkname == other.linkname and @magic == other.magic and @mode == other.mode and @mtime == other.mtime and @name == other.name and @prefix == other.prefix and @size == other.size and @typeflag == other.typeflag and @uid == other.uid and @uname == other.uname and @version == other.version end def to_s # :nodoc: update_checksum header end ## # Updates the TarHeader's checksum def update_checksum header = header " " * 8 @checksum = oct calculate_checksum(header), 6 end private def calculate_checksum(header) header.unpack("C*").inject {|a, b| a + b } end def header(checksum = @checksum) header = [ name, oct(mode, 7), oct(uid, 7), oct(gid, 7), oct(size, 11), oct(mtime, 11), checksum, " ", typeflag, linkname, magic, oct(version, 2), uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix, ] header = header.pack PACK_FORMAT header << ("\0" * ((512 - header.size) % 512)) end def oct(num, len) "%0#{len}o" % num end end PK!Cold.rbnu[# frozen_string_literal: true #-- # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # All rights reserved. # See LICENSE.txt for permissions. #++ ## # The format class knows the guts of the ancient .gem file format and provides # the capability to read such ancient gems. # # Please pretend this doesn't exist. class Gem::Package::Old < Gem::Package undef_method :spec= ## # Creates a new old-format package reader for +gem+. Old-format packages # cannot be written. def initialize(gem, security_policy) require 'fileutils' require 'zlib' Gem.load_yaml @contents = nil @gem = gem @security_policy = security_policy @spec = nil end ## # A list of file names contained in this gem def contents verify return @contents if @contents @gem.with_read_io do |io| read_until_dashes io # spec header = file_list io @contents = header.map {|file| file['path'] } end end ## # Extracts the files in this package into +destination_dir+ def extract_files(destination_dir) verify errstr = "Error reading files from gem" @gem.with_read_io do |io| read_until_dashes io # spec header = file_list io raise Gem::Exception, errstr unless header header.each do |entry| full_name = entry['path'] destination = install_location full_name, destination_dir file_data = String.new read_until_dashes io do |line| file_data << line end file_data = file_data.strip.unpack("m")[0] file_data = Zlib::Inflate.inflate file_data raise Gem::Package::FormatError, "#{full_name} in #{@gem} is corrupt" if file_data.length != entry['size'].to_i FileUtils.rm_rf destination FileUtils.mkdir_p File.dirname(destination), :mode => dir_mode && 0755 File.open destination, 'wb', file_mode(entry['mode']) do |out| out.write file_data end verbose destination end end rescue Zlib::DataError raise Gem::Exception, errstr end ## # Reads the file list section from the old-format gem +io+ def file_list(io) # :nodoc: header = String.new read_until_dashes io do |line| header << line end Gem::SafeYAML.safe_load header end ## # Reads lines until a "---" separator is found def read_until_dashes(io) # :nodoc: while (line = io.gets) && line.chomp.strip != "---" do yield line if block_given? end end ## # Skips the Ruby self-install header in +io+. def skip_ruby(io) # :nodoc: loop do line = io.gets return if line.chomp == '__END__' break unless line end raise Gem::Exception, "Failed to find end of Ruby script while reading gem" end ## # The specification for this gem def spec verify return @spec if @spec yaml = String.new @gem.with_read_io do |io| skip_ruby io read_until_dashes io do |line| yaml << line end end begin @spec = Gem::Specification.from_yaml yaml rescue YAML::SyntaxError raise Gem::Exception, "Failed to parse gem specification out of gem file" end rescue ArgumentError raise Gem::Exception, "Failed to parse gem specification out of gem file" end ## # Raises an exception if a security policy that verifies data is active. # Old format gems cannot be verified as signed. def verify return true unless @security_policy raise Gem::Security::Exception, 'old format gems do not contain signatures and cannot be verified' if @security_policy.verify_data true end end PK!$B6-- io_source.rbnu[# frozen_string_literal: true ## # Supports reading and writing gems from/to a generic IO object. This is # useful for other applications built on top of rubygems, such as # rubygems.org. # # This is a private class, do not depend on it directly. Instead, pass an IO # object to `Gem::Package.new`. class Gem::Package::IOSource < Gem::Package::Source # :nodoc: all attr_reader :io def initialize(io) @io = io end def start @start ||= begin if io.pos > 0 raise Gem::Package::Error, "Cannot read start unless IO is at start" end value = io.read 20 io.rewind value end end def present? true end def with_read_io yield io ensure io.rewind end def with_write_io yield io ensure io.rewind end def path end end PK!̊SS digest_io.rbnu[# frozen_string_literal: true ## # IO wrapper that creates digests of contents written to the IO it wraps. class Gem::Package::DigestIO ## # Collected digests for wrapped writes. # # { # 'SHA1' => #, # 'SHA512' => #, # } attr_reader :digests ## # Wraps +io+ and updates digest for each of the digest algorithms in # the +digests+ Hash. Returns the digests hash. Example: # # io = StringIO.new # digests = { # 'SHA1' => OpenSSL::Digest.new('SHA1'), # 'SHA512' => OpenSSL::Digest.new('SHA512'), # } # # Gem::Package::DigestIO.wrap io, digests do |digest_io| # digest_io.write "hello" # end # # digests['SHA1'].hexdigest #=> "aaf4c61d[...]" # digests['SHA512'].hexdigest #=> "9b71d224[...]" def self.wrap(io, digests) digest_io = new io, digests yield digest_io return digests end ## # Creates a new DigestIO instance. Using ::wrap is recommended, see the # ::wrap documentation for documentation of +io+ and +digests+. def initialize(io, digests) @io = io @digests = digests end ## # Writes +data+ to the underlying IO and updates the digests def write(data) result = @io.write data @digests.each do |_, digest| digest << data end result end end PK!a  tar_reader/entry.rbnu[PK!dyffW tar_test_case.rbnu[PK!9&b b tar_reader.rbnu[PK!   #tar_writer.rbnu[PK!&-GG Asource.rbnu[PK!WaacBfile_source.rbnu[PK!>d Etar_header.rbnu[PK!C\old.rbnu[PK!$B6-- kio_source.rbnu[PK!̊SS ndigest_io.rbnu[PK t