summaryrefslogtreecommitdiff
path: root/tools/aapt/ResourceTable.cpp
diff options
context:
space:
mode:
author Eric Miao <ericymiao@google.com> 2022-09-09 15:46:14 -0700
committer Eric Miao <ericymiao@google.com> 2022-11-15 12:12:33 -0800
commit368cd19d031f5a0b219ea92531d11ccb0ee66c4d (patch)
treeea6aa74fa746c043112705fdb08438abf782717b /tools/aapt/ResourceTable.cpp
parentb0d0974aeba2b0498f5f576ff38012ac94b909a8 (diff)
androidfw: Add support for compact resource entries
Bug: 237583012 Given the large number of simple resources such as strings in Android resources, their ResTable_entry and Res_value can be encoded together in a compact way. This allows a significant saving in both storage and memory footprint. The basic observations for simple resources are: * ResTable_entry.size will always be sizeof(ResTable_entry) unless it's a complex entry * ResTable_entry.key is unlikely to exceed 16-bit * ResTable_entry.flags only uses 3 bits for now * Res_value.size will always be sizeof(Res_value) Given the above, we could well encode the information into a compact/compatible structure. struct compact { uint16_t key; uint16_t flags; uint32_t data; }; The layout of this structure will allow maximum backward compatibility. e.g. the flags will be at the same offset, and a `dtohs((ResTable_entry *)entry->flags) & FLAG_COMPACT` would tell if this entry is a compact one or not. For a compact entry: struct compact *entry; entry_size == sizeof(*entry) entry_key == static_cast<uint32_t>(dtohs(entry->key)) entry_flags == dtohs(entry->flags) & 0xff // low 8-bit data_type == dtohs(entry->flags) >> 8 // high 8-bit data_size == sizeof(Res_value) data_value == dtohl(entry->data) To allow minimum code change and backward compatibility, we change 'struct ResTable_entry' to 'union ResTable_entry', with an anonymous structure inside that's fully backward compatible. Thus, any existing reference such as: ResTable_entry *entry = ... if (dtohs(entry->flags) & ResTable_entry::FLAG_COMPLEX) ... would still work. However, special care needs to be taken after an entry is obtained, and when value needs to be extracted. A compact entry will not encode a complex value, and hence complex entries/values are handled the same way. Change-Id: I15d97a4f5e85fab28c075496f7f0cf6b1fcd73e3
Diffstat (limited to 'tools/aapt/ResourceTable.cpp')
-rw-r--r--tools/aapt/ResourceTable.cpp8
1 files changed, 4 insertions, 4 deletions
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 47750fc11a6e..4e597fb3b30a 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -3743,15 +3743,15 @@ ssize_t ResourceTable::Entry::flatten(Bundle* /* bundle */, const sp<AaptFile>&
size_t amt = 0;
ResTable_entry header;
memset(&header, 0, sizeof(header));
- header.size = htods(sizeof(header));
+ header.full.size = htods(sizeof(header));
const type ty = mType;
if (ty == TYPE_BAG) {
- header.flags |= htods(header.FLAG_COMPLEX);
+ header.full.flags |= htods(header.FLAG_COMPLEX);
}
if (isPublic) {
- header.flags |= htods(header.FLAG_PUBLIC);
+ header.full.flags |= htods(header.FLAG_PUBLIC);
}
- header.key.index = htodl(mNameIndex);
+ header.full.key.index = htodl(mNameIndex);
if (ty != TYPE_BAG) {
status_t err = data->writeData(&header, sizeof(header));
if (err != NO_ERROR) {