class Android::Resource::ResTablePackage

Attributes

name[R]

Public Instance Methods

find(res_id, opts={}) click to toggle source

find resource by resource id @param [String] res_id (like ‘@0x7f010001’ or ‘@string/key’) @param [Hash] opts option @option opts [String] :lang language code like ‘ja’, ‘cn’… @option opts [String] :contry cantry code like ‘jp’… @raise [ArgumentError] invalid id format @note

This method only support string and drawable resource for now.

@note

Always return nil if assign not string type res id.
# File lib/android/resource.rb, line 219
def find(res_id, opts={})
  hex_id = strid2int(res_id)
  tid = ((hex_id&0xff0000) >>16)
  key = hex_id&0xffff

  case type(tid)
  when 'string'
    return find_res_string(key, opts)
  when 'drawable', 'mipmap'
    drawables = []
    @types[tid].each do |type|
      unless type[key].nil?
        drawables << @global_string_pool.strings[type[key].val.data]
      end
    end
    return drawables
  else
    nil
  end
end
global_string_pool=(pool) click to toggle source
# File lib/android/resource.rb, line 203
def global_string_pool=(pool)
  @global_string_pool = pool
  extract_res_strings
end
inspect() click to toggle source
# File lib/android/resource.rb, line 378
def inspect
  "<ResTablePackage offset:%#08x, size:%#x, name:\"%s\">" % [@offset, @size, @name]
end
key(id) click to toggle source
# File lib/android/resource.rb, line 303
def key(id)
  key_strings[id]
end
key_id(str) click to toggle source
# File lib/android/resource.rb, line 306
def key_id(str)
  raise NotFoundError unless key_strings.include? str
  key_strings.index(str)
end
key_strings() click to toggle source
# File lib/android/resource.rb, line 300
def key_strings
  @key_strings.strings
end
res_hex_id(readable_id, opt={}) click to toggle source
# File lib/android/resource.rb, line 281
def res_hex_id(readable_id, opt={})
  dummy, typestr, keystr = readable_id.match(/^@?(\w+)\/(\w+)$/).to_a
  tid = type_id(typestr)
  raise NotFoundError unless @types.has_key?(tid)
  keyid = @types[tid][0].keys[keystr]
  raise NotFoundError if keyid.nil?
  "@0x7f%02x%04x" % [tid, keyid]
end
res_readable_id(hex_id) click to toggle source
# File lib/android/resource.rb, line 271
def res_readable_id(hex_id)
  if hex_id.kind_of? String
    hex_id = hex_id.sub(/^@/,'').to_i(16)
  end
  tid = ((hex_id&0xff0000) >>16)
  key = hex_id&0xffff
  raise NotFoundError if !@types.has_key?(tid) || @types[tid][0][key].nil?
  keyid= @types[tid][0][key].key # ugh!
  "@#{type(tid)}/#{key(keyid)}"
end
res_types() click to toggle source
# File lib/android/resource.rb, line 240
def res_types
end
strid2int(res_id) click to toggle source

convert string resource id to fixnum @param [String] res_id (like ‘@0x7f010001’ or ‘@string/key’) @return [Fixnum] integer id (like 0x7f010001) @raise [ArgumentError] invalid format

# File lib/android/resource.rb, line 260
def strid2int(res_id)
  case res_id
  when /^@?0x[0-9a-fA-F]{8}$/
    return res_id.sub(/^@/,'').to_i(16)
  when /^@?\w+\/\w+/
    return res_hex_id(res_id).sub(/^@/,'').to_i(16)
  else
    raise ArgumentError
  end
end
type(id) click to toggle source
# File lib/android/resource.rb, line 293
def type(id)
  type_strings[id-1]
end
type_id(str) click to toggle source
# File lib/android/resource.rb, line 296
def type_id(str)
  raise NotFoundError unless type_strings.include? str
  type_strings.index(str) + 1
end
type_strings() click to toggle source
# File lib/android/resource.rb, line 290
def type_strings
  @type_strings.strings
end

Private Instance Methods

extract_res_strings() click to toggle source
# File lib/android/resource.rb, line 347
def extract_res_strings
  @res_strings_lang = {}
  @res_strings_contry = {}
  begin
    type = type_id('string')
  rescue NotFoundError
    return
  end
  @types[type_id('string')].each do |type|
    str_hash  = {}
    type.entry_count.times do |i|
      entry = type[i]
      if entry.nil?
        str_hash[i] = nil
      else
        str_hash[i] = @global_string_pool.strings[type[i].val.data]
      end
    end
    lang = type.config.locale_lang
    contry = type.config.locale_contry
    if lang.nil? && contry.nil?
      @res_strings_default ||= {}
      @res_strings_default.merge!(str_hash) { |_key, val1, _val2| val1 }
    else
      @res_strings_lang[lang] = str_hash unless lang.nil?
      @res_strings_contry[contry] = str_hash unless contry.nil?
    end
  end
end
find_res_string(key, opts={}) click to toggle source
# File lib/android/resource.rb, line 243
def find_res_string(key, opts={})
  unless opts[:lang].nil?
    string = @res_strings_lang[opts[:lang]]
  end
  unless opts[:contry].nil?
    string = @res_strings_contry[opts[:contry]]
  end
  string = @res_strings_default if string.nil?
  raise NotFoundError unless string.has_key? key
  return string[key]
end
parse() click to toggle source
Calls superclass method Android::Resource::ChunkHeader#parse
# File lib/android/resource.rb, line 311
def parse
  super
  @id = read_int32
  @name = @data_io.read(256).force_encoding(Encoding::UTF_16LE)
  @name.encode!(Encoding::UTF_8).strip!
  type_strings_offset = read_int32
  @type_strings = ResStringPool.new(@data, @offset + type_strings_offset)
  @last_public_type = read_int32
  key_strings_offset = read_int32
  @key_strings = ResStringPool.new(@data, @offset + key_strings_offset)
  @last_public_key = read_int32

  offset = @offset + key_strings_offset + @key_strings.size

  @types = {}
  @specs = {}
  while offset < (@offset + @size)
    type = @data[offset, 2].unpack('v')[0]
    case type
    when 0x0201 # RES_TABLE_TYPE_TYPE
      type = ResTableType.new(@data, offset, self)
      offset += type.size
      @types[type.id] = [] if @types[type.id].nil?
      @types[type.id] << type
    when 0x0202 # RES_TABLE_TYPE_SPEC_TYPE`
      spec = ResTableTypeSpec.new(@data, offset)
      offset += spec.size
      @specs[spec.id] = [] if @specs[spec.id].nil?
      @specs[spec.id] << spec
    else
      raise "chunk type error: type:%#04x" % type
    end
  end
end