static ::testing::AssertionResult TestParse(AaptGroupEntry& entry, const String8& dirName, String8* outType) { if (entry.initFromDirName(dirName, outType)) { return ::testing::AssertionSuccess() << dirName << " was successfully parsed"; } return ::testing::AssertionFailure() << dirName << " could not be parsed"; }
ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptDir>& dir, const AaptGroupEntry& ge, const ResourceFilter* filter) { ssize_t count = 0; const size_t ND = dir->getDirs().size(); size_t i; for (i=0; i<ND; i++) { const sp<AaptDir>& subDir = dir->getDirs().valueAt(i); const bool filterable = filter != NULL && subDir->getLeaf().find("mipmap-") != 0; if (filterable && subDir->getLeaf() != subDir->getPath() && !filter->match(ge.toParams())) { continue; } ssize_t res = processAssets(bundle, zip, subDir, ge, filterable ? filter : NULL); if (res < 0) { return res; } count += res; } if (filter != NULL && !filter->match(ge.toParams())) { return count; } const size_t NF = dir->getFiles().size(); for (i=0; i<NF; i++) { sp<AaptGroup> gp = dir->getFiles().valueAt(i); ssize_t fi = gp->getFiles().indexOfKey(ge); if (fi >= 0) { sp<AaptFile> fl = gp->getFiles().valueAt(fi); if (!processFile(bundle, zip, gp, fl)) { return UNKNOWN_ERROR; } count++; } } return count; }
ssize_t AaptAssets::slurpResourceZip(Bundle* bundle, const char* filename) { int count = 0; SortedVector<AaptGroupEntry> entries; ZipFile* zip = new ZipFile; status_t err = zip->open(filename, ZipFile::kOpenReadOnly); if (err != NO_ERROR) { fprintf(stderr, "error opening zip file %s\n", filename); count = err; delete zip; return -1; } const int N = zip->getNumEntries(); for (int i=0; i<N; i++) { ZipEntry* entry = zip->getEntryByIndex(i); if (entry->getDeleted()) { continue; } String8 entryName(entry->getFileName()); String8 dirName = entryName.getPathDir(); sp<AaptDir> dir = dirName == "" ? this : makeDir(dirName); String8 resType; AaptGroupEntry kind; String8 remain; if (entryName.walkPath(&remain) == kResourceDir) { // these are the resources, pull their type out of the directory name kind.initFromDirName(remain.walkPath().string(), &resType); } else { // these are untyped and don't have an AaptGroupEntry } if (entries.indexOf(kind) < 0) { entries.add(kind); mGroupEntries.add(kind); } // use the one from the zip file if they both exist. dir->removeFile(entryName.getPathLeaf()); sp<AaptFile> file = new AaptFile(entryName, kind, resType); status_t err = dir->addLeafFile(entryName.getPathLeaf(), file); if (err != NO_ERROR) { fprintf(stderr, "err=%s entryName=%s\n", strerror(err), entryName.string()); count = err; goto bail; } file->setCompressionMethod(entry->getCompressionMethod()); #if 0 if (entryName == "AndroidManifest.xml") { printf("AndroidManifest.xml\n"); } printf("\n\nfile: %s\n", entryName.string()); #endif size_t len = entry->getUncompressedLen(); void* data = zip->uncompress(entry); void* buf = file->editData(len); memcpy(buf, data, len); #if 0 const int OFF = 0; const unsigned char* p = (unsigned char*)data; const unsigned char* end = p+len; p += OFF; for (int i=0; i<32 && p < end; i++) { printf("0x%03x ", i*0x10 + OFF); for (int j=0; j<0x10 && p < end; j++) { printf(" %02x", *p); p++; } printf("\n"); } #endif free(data); count++; } bail: delete zip; return count; }
ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir) { ssize_t err = 0; DIR* dir = opendir(srcDir.string()); if (dir == NULL) { fprintf(stderr, "ERROR: opendir(%s): %s\n", srcDir.string(), strerror(errno)); return UNKNOWN_ERROR; } status_t count = 0; /* * Run through the directory, looking for dirs that match the * expected pattern. */ while (1) { struct dirent* entry = readdir(dir); if (entry == NULL) { break; } if (isHidden(srcDir.string(), entry->d_name)) { continue; } String8 subdirName(srcDir); subdirName.appendPath(entry->d_name); AaptGroupEntry group; String8 resType; bool b = group.initFromDirName(entry->d_name, &resType); if (!b) { fprintf(stderr, "invalid resource directory name: %s/%s\n", srcDir.string(), entry->d_name); err = -1; continue; } FileType type = getFileType(subdirName.string()); if (type == kFileTypeDirectory) { sp<AaptDir> dir = makeDir(String8(entry->d_name)); ssize_t res = dir->slurpFullTree(bundle, subdirName, group, resType); if (res < 0) { count = res; goto bail; } if (res > 0) { mGroupEntries.add(group); count += res; } mDirs.add(dir); } else { if (bundle->getVerbose()) { fprintf(stderr, " (ignoring file '%s')\n", subdirName.string()); } } } bail: closedir(dir); dir = NULL; if (err != 0) { return err; } return count; }