class Android::AXMLParser
binary AXML parser @see android.googlesource.com/platform/frameworks/base.git Android
OS frameworks source @note
refer to Android OS framework code: /frameworks/base/include/androidfw/ResourceTypes.h, /frameworks/base/libs/androidfw/ResourceTypes.cpp
Constants
- HEADER
- TAG_CDSECT
- TAG_END
- TAG_END_NAMESPACE
- TAG_ENTITY_REF
- TAG_START
- TAG_START_NAMESPACE
- TAG_TEXT
- VAL_TYPE_ATTRIBUTE
- VAL_TYPE_DIMENSION
- VAL_TYPE_FLOAT
- VAL_TYPE_FRACTION
- VAL_TYPE_INT_BOOLEAN
- VAL_TYPE_INT_COLOR_ARGB4
- VAL_TYPE_INT_COLOR_ARGB8
- VAL_TYPE_INT_COLOR_RGB4
- VAL_TYPE_INT_COLOR_RGB8
- VAL_TYPE_INT_DEC
- VAL_TYPE_INT_HEX
- VAL_TYPE_NULL
- VAL_TYPE_REFERENCE
- VAL_TYPE_STRING
Attributes
metadata[R]
@return [Array<String>] strings defined in axml
strings[R]
@return [Array<String>] strings defined in axml
Public Class Methods
axml?(data)
click to toggle source
# File lib/android/axml_parser.rb, line 18 def self.axml?(data) (data[0..3] == HEADER) end
new(axml)
click to toggle source
@param [String] axml binary xml data
# File lib/android/axml_parser.rb, line 52 def initialize(axml) @io = StringIO.new(axml, "rb") @strings = [] end
Public Instance Methods
convert_value(val_str_id, flags, val)
click to toggle source
# File lib/android/axml_parser.rb, line 219 def convert_value(val_str_id, flags, val) unless val_str_id == 0xFFFFFFFF value = @strings[val_str_id] else type = flags >> 24 case type when VAL_TYPE_NULL value = nil when VAL_TYPE_REFERENCE value = "@%#x" % val # refered resource id. when VAL_TYPE_INT_DEC value = val when VAL_TYPE_INT_HEX value = "%#x" % val when VAL_TYPE_INT_BOOLEAN value = ((val == 0xFFFFFFFF) || (val==1)) ? true : false else value = "[%#x, flag=%#x]" % [val, flags] end end end
current_nesting_level()
click to toggle source
# File lib/android/axml_parser.rb, line 215 def current_nesting_level @parents.length end
get_namespace_prefix(ns_uri)
click to toggle source
find the first declared namespace prefix for a URI
# File lib/android/axml_parser.rb, line 188 def get_namespace_prefix(ns_uri) # a namespace might be given as a URI or as a reference to a previously defined namespace. # E.g. like this: # <tag1 xmlns:android="http://schemas.android.com/apk/res/android"> # <tag2 xmlns:n0="android" /> # </tag1> # Walk recursively through the namespaces to # transitively resolve URIs that just pointed to previous namespace prefixes current_uri = ns_uri @namespaces.reverse.each do |ns| if ns[:prefix] == current_uri # we found a previous namespace declaration that was referenced to by # the current_uri. Proceed with this namespace’s URI and try to see if this # is also just a reference to a previous namespace current_uri = ns[:uri] end end # current_uri now contains the URI of the topmost namespace declaration. # We’ll take the prefix of this and return it. @namespaces.reverse.each do |ns| return ns[:prefix] if ns[:uri] == current_uri end raise "Could not resolve URI #{ns_uri} to a namespace prefix" end
parse()
click to toggle source
parse binary xml @return [REXML::Document]
# File lib/android/axml_parser.rb, line 59 def parse @doc = REXML::Document.new @doc << REXML::XMLDecl.new @num_str = word(4*4) @xml_offset = word(3*4) @parents = [@doc] @namespaces = [] @metadata = [] parse_strings parse_tags @doc end
parse_attribute()
click to toggle source
parse attribute of a element
# File lib/android/axml_parser.rb, line 175 def parse_attribute ns_id, name_id, val_str_id, flags, val = @io.read(4*5).unpack("V*") key = @strings[name_id] unless ns_id == 0xFFFFFFFF namespace_uri = @strings[ns_id] prefix = get_namespace_prefix(namespace_uri) key = "#{prefix}:#{key}" end value = convert_value(val_str_id, flags, val) return key, value, (flags >> 24) end
parse_strings()
click to toggle source
relace string table parser
# File lib/android/axml_parser.rb, line 92 def parse_strings strpool = Resource::ResStringPool.new(@io.string, 8) # ugh! @strings = strpool.strings end
short(offset)
click to toggle source
read 2byte as short integer @param [Integer] offset offset from top position. current position is used if ofset is nil @return [Integer] little endian unsign short value
# File lib/android/axml_parser.rb, line 86 def short(offset) @io.pos = offset unless offset.nil? @io.read(2).unpack("v")[0] end
word(offset=nil)
click to toggle source
read one word(4byte) as integer @param [Integer] offset offset from top position. current position is used if ofset is nil @return [Integer] little endian word value
# File lib/android/axml_parser.rb, line 78 def word(offset=nil) @io.pos = offset unless offset.nil? @io.read(4).unpack("V")[0] end