
#==============================================================================#
# exerb/archive.rb
# $Id: archive.rb,v 1.5 2002/09/20 09:12:12 yuya Exp $
#==============================================================================#

#==============================================================================#
# Exerb Module
module Exerb

  #============================================================================#
  # Archive Class
  class Archive

    #==========================================================================#
    # Initialize Method

    def initialize
      @kcode  = 'none'
      @script = []
      @dll    = []
    end

    #==========================================================================#
    # Instance Methods

    def set_kcode(kcode)
      @kcode = kcode
    end

    def add_script(name, filepath)
      @script << Script.new(name, filepath)
    end

    def add_dll(name, filepath)
      @dll << DLL.new(name, filepath)
    end

    def pack
      name_table   = NameTable.new
      script_table = ScriptTable.new
      dll_table    = DLLTable.new

      @script.each { |script|
        script_table.add(name_table.add(script.name), script.pack)
      }

      @dll.each { |dll|
        dll_table.add(name_table.add(dll.name), dll.pack)
      }

      packed_name_table   = name_table.pack
      packed_script_table = script_table.pack
      packed_dll_table    = dll_table.pack

      archive_header = ArchiveHeader.new
      archive_header.signature        = 'RUBY'
      archive_header.time_date_stamp  = Time.now.to_i
      archive_header.offset_to_name   = ArchiveHeader.size
      archive_header.number_of_name   = name_table.size
      archive_header.offset_to_script = ArchiveHeader.size + packed_name_table.size
      archive_header.number_of_script = script_table.size
      archive_header.offset_to_dll    = ArchiveHeader.size + packed_name_table.size + packed_script_table.size
      archive_header.number_of_dll    = dll_table.size

      archive_header.options = case @kcode
                               when 'none' then ArchiveHeader::OPTIONS_KCODE_NONE
                               when 'euc'  then ArchiveHeader::OPTIONS_KCODE_EUC
                               when 'sjis' then ArchiveHeader::OPTIONS_KCODE_SJIS
                               when 'utf8' then ArchiveHeader::OPTIONS_KCODE_UTF8
                               else raise 'invalid char-set'
                               end

      return archive_header.pack + packed_name_table + packed_script_table + packed_dll_table
    end

    def output(io)
      io.print(self.pack)
    end

    def output_to_file(filepath)
      File.open(filepath, 'wb') { |file|
        self.output(file)
      }
    end

    #==========================================================================#
    # Script Class
    class Script

      #========================================================================#
      # Initialize Method

      def initialize(name, filepath)
        @name     = name
        @filepath = filepath
      end

      #========================================================================#
      # Accessor

      attr_reader :name, :filepath

      #========================================================================#
      # Instance Methods

      def pack
        return File.open(filepath, 'rb') { |file| file.read }
      end

    end # Script

    #==========================================================================#
    # DLL Class
    class DLL

      #========================================================================#
      # Initialize Method

      def initialize(name, filepath)
        @name     = name
        @filepath = filepath
      end

      #========================================================================#
      # Accessor

      attr_reader :name, :filepath

      #========================================================================#
      # Instance Methods

      def pack
        return File.open(filepath, 'rb') { |file| file.read }
      end

    end # DLL

  end # Archive

end # Exerb

#==============================================================================#
#==============================================================================#
