class Distillery::DatFile

Handle information from DAT file

Attributes

date[R]

Datfile date

@return [String,nil]

description[R]

Datfile description

@return [String,nil]

games[R]

@return [Set<Games>]

name[R]

Datfile name

@return [String,nil]

roms[R]

@return [Vault]

url[R]

Datfile url

@return [String,nil]

version[R]

Datfile version

@return [String,nil]

Public Class Methods

new(datfile) click to toggle source

Create DatFile representation from file.

@param datfile [String]

# File lib/distillery/datfile.rb, line 43
def initialize(datfile)
    @games     = Set.new
    @roms      = Vault::new
    @roms_game = {}

    if !FileTest.file?(datfile)
        raise ArgumentError, "DAT file is missing or not a regular file"
    end
    
    # Get datafile as XML document
    dat = Nokogiri::XML(File.read(datfile))

    dat.xpath('//header').each {|hdr|
        @name        = hdr.xpath('name'       )&.first&.content
        @description = hdr.xpath('description')&.first&.content
        @url         = hdr.xpath('url'        )&.first&.content
        @date        = hdr.xpath('date'       )&.first&.content
        @version     = hdr.xpath('version'    )&.first&.content
    }
    
    # Process each game elements
    dat.xpath('//game').each {|g|
        releases = g.xpath('release').map {|r|
            Release::new(r[:name], region: r[:region].upcase)
        }
        roms     = g.xpath('rom').map {|r|
            path = File.join(r[:name].split('\\'))
            ROM::new(ROM::Path::Virtual.new(path),
                     :size  => Integer(r[:size]),
                     :crc32 => r[:crc ],
                     :md5   => r[:md5 ],
                     :sha1  => r[:sha1])
        }
        game     = Game::new(g['name'], *roms, releases: releases,
                                                cloneof: g['cloneof'])

        roms.each {|rom|
            (@roms_game[rom.object_id] ||= []) << game
            @roms << rom
        }

        if @games.add?(game).nil?
            raise ContentError,
                  "Game '#{game}' defined multiple times in DAT file"
        end
    }
end

Public Instance Methods

clash(type = :fullname) click to toggle source

Identify ROM which have the same fullname/name but are different

@param type [:fullname, :name] Check by fullname or name

@return [Hash{String => Array<ROM>}]

# File lib/distillery/datfile.rb, line 97
def clash(type = :fullname)
    grp = case type
          when :fullname then @roms.each.group_by {|rom| rom.fullname      }
          when :name     then @roms.each.group_by {|rom| rom.name          }
          else raise ArgumentError
          end

    grp.select           {|_, roms| roms.size > 1 }
       .transform_values {|roms|
        lst = []
        while rom = roms.first do
            t, f = roms.partition {|r| r.same?(rom) }
            lst << t.first
            roms = f
        end
        lst
    }
end
each_game() { |g| ... } click to toggle source

Iterate over each game

@yieldparam game [Game]

@return [self,Enumerator]

# File lib/distillery/datfile.rb, line 143
def each_game
    block_given? ? @games.each {|g| yield(g) }
                 : @games.each
end
each_rom() { |r| ... } click to toggle source

Iterate over each ROM

@yieldparam rom [ROM]

@return [self,Enumerator]

# File lib/distillery/datfile.rb, line 127
def each_rom
    block_given? ? @roms.each {|r| yield(r) }
                 : @roms.each
end
getGames(rom) click to toggle source

Get Games to which this ROM belongs. @note This only works for ROMs created by the DatFile

@param rom [Rom]

@return [Array<Game>]

# File lib/distillery/datfile.rb, line 34
def getGames(rom)
    @roms_game[rom.object_id]
end
with_partial_checksum() click to toggle source

List of ROM with loosely defined (ie: with some missing checksum)

@return [Array<ROM>,nil]

# File lib/distillery/datfile.rb, line 22
def with_partial_checksum
    @roms.with_partial_checksum
end