1.0 The Example
We know from the Table header in our example that there is only one Package, so there can be only one Package chunk which is everything after the StringPool chunk.
0000000 02 00 0c 00 64 04 00 00 01 00 00 00 01 00 1c 00
0000010 d0 00 00 00 06 00 00 00 00 00 00 00 00 01 00 00
0000020 34 00 00 00 00 00 00 00 00 00 00 00 1d 00 00 00
0000030 3a 00 00 00 57 00 00 00 6d 00 00 00 8f 00 00 00
0000040 1a 1a 72 65 73 2f 64 72 61 77 61 62 6c 65 2d 6c
0000050 64 70 69 2f 69 63 6f 6e 2e 70 6e 67 00 1a 1a 72
0000060 65 73 2f 64 72 61 77 61 62 6c 65 2d 6d 64 70 69
0000070 2f 69 63 6f 6e 2e 70 6e 67 00 1a 1a 72 65 73 2f
0000080 64 72 61 77 61 62 6c 65 2d 68 64 70 69 2f 69 63
0000090 6f 6e 2e 70 6e 67 00 13 13 72 65 73 2f 6c 61 79
00000a0 6f 75 74 2f 6d 61 69 6e 2e 78 6d 6c 00 1f 1f 48
00000b0 65 6c 6c 6f 20 57 6f 72 6c 64 2c 20 50 65 6e 64
00000c0 72 61 67 6f 6e 41 63 74 69 76 69 74 79 21 00 09
00000d0 09 50 65 6e 64 72 61 67 6f 6e 00 00 00 02 1c 01
00000e0 88 03 00 00 7f 00 00 00 78 00 70 00 65 00 72 00
00000f0 2e 00 72 00 65 00 73 00 6f 00 75 00 72 00 63 00
0000100 65 00 73 00 2e 00 70 00 65 00 6e 00 64 00 72 00
0000110 61 00 67 00 6f 00 6e 00 00 00 00 00 00 00 00 00
0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001e0 00 00 00 00 00 00 00 00 1c 01 00 00 04 00 00 00
00001f0 6c 01 00 00 04 00 00 00 01 00 1c 00 50 00 00 00
0000200 04 00 00 00 00 00 00 00 00 01 00 00 2c 00 00 00
0000210 00 00 00 00 00 00 00 00 07 00 00 00 12 00 00 00
0000220 1b 00 00 00 04 04 61 74 74 72 00 08 08 64 72 61
0000230 77 61 62 6c 65 00 06 06 6c 61 79 6f 75 74 00 06
0000240 06 73 74 72 69 6e 67 00 01 00 1c 00 50 00 00 00
0000250 04 00 00 00 00 00 00 00 00 01 00 00 2c 00 00 00
0000260 00 00 00 00 00 00 00 00 07 00 00 00 0e 00 00 00
0000270 16 00 00 00 04 04 69 63 6f 6e 00 04 04 6d 61 69
0000280 6e 00 05 05 68 65 6c 6c 6f 00 08 08 61 70 70 5f
0000290 6e 61 6d 65 00 00 00 00 02 02 10 00 10 00 00 00
00002a0 01 00 00 00 00 00 00 00 02 02 10 00 14 00 00 00
00002b0 02 00 00 00 01 00 00 00 00 01 00 00 01 02 34 00
00002c0 48 00 00 00 02 00 00 00 01 00 00 00 38 00 00 00
00002d0 20 00 00 00 00 00 00 00 00 00 00 00 00 00 78 00
00002e0 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
00002f0 00 00 00 00 08 00 00 00 00 00 00 00 08 00 00 03
0000300 00 00 00 00 01 02 34 00 48 00 00 00 02 00 00 00
0000310 01 00 00 00 38 00 00 00 20 00 00 00 00 00 00 00
0000320 00 00 00 00 00 00 a0 00 00 00 00 00 00 00 00 00
0000330 04 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00
0000340 00 00 00 00 08 00 00 03 01 00 00 00 01 02 34 00
0000350 48 00 00 00 02 00 00 00 01 00 00 00 38 00 00 00
0000360 20 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 00
0000370 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
0000380 00 00 00 00 08 00 00 00 00 00 00 00 08 00 00 03
0000390 02 00 00 00 02 02 10 00 14 00 00 00 03 00 00 00
00003a0 01 00 00 00 00 00 00 00 01 02 34 00 48 00 00 00
00003b0 03 00 00 00 01 00 00 00 38 00 00 00 20 00 00 00
00003c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00003e0 08 00 00 00 01 00 00 00 08 00 00 03 03 00 00 00
00003f0 02 02 10 00 18 00 00 00 04 00 00 00 02 00 00 00
0000400 00 00 00 00 00 00 00 00 01 02 34 00 5c 00 00 00
0000410 04 00 00 00 02 00 00 00 3c 00 00 00 20 00 00 00
0000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0000440 10 00 00 00 08 00 00 00 02 00 00 00 08 00 00 03
0000450 04 00 00 00 08 00 00 00 03 00 00 00 08 00 00 03
0000460 05 00 00 00
0000464
The bytes in blue are the Package chunk header, the bytes in green the Package chunk body.
2.0 Package Chunks
A Package chunk contains a set of Resources and a set of strings associated with those Resources.
The Resources are grouped by type. For each of set of Resources of a given type that the Package chunk contains there is a TypeSpec chunk and one or more Type chunks.
The strings are stored in two StringPool chunks
-
the typeStrings StringPool chunk which contains the names of the types of the Resources defined in the Package
-
the keyStrings StringPool chunk which contains the names (keys) of the Resources defined in the Package.
3.0 The Package Chunk Header
The format of a Package chunk header is defined by the following slightly misleadingly named C++ struct
(see frameworks/base/include/ResourceTypes.h
lines 768-795)
struct ResTable_package
{
struct ResChunk_header header;
// If this is a base package, its ID. Package IDs start
// at 1 (corresponding to the value of the package bits in a
// resource identifier). 0 means this is not a base package.
uint32_t id;
// Actual name of this package, -terminated.
char16_t name[128];
// Offset to a ResStringPool_header defining the resource
// type symbol table. If zero, this package is inheriting from
// another base package (overriding specific values in it).
uint32_t typeStrings;
// Last index into typeStrings that is for public use by others.
uint32_t lastPublicType;
// Offset to a ResStringPool_header defining the resource
// key symbol table. If zero, this package is inheriting from
// another base package (overriding specific values in it).
uint32_t keyStrings;
// Last index into keyStrings that is for public use by others.
uint32_t lastPublicKey;
};
3.1 header
The header field is a struct ResChunk_header instance.
The header.type
field is always 0x0200
(RES_TABLE_PACKAGE_TYPE
).
The header.headerSize
field is always 0x011c
.
3.2 id
The id
field specifies the numeric id of the Package. It is used as part of the identity of each Resource defined in the Package. The id of the Package defined by an application is always 0x7F
(127
).
3.3 name
The name
field specifies the symbolic name of the Package. For an application this is the name specified in the application manifest using the package
attribute.
3.4 typeStrings
The typeStrings
field specifies the offset from the start of the Package chunk to the start of the typeStrings StringPool chunk.
Note
Although the comment in the definition of ResTable_package
shown above states that this can be zero, the runtime code does not handle this situation at all gracefully.
3.5 lastPublicType
The lastPublicType
field specifies the index of the last string in the typeStrings StringPool which is publically visible.
Note
It is not clear what, if anything, this field is actually for.
3.6 keyStrings
The keyStrings
field specifies the offset from the start of the Package chunk to the start of the keyStrings StringPool chunk.
Note
Although the comment in the definition of the ResTable_package struct
above states that this can be zero, the runtime codedoes not handle this situation at all gracefully.
3.7 lastPublicKey
The lastPublicType
field specifies the index of the last string in the keyStrings StringPool which is publically visible.
Note
It is not clear what, if anything, this field is actually for.
3.8 The Example Annotated
This is an annotated version of the Package chunk header from the example.
...
000000dc 00 02 // type [PACKAGE]
000000de 1c 01 // header size
000000e0 88 03 00 00 // chunk size
--------------------
000000e4 7f 00 00 00 // id
000000e8 78 00 70 00 // name [xper.resources.pendragon]
000000ec 65 00 72 00
000000f0 2e 00 72 00
000000f4 65 00 73 00
000000f8 6f 00 75 00
000000fc 72 00 63 00
00000100 65 00 73 00
00000104 2e 00 70 00
00000108 65 00 6e 00
0000010c 64 00 72 00
00000110 61 00 67 00
00000114 6f 00 6e 00
00000118 00 00 00 00
...
000001e8 1c 01 00 00 // typeStrings (address 000001f8)
000001ec 04 00 00 00 // lastPublicType
000001f0 6c 01 00 00 // keyStrings (address 00000248)
000001f4 04 00 00 00 // lastPublicKey
++++++++++++++++++++
...
Note that the name
field is a fixed size and in this case most of it unused which explains the expanse of zeroes between 00000120
and 000001e0
.
4.0 The Package Chunk Body
4.1 The typeStrings StringPool Chunk
This is an annotated version of the typeStrings StringPool chunk from the example.
...
000001f8 01 00 // type [STRING_POOL]
000001fa 1c 00 // header size
000001fc 50 00 00 00 // chunk size
--------------------
00000200 04 00 00 00 // stringCount
00000204 00 00 00 00 // styleCount
00000208 00 01 00 00 // flags
0000020c 2c 00 00 00 // stringsStart (address 00000224)
00000210 00 00 00 00 // stylesStart (address 000001f8)
++++++++++++++++++++
00000214 00 00 00 00 // string[0]
00000218 07 00 00 00 // string[1]
0000021c 12 00 00 00 // string[2]
00000220 1b 00 00 00 // string[3]
00000224 04 04 61 74 // [0] "attr"
00000228 74 72 00 08 // [1] "drawable"
0000022c 08 64 72 61
00000230 77 61 62 6c
00000234 65 00 06 06 // [2] "layout"
00000238 6c 61 79 6f
0000023c 75 74 00 06 // [3] "string"
00000240 06 73 74 72
00000244 69 6e 67 00
==================== [End of STRING_POOL]
...
4.2 The keyStrings StringPool Chunk
This is an annotated version of the keyStrings StringPool chunk from the example.
...
00000248 01 00 // type [STRING_POOL]
0000024a 1c 00 // header size
0000024c 50 00 00 00 // chunk size
--------------------
00000250 04 00 00 00 // stringCount
00000254 00 00 00 00 // styleCount
00000258 00 01 00 00 // flags
0000025c 2c 00 00 00 // stringsStart (address 00000274)
00000260 00 00 00 00 // stylesStart (address 00000248)
++++++++++++++++++++
00000264 00 00 00 00 // string[0]
00000268 07 00 00 00 // string[1]
0000026c 0e 00 00 00 // string[2]
00000270 16 00 00 00 // string[3]
00000274 04 04 69 63 // [0] "icon"
00000278 6f 6e 00 04 // [1] "main"
0000027c 04 6d 61 69
00000280 6e 00 05 05 // [2] "hello"
00000284 68 65 6c 6c
00000288 6f 00 08 08 // [3] "app_name"
0000028c 61 70 70 5f
00000290 6e 61 6d 65
00000294 00 00 00 00
==================== [End of STRING_POOL]
...
4.3 Resource Types And TypeSpec and Type Chunks
TypeSpec and Type chunks contained in a Package chunk are used to represent the following Resource types (these are the type names as they appear in the typeStrings StringPool chunk)
-
array
-
attr
-
bool
-
color
-
dimen
-
drawable
-
fraction
-
integer
-
layout
-
plurals
-
string
-
style
If one or more Resources of a given type are defined in a Package then those Resources are represented by a TypeSpec chunk and one or more Type chunks in the Package chunk.
There is a one-to-one mapping between the type of a Resouce as declared and its representation in the Package chunk with the minor exception of the Resource types declared as
-
array,
-
integer-array,
or
-
string-array
These all end up in the array Typespec and Type chunks.
Copyright (c) 2011 By Simon Lewis. All Rights Reserved.