def read_table table
      table_offset = @archive_header.send "#{table}_table_offset"
      @io.seek @user_header.archive_header_offset + table_offset
      table_entries = @archive_header.send "#{table}_table_entries"
      data = @io.read table_entries * 16
      key = Hashing::hash_for :table, "(#{table} table)"
      data = Hashing::decrypt data, key
      klass = table == :hash ? HashTableEntry : BlockTableEntry
      (0...table_entries).map do |i|
        klass.read(data[i * 16, 16])
      end
    end
def read_table table
      table_offset = @archive_header.send "#{table}_table_offset"
      @io.seek @user_header.archive_header_offset + table_offset
      table_entries = @archive_header.send "#{table}_table_entries"
      data = @io.read table_entries * 16
      key = Hashing::hash_for :table, "(#{table} table)"
      data = Hashing::decrypt data, key
      klass = table == :hash ? HashTableEntry : BlockTableEntry
      (0...table_entries).map do |i|
        klass.read(data[i * 16, 16])
      end
    end
In general, MPQ archives start with either the MPQ header, or they start
 with a user header which points to the MPQ header. StarCraft 2 replays
 always have a user header, so we don't even bother to check here.

 The MPQ header points to two very helpful parts of the MPQ archive: the
 hash table, which tells us where the contents of files are found, and the
 block table, which holds said contents of files. That's all we need to
 read up front.
 Both the hash and block tables' contents are hashed (in the same way), so
 we need to decrypt them in order to read their contents.