class Distillery::ROMArchive

Deal with ROM embedded in an archive file.

Constants

EXTENSIONS

Allowed extension names

PREFERED

Prefered

Attributes

file[R]

Archive file @return [String]

Public Class Methods

archive?(file, archives: EXTENSIONS) click to toggle source

Check using extension if file is an archive

@param file [String] file to test

@return [Boolean]

# File lib/distillery/rom-archive.rb, line 48
def self.archive?(file, archives: EXTENSIONS)
    return false if archives.nil?
    archives.include?(File.extname(file)[1..-1])
end
bufsize=(size) click to toggle source

Set buffer size used when processing archive content

@param size [Integer] size in kbytes

# File lib/distillery/rom-archive.rb, line 37
def self.bufsize=(size)
    @@bufsize = size << 10
end
from_file(file, headers: nil) click to toggle source

Read ROM archive from file

@param file [String] path to archive file @param headers [Array,nil,false] header definition list

@return [ROMArchive]

# File lib/distillery/rom-archive.rb, line 61
def self.from_file(file, headers: nil)
    # Create archive object
    archive = self.new(file)

    #
    Distillery::Archiver.for(file).each {|entry, i|
        path = ROM::Path::Archive.new(archive, entry)
        archive[entry] = ROM.new(path, **ROM.info(i, headers: headers))
    }

    archive
end
new(file) click to toggle source

Create an empty archive

@param file [String] archive file

# File lib/distillery/rom-archive.rb, line 79
def initialize(file)
    @file   = file
    @roms   = {}
end

Public Instance Methods

==(o) click to toggle source

Test if archive is identical (same file, same content)

@param o [ROMArchive] other archive @return [Boolean]

# File lib/distillery/rom-archive.rb, line 123
def ==(o)
    o.kind_of?(ROMArchive)                                          &&
        (self.entries.to_set == o.entries.to_set)                   &&
        self.entries.all? {|entry| self[entry].same?(o[entry]) }
end
[](entry) click to toggle source

Get ROM by entry

@param entry [String] archive entry @return [ROM]

# File lib/distillery/rom-archive.rb, line 171
def [](entry)
    @roms[entry]
end
[]=(entry, rom) click to toggle source

Assign a ROM to the archive

@param entry [String] archive entry name @param rom [ROM] ROM

@return [ROM] the assigned ROM

# File lib/distillery/rom-archive.rb, line 99
def []=(entry, rom)
    @roms.merge!(entry => rom) {|key, old_rom, new_rom|
        warn "replacing ROM entry \"#{key}\" (#{to_s})"
        new_rom
    }
    rom
end
delete!(entry) click to toggle source

Delete entry

@param entry [String] archive entry

@return [Boolean] operation status

# File lib/distillery/rom-archive.rb, line 182
def delete!(entry)
    Distillery::Archiver.for(@file) {|archive|
        if archive.delete!(entry)
            if archive.empty?
                File.unlink(@file)
            end
            true
        else
            false
        end
    }
end
each() { |r| ... } click to toggle source

Iterate over each ROM

@yieldparam rom [ROM]

@return [self,Enumerator]

# File lib/distillery/rom-archive.rb, line 143
def each
    block_given? ? @roms.each_value {|r| yield(r) }
                 : @roms.each_value
end
entries() click to toggle source

List of archive entries

@return [Array<String>]

# File lib/distillery/rom-archive.rb, line 161
def entries
    @roms.keys
end
extract(entry, to, length = nil, offset = 0, force: false) click to toggle source

Extract rom to the filesystem

@param entry [String] entry (rom) to extract @param to [String] destination @param length [Integer,nil] data length to be copied @param offset [Integer] data offset @param force [Boolean] remove previous file if necessary

@return [Boolean] operation status

# File lib/distillery/rom-archive.rb, line 220
def extract(entry, to, length = nil, offset = 0, force: false)
    Distillery::Archiver.for(@file).reader(entry) {|i|
        # Copy file
        begin
            op = force ? File::TRUNC : File::EXCL
            File.open(to, File::CREAT|File::WRONLY|op) {|o|
                while (skip = [ offset, @@bufsize ].min) > 0
                    i.read(skip)
                    offset -= skip
                end

                if length.nil?
                    while data = i.read(@@bufsize)
                        o.write(data)
                    end
                else
                    while ((sz = [ length, @@bufsize ].min) > 0) &&
                          (data = i.read(sz))
                        o.write(data)
                        length -= sz
                    end
                end
            }
        rescue Errno::EEXIST
            return false
        end
        
        # Assuming entries are unique
        return true
    }
    
    # Was not found
    return false
end
reader(entry, &block) click to toggle source

Read ROM. @note Can be costly, to be avoided.

@param entry [String] archive entry

@yieldparam [#read] io stream for reading

@return block value

# File lib/distillery/rom-archive.rb, line 205
def reader(entry, &block)
    Distillery::Archiver.for(@file).reader(entry, &block)
end
roms() click to toggle source

List of ROMs

@return [Array<ROM>]

# File lib/distillery/rom-archive.rb, line 152
def roms
    @roms.values
end
same_file?(o) click to toggle source

Same archive file

@param o [ROMArchive] other archive @return [Boolean]

# File lib/distillery/rom-archive.rb, line 113
def same_file?(o)
    self.file == o.file
end
size() click to toggle source

Archive size (number of entries) @return [Integer]

# File lib/distillery/rom-archive.rb, line 132
def size
    @roms.size
end
to_s() click to toggle source

String representation of the archive @return [String]

# File lib/distillery/rom-archive.rb, line 87
def to_s
    @file
end