summaryrefslogtreecommitdiffstats
path: root/tools/aapt2/BinaryResourceParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/BinaryResourceParser.cpp')
-rw-r--r--tools/aapt2/BinaryResourceParser.cpp80
1 files changed, 63 insertions, 17 deletions
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp
index 326a2ac..d16f63b 100644
--- a/tools/aapt2/BinaryResourceParser.cpp
+++ b/tools/aapt2/BinaryResourceParser.cpp
@@ -39,7 +39,7 @@ using namespace android;
* given a mapping from resource ID to resource name.
*/
struct ReferenceIdToNameVisitor : ValueVisitor {
- ReferenceIdToNameVisitor(const std::shared_ptr<Resolver>& resolver,
+ ReferenceIdToNameVisitor(const std::shared_ptr<IResolver>& resolver,
std::map<ResourceId, ResourceName>* cache) :
mResolver(resolver), mCache(cache) {
}
@@ -96,30 +96,25 @@ private:
reference.name = cacheIter->second;
reference.id = 0;
} else {
- const android::ResTable& table = mResolver->getResTable();
- android::ResTable::resource_name resourceName;
- if (table.getResourceName(reference.id.id, false, &resourceName)) {
- const ResourceType* type = parseResourceType(StringPiece16(resourceName.type,
- resourceName.typeLen));
- assert(type);
- reference.name.package.assign(resourceName.package, resourceName.packageLen);
- reference.name.type = *type;
- reference.name.entry.assign(resourceName.name, resourceName.nameLen);
- reference.id = 0;
+ Maybe<ResourceName> result = mResolver->findName(reference.id);
+ if (result) {
+ reference.name = result.value();
// Add to cache.
mCache->insert({reference.id, reference.name});
+
+ reference.id = 0;
}
}
}
- std::shared_ptr<Resolver> mResolver;
+ std::shared_ptr<IResolver> mResolver;
std::map<ResourceId, ResourceName>* mCache;
};
BinaryResourceParser::BinaryResourceParser(const std::shared_ptr<ResourceTable>& table,
- const std::shared_ptr<Resolver>& resolver,
+ const std::shared_ptr<IResolver>& resolver,
const Source& source,
const void* data,
size_t len) :
@@ -401,6 +396,12 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
}
break;
+ case RES_TABLE_PUBLIC_TYPE:
+ if (!parsePublic(parser.getChunk())) {
+ return false;
+ }
+ break;
+
default:
Logger::warn(mSource)
<< "unexpected chunk of type "
@@ -434,6 +435,55 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) {
return true;
}
+bool BinaryResourceParser::parsePublic(const ResChunk_header* chunk) {
+ const Public_header* header = convertTo<Public_header>(chunk);
+
+ if (header->typeId == 0) {
+ Logger::error(mSource)
+ << "invalid type ID " << header->typeId << std::endl;
+ return false;
+ }
+
+ const ResourceType* parsedType = parseResourceType(util::getString(mTypePool,
+ header->typeId - 1));
+ if (!parsedType) {
+ Logger::error(mSource)
+ << "invalid type " << util::getString(mTypePool, header->typeId - 1) << std::endl;
+ return false;
+ }
+
+ const uintptr_t chunkEnd = reinterpret_cast<uintptr_t>(chunk) + chunk->size;
+ const Public_entry* entry = reinterpret_cast<const Public_entry*>(
+ getChunkData(header->header));
+ for (uint32_t i = 0; i < header->count; i++) {
+ if (reinterpret_cast<uintptr_t>(entry) + sizeof(*entry) > chunkEnd) {
+ Logger::error(mSource)
+ << "Public_entry extends beyond chunk."
+ << std::endl;
+ return false;
+ }
+
+ const ResourceId resId = { mTable->getPackageId(), header->typeId, entry->entryId };
+ const ResourceName name = {
+ mTable->getPackage(),
+ *parsedType,
+ util::getString(mKeyPool, entry->key.index).toString() };
+
+ SourceLine source;
+ if (mSourcePool.getError() == NO_ERROR) {
+ source.path = util::utf16ToUtf8(util::getString(mSourcePool, entry->source.index));
+ source.line = entry->sourceLine;
+ }
+
+ if (!mTable->markPublic(name, resId, source)) {
+ return false;
+ }
+
+ entry++;
+ }
+ return true;
+}
+
bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
if (mTypePool.getError() != NO_ERROR) {
Logger::error(mSource)
@@ -641,10 +691,6 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na
return util::make_unique<BinaryPrimitive>(nullType);
}
- if (value->dataType == ExtendedTypes::TYPE_SENTINEL) {
- return util::make_unique<Sentinel>();
- }
-
if (value->dataType == ExtendedTypes::TYPE_RAW_STRING) {
return util::make_unique<RawString>(
mTable->getValueStringPool().makeRef(util::getString(mValuePool, value->data),