Loading include/utils/AssetManager.h +9 −2 Original line number Diff line number Diff line Loading @@ -251,6 +251,9 @@ private: Asset* getResourceTableAsset(); Asset* setResourceTableAsset(Asset* asset); ResTable* getResourceTable(); ResTable* setResourceTable(ResTable* res); bool isUpToDate(); protected: Loading @@ -265,6 +268,7 @@ private: time_t mModWhen; Asset* mResourceTableAsset; ResTable* mResourceTable; static Mutex gLock; static DefaultKeyedVector<String8, wp<SharedZip> > gOpen; Loading @@ -288,8 +292,11 @@ private: */ ZipFileRO* getZip(const String8& path); Asset* getZipResourceTable(const String8& path); Asset* setZipResourceTable(const String8& path, Asset* asset); Asset* getZipResourceTableAsset(const String8& path); Asset* setZipResourceTableAsset(const String8& path, Asset* asset); ResTable* getZipResourceTable(const String8& path); ResTable* setZipResourceTable(const String8& path, ResTable* res); // generate path, e.g. "common/en-US-noogle.zip" static String8 getPathName(const char* path); Loading include/utils/ResourceTypes.h +1 −0 Original line number Diff line number Diff line Loading @@ -1580,6 +1580,7 @@ public: bool copyData=false); status_t add(Asset* asset, void* cookie, bool copyData=false); status_t add(ResTable* src); status_t getError() const; Loading libs/utils/Asset.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -582,11 +582,14 @@ const void* _FileAsset::ensureAlignment(FileMap* map) if ((((size_t)data)&0x3) == 0) { // We can return this directly if it is aligned on a word // boundary. LOGV("Returning aligned FileAsset %p (%s).", this, getAssetSource()); return data; } // If not aligned on a word boundary, then we need to copy it into // our own buffer. LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength); LOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this, getAssetSource(), (int)mLength); unsigned char* buf = new unsigned char[mLength]; if (buf == NULL) { LOGE("alloc of %ld bytes failed\n", (long) mLength); Loading libs/utils/AssetManager.cpp +83 −14 Original line number Diff line number Diff line Loading @@ -395,12 +395,20 @@ const ResTable* AssetManager::getResTable(bool required) const const size_t N = mAssetPaths.size(); for (size_t i=0; i<N; i++) { Asset* ass = NULL; ResTable* sharedRes = NULL; bool shared = true; const asset_path& ap = mAssetPaths.itemAt(i); LOGV("Looking for resource asset in '%s'\n", ap.path.string()); if (ap.type != kFileTypeDirectory) { ass = const_cast<AssetManager*>(this)-> if (i == 0) { // The first item is typically the framework resources, // which we want to avoid parsing every time. sharedRes = const_cast<AssetManager*>(this)-> mZipSet.getZipResourceTable(ap.path); } if (sharedRes == NULL) { ass = const_cast<AssetManager*>(this)-> mZipSet.getZipResourceTableAsset(ap.path); if (ass == NULL) { LOGV("loading resource table %s\n", ap.path.string()); ass = const_cast<AssetManager*>(this)-> Loading @@ -409,7 +417,19 @@ const ResTable* AssetManager::getResTable(bool required) const ap); if (ass != NULL && ass != kExcludedAsset) { ass = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, ass); mZipSet.setZipResourceTableAsset(ap.path, ass); } } if (i == 0 && ass != NULL) { // If this is the first resource table in the asset // manager, then we are going to cache it so that we // can quickly copy it out for others. LOGV("Creating shared resources for %s", ap.path.string()); sharedRes = new ResTable(); sharedRes->add(ass, (void*)(i+1), false); sharedRes = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, sharedRes); } } } else { Loading @@ -420,13 +440,19 @@ const ResTable* AssetManager::getResTable(bool required) const ap); shared = false; } if (ass != NULL && ass != kExcludedAsset) { if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { if (rt == NULL) { mResources = rt = new ResTable(); updateResourceParamsLocked(); } LOGV("Installing resource asset %p in to table %p\n", ass, mResources); if (sharedRes != NULL) { LOGV("Copying existing resources for %s", ap.path.string()); rt->add(sharedRes); } else { LOGV("Parsing resources for %s", ap.path.string()); rt->add(ass, (void*)(i+1), !shared); } if (!shared) { delete ass; Loading Loading @@ -1510,7 +1536,8 @@ Mutex AssetManager::SharedZip::gLock; DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen; AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen) : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL) : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL), mResourceTable(NULL) { //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath); mZipFile = new ZipFileRO; Loading Loading @@ -1563,6 +1590,25 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset) return mResourceTableAsset; } ResTable* AssetManager::SharedZip::getResourceTable() { LOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable); return mResourceTable; } ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res) { { AutoMutex _l(gLock); if (mResourceTable == NULL) { mResourceTable = res; return res; } } delete res; return mResourceTable; } bool AssetManager::SharedZip::isUpToDate() { time_t modWhen = getFileModDate(mPath.string()); Loading @@ -1572,6 +1618,9 @@ bool AssetManager::SharedZip::isUpToDate() AssetManager::SharedZip::~SharedZip() { //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath); if (mResourceTable != NULL) { delete mResourceTable; } if (mResourceTableAsset != NULL) { delete mResourceTableAsset; } Loading Loading @@ -1627,7 +1676,7 @@ ZipFileRO* AssetManager::ZipSet::getZip(const String8& path) return zip->getZip(); } Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; Loading @@ -1638,7 +1687,7 @@ Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) return zip->getResourceTableAsset(); } Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path, Asset* asset) { int idx = getIndex(path); Loading @@ -1647,6 +1696,26 @@ Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, return zip->setResourceTableAsset(asset); } ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; if (zip == NULL) { zip = SharedZip::get(path); mZipFile.editItemAt(idx) = zip; } return zip->getResourceTable(); } ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path, ResTable* res) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; // doesn't make sense to call before previously accessing. return zip->setResourceTable(res); } /* * Generate the partial pathname for the specified archive. The caller * gets to prepend the asset root directory. Loading libs/utils/ResourceTypes.cpp +71 −25 Original line number Diff line number Diff line Loading @@ -1136,8 +1136,9 @@ status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const struct ResTable::Header { Header() : ownedData(NULL), header(NULL) { } Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL) { } ResTable* const owner; void* ownedData; const ResTable_header* header; size_t size; Loading @@ -1163,8 +1164,8 @@ struct ResTable::Type struct ResTable::Package { Package(const Header* _header, const ResTable_package* _package) : header(_header), package(_package) { } Package(ResTable* _owner, const Header* _header, const ResTable_package* _package) : owner(_owner), header(_header), package(_package) { } ~Package() { size_t i = types.size(); Loading @@ -1174,10 +1175,14 @@ struct ResTable::Package } } ResTable* const owner; const Header* const header; const ResTable_package* const package; Vector<Type*> types; ResStringPool typeStrings; ResStringPool keyStrings; const Type* getType(size_t idx) const { return idx < types.size() ? types[idx] : NULL; } Loading @@ -1188,13 +1193,16 @@ struct ResTable::Package // table that defined the package); the ones after are skins on top of it. struct ResTable::PackageGroup { PackageGroup(const String16& _name, uint32_t _id) : name(_name), id(_id), typeCount(0), bags(NULL) { } PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id) : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { } ~PackageGroup() { clearBagCache(); const size_t N = packages.size(); for (size_t i=0; i<N; i++) { delete packages[i]; Package* pkg = packages[i]; if (pkg->owner == owner) { delete pkg; } } } Loading Loading @@ -1225,13 +1233,15 @@ struct ResTable::PackageGroup } } ResTable* const owner; String16 const name; uint32_t const id; Vector<Package*> packages; // Taken from the root package. ResStringPool typeStrings; ResStringPool keyStrings; // This is for finding typeStrings and other common package stuff. Package* basePackage; // For quick access. size_t typeCount; // Computed attribute bags, first indexed by the type and second Loading Loading @@ -1560,11 +1570,36 @@ status_t ResTable::add(Asset* asset, void* cookie, bool copyData) return add(data, size, cookie, asset, copyData); } status_t ResTable::add(ResTable* src) { mError = src->mError; mParams = src->mParams; for (size_t i=0; i<src->mHeaders.size(); i++) { mHeaders.add(src->mHeaders[i]); } for (size_t i=0; i<src->mPackageGroups.size(); i++) { PackageGroup* srcPg = src->mPackageGroups[i]; PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id); for (size_t j=0; j<srcPg->packages.size(); j++) { pg->packages.add(srcPg->packages[j]); } pg->basePackage = srcPg->basePackage; pg->typeCount = srcPg->typeCount; mPackageGroups.add(pg); } memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap)); return mError; } status_t ResTable::add(const void* data, size_t size, void* cookie, Asset* asset, bool copyData) { if (!data) return NO_ERROR; Header* header = new Header; Header* header = new Header(this); header->index = mHeaders.size(); header->cookie = cookie; mHeaders.add(header); Loading Loading @@ -1682,11 +1717,13 @@ void ResTable::uninit() N = mHeaders.size(); for (size_t i=0; i<N; i++) { Header* header = mHeaders[i]; if (header->owner == this) { if (header->ownedData) { free(header->ownedData); } delete header; } } mPackageGroups.clear(); mHeaders.clear(); Loading Loading @@ -1728,8 +1765,8 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const outName->package = grp->name.string(); outName->packageLen = grp->name.size(); outName->type = grp->typeStrings.stringAt(t, &outName->typeLen); outName->name = grp->keyStrings.stringAt( outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen); outName->name = grp->basePackage->keyStrings.stringAt( dtohl(entry->key.index), &outName->nameLen); return true; } Loading Loading @@ -2331,13 +2368,13 @@ nope: continue; } const ssize_t ti = group->typeStrings.indexOfString(type, typeLen); const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen); if (ti < 0) { TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string())); continue; } const ssize_t ei = group->keyStrings.indexOfString(name, nameLen); const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen); if (ei < 0) { TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string())); continue; Loading Loading @@ -3630,25 +3667,36 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, PackageGroup* group = NULL; uint32_t id = dtohl(pkg->id); if (id != 0 && id < 256) { package = new Package(this, header, pkg); if (package == NULL) { return (mError=NO_MEMORY); } size_t idx = mPackageMap[id]; if (idx == 0) { idx = mPackageGroups.size()+1; char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)]; strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t)); group = new PackageGroup(String16(tmpName), id); group = new PackageGroup(this, String16(tmpName), id); if (group == NULL) { delete package; return (mError=NO_MEMORY); } err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings), err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings), header->dataEnd-(base+dtohl(pkg->typeStrings))); if (err != NO_ERROR) { delete group; delete package; return (mError=err); } err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings), err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings), header->dataEnd-(base+dtohl(pkg->keyStrings))); if (err != NO_ERROR) { delete group; delete package; return (mError=err); } Loading @@ -3657,6 +3705,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, if (err < NO_ERROR) { return (mError=err); } group->basePackage = package; mPackageMap[id] = (uint8_t)idx; } else { group = mPackageGroups.itemAt(idx-1); Loading @@ -3664,10 +3714,6 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, return (mError=UNKNOWN_ERROR); } } package = new Package(header, pkg); if (package == NULL) { return (mError=NO_MEMORY); } err = group->packages.add(package); if (err < NO_ERROR) { return (mError=err); Loading Loading
include/utils/AssetManager.h +9 −2 Original line number Diff line number Diff line Loading @@ -251,6 +251,9 @@ private: Asset* getResourceTableAsset(); Asset* setResourceTableAsset(Asset* asset); ResTable* getResourceTable(); ResTable* setResourceTable(ResTable* res); bool isUpToDate(); protected: Loading @@ -265,6 +268,7 @@ private: time_t mModWhen; Asset* mResourceTableAsset; ResTable* mResourceTable; static Mutex gLock; static DefaultKeyedVector<String8, wp<SharedZip> > gOpen; Loading @@ -288,8 +292,11 @@ private: */ ZipFileRO* getZip(const String8& path); Asset* getZipResourceTable(const String8& path); Asset* setZipResourceTable(const String8& path, Asset* asset); Asset* getZipResourceTableAsset(const String8& path); Asset* setZipResourceTableAsset(const String8& path, Asset* asset); ResTable* getZipResourceTable(const String8& path); ResTable* setZipResourceTable(const String8& path, ResTable* res); // generate path, e.g. "common/en-US-noogle.zip" static String8 getPathName(const char* path); Loading
include/utils/ResourceTypes.h +1 −0 Original line number Diff line number Diff line Loading @@ -1580,6 +1580,7 @@ public: bool copyData=false); status_t add(Asset* asset, void* cookie, bool copyData=false); status_t add(ResTable* src); status_t getError() const; Loading
libs/utils/Asset.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -582,11 +582,14 @@ const void* _FileAsset::ensureAlignment(FileMap* map) if ((((size_t)data)&0x3) == 0) { // We can return this directly if it is aligned on a word // boundary. LOGV("Returning aligned FileAsset %p (%s).", this, getAssetSource()); return data; } // If not aligned on a word boundary, then we need to copy it into // our own buffer. LOGV("Copying FileAsset %p to buffer size %d to make it aligned.", this, (int)mLength); LOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this, getAssetSource(), (int)mLength); unsigned char* buf = new unsigned char[mLength]; if (buf == NULL) { LOGE("alloc of %ld bytes failed\n", (long) mLength); Loading
libs/utils/AssetManager.cpp +83 −14 Original line number Diff line number Diff line Loading @@ -395,12 +395,20 @@ const ResTable* AssetManager::getResTable(bool required) const const size_t N = mAssetPaths.size(); for (size_t i=0; i<N; i++) { Asset* ass = NULL; ResTable* sharedRes = NULL; bool shared = true; const asset_path& ap = mAssetPaths.itemAt(i); LOGV("Looking for resource asset in '%s'\n", ap.path.string()); if (ap.type != kFileTypeDirectory) { ass = const_cast<AssetManager*>(this)-> if (i == 0) { // The first item is typically the framework resources, // which we want to avoid parsing every time. sharedRes = const_cast<AssetManager*>(this)-> mZipSet.getZipResourceTable(ap.path); } if (sharedRes == NULL) { ass = const_cast<AssetManager*>(this)-> mZipSet.getZipResourceTableAsset(ap.path); if (ass == NULL) { LOGV("loading resource table %s\n", ap.path.string()); ass = const_cast<AssetManager*>(this)-> Loading @@ -409,7 +417,19 @@ const ResTable* AssetManager::getResTable(bool required) const ap); if (ass != NULL && ass != kExcludedAsset) { ass = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, ass); mZipSet.setZipResourceTableAsset(ap.path, ass); } } if (i == 0 && ass != NULL) { // If this is the first resource table in the asset // manager, then we are going to cache it so that we // can quickly copy it out for others. LOGV("Creating shared resources for %s", ap.path.string()); sharedRes = new ResTable(); sharedRes->add(ass, (void*)(i+1), false); sharedRes = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, sharedRes); } } } else { Loading @@ -420,13 +440,19 @@ const ResTable* AssetManager::getResTable(bool required) const ap); shared = false; } if (ass != NULL && ass != kExcludedAsset) { if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { if (rt == NULL) { mResources = rt = new ResTable(); updateResourceParamsLocked(); } LOGV("Installing resource asset %p in to table %p\n", ass, mResources); if (sharedRes != NULL) { LOGV("Copying existing resources for %s", ap.path.string()); rt->add(sharedRes); } else { LOGV("Parsing resources for %s", ap.path.string()); rt->add(ass, (void*)(i+1), !shared); } if (!shared) { delete ass; Loading Loading @@ -1510,7 +1536,8 @@ Mutex AssetManager::SharedZip::gLock; DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen; AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen) : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL) : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL), mResourceTable(NULL) { //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath); mZipFile = new ZipFileRO; Loading Loading @@ -1563,6 +1590,25 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset) return mResourceTableAsset; } ResTable* AssetManager::SharedZip::getResourceTable() { LOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable); return mResourceTable; } ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res) { { AutoMutex _l(gLock); if (mResourceTable == NULL) { mResourceTable = res; return res; } } delete res; return mResourceTable; } bool AssetManager::SharedZip::isUpToDate() { time_t modWhen = getFileModDate(mPath.string()); Loading @@ -1572,6 +1618,9 @@ bool AssetManager::SharedZip::isUpToDate() AssetManager::SharedZip::~SharedZip() { //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath); if (mResourceTable != NULL) { delete mResourceTable; } if (mResourceTableAsset != NULL) { delete mResourceTableAsset; } Loading Loading @@ -1627,7 +1676,7 @@ ZipFileRO* AssetManager::ZipSet::getZip(const String8& path) return zip->getZip(); } Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; Loading @@ -1638,7 +1687,7 @@ Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) return zip->getResourceTableAsset(); } Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path, Asset* asset) { int idx = getIndex(path); Loading @@ -1647,6 +1696,26 @@ Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, return zip->setResourceTableAsset(asset); } ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; if (zip == NULL) { zip = SharedZip::get(path); mZipFile.editItemAt(idx) = zip; } return zip->getResourceTable(); } ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path, ResTable* res) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; // doesn't make sense to call before previously accessing. return zip->setResourceTable(res); } /* * Generate the partial pathname for the specified archive. The caller * gets to prepend the asset root directory. Loading
libs/utils/ResourceTypes.cpp +71 −25 Original line number Diff line number Diff line Loading @@ -1136,8 +1136,9 @@ status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const struct ResTable::Header { Header() : ownedData(NULL), header(NULL) { } Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL) { } ResTable* const owner; void* ownedData; const ResTable_header* header; size_t size; Loading @@ -1163,8 +1164,8 @@ struct ResTable::Type struct ResTable::Package { Package(const Header* _header, const ResTable_package* _package) : header(_header), package(_package) { } Package(ResTable* _owner, const Header* _header, const ResTable_package* _package) : owner(_owner), header(_header), package(_package) { } ~Package() { size_t i = types.size(); Loading @@ -1174,10 +1175,14 @@ struct ResTable::Package } } ResTable* const owner; const Header* const header; const ResTable_package* const package; Vector<Type*> types; ResStringPool typeStrings; ResStringPool keyStrings; const Type* getType(size_t idx) const { return idx < types.size() ? types[idx] : NULL; } Loading @@ -1188,13 +1193,16 @@ struct ResTable::Package // table that defined the package); the ones after are skins on top of it. struct ResTable::PackageGroup { PackageGroup(const String16& _name, uint32_t _id) : name(_name), id(_id), typeCount(0), bags(NULL) { } PackageGroup(ResTable* _owner, const String16& _name, uint32_t _id) : owner(_owner), name(_name), id(_id), typeCount(0), bags(NULL) { } ~PackageGroup() { clearBagCache(); const size_t N = packages.size(); for (size_t i=0; i<N; i++) { delete packages[i]; Package* pkg = packages[i]; if (pkg->owner == owner) { delete pkg; } } } Loading Loading @@ -1225,13 +1233,15 @@ struct ResTable::PackageGroup } } ResTable* const owner; String16 const name; uint32_t const id; Vector<Package*> packages; // Taken from the root package. ResStringPool typeStrings; ResStringPool keyStrings; // This is for finding typeStrings and other common package stuff. Package* basePackage; // For quick access. size_t typeCount; // Computed attribute bags, first indexed by the type and second Loading Loading @@ -1560,11 +1570,36 @@ status_t ResTable::add(Asset* asset, void* cookie, bool copyData) return add(data, size, cookie, asset, copyData); } status_t ResTable::add(ResTable* src) { mError = src->mError; mParams = src->mParams; for (size_t i=0; i<src->mHeaders.size(); i++) { mHeaders.add(src->mHeaders[i]); } for (size_t i=0; i<src->mPackageGroups.size(); i++) { PackageGroup* srcPg = src->mPackageGroups[i]; PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id); for (size_t j=0; j<srcPg->packages.size(); j++) { pg->packages.add(srcPg->packages[j]); } pg->basePackage = srcPg->basePackage; pg->typeCount = srcPg->typeCount; mPackageGroups.add(pg); } memcpy(mPackageMap, src->mPackageMap, sizeof(mPackageMap)); return mError; } status_t ResTable::add(const void* data, size_t size, void* cookie, Asset* asset, bool copyData) { if (!data) return NO_ERROR; Header* header = new Header; Header* header = new Header(this); header->index = mHeaders.size(); header->cookie = cookie; mHeaders.add(header); Loading Loading @@ -1682,11 +1717,13 @@ void ResTable::uninit() N = mHeaders.size(); for (size_t i=0; i<N; i++) { Header* header = mHeaders[i]; if (header->owner == this) { if (header->ownedData) { free(header->ownedData); } delete header; } } mPackageGroups.clear(); mHeaders.clear(); Loading Loading @@ -1728,8 +1765,8 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const outName->package = grp->name.string(); outName->packageLen = grp->name.size(); outName->type = grp->typeStrings.stringAt(t, &outName->typeLen); outName->name = grp->keyStrings.stringAt( outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen); outName->name = grp->basePackage->keyStrings.stringAt( dtohl(entry->key.index), &outName->nameLen); return true; } Loading Loading @@ -2331,13 +2368,13 @@ nope: continue; } const ssize_t ti = group->typeStrings.indexOfString(type, typeLen); const ssize_t ti = group->basePackage->typeStrings.indexOfString(type, typeLen); if (ti < 0) { TABLE_NOISY(printf("Type not found in package %s\n", String8(group->name).string())); continue; } const ssize_t ei = group->keyStrings.indexOfString(name, nameLen); const ssize_t ei = group->basePackage->keyStrings.indexOfString(name, nameLen); if (ei < 0) { TABLE_NOISY(printf("Name not found in package %s\n", String8(group->name).string())); continue; Loading Loading @@ -3630,25 +3667,36 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, PackageGroup* group = NULL; uint32_t id = dtohl(pkg->id); if (id != 0 && id < 256) { package = new Package(this, header, pkg); if (package == NULL) { return (mError=NO_MEMORY); } size_t idx = mPackageMap[id]; if (idx == 0) { idx = mPackageGroups.size()+1; char16_t tmpName[sizeof(pkg->name)/sizeof(char16_t)]; strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(char16_t)); group = new PackageGroup(String16(tmpName), id); group = new PackageGroup(this, String16(tmpName), id); if (group == NULL) { delete package; return (mError=NO_MEMORY); } err = group->typeStrings.setTo(base+dtohl(pkg->typeStrings), err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings), header->dataEnd-(base+dtohl(pkg->typeStrings))); if (err != NO_ERROR) { delete group; delete package; return (mError=err); } err = group->keyStrings.setTo(base+dtohl(pkg->keyStrings), err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings), header->dataEnd-(base+dtohl(pkg->keyStrings))); if (err != NO_ERROR) { delete group; delete package; return (mError=err); } Loading @@ -3657,6 +3705,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, if (err < NO_ERROR) { return (mError=err); } group->basePackage = package; mPackageMap[id] = (uint8_t)idx; } else { group = mPackageGroups.itemAt(idx-1); Loading @@ -3664,10 +3714,6 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, return (mError=UNKNOWN_ERROR); } } package = new Package(header, pkg); if (package == NULL) { return (mError=NO_MEMORY); } err = group->packages.add(package); if (err < NO_ERROR) { return (mError=err); Loading