xref: /aosp_15_r20/frameworks/base/tools/aapt/FileFinder.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker //
2*d57664e9SAndroid Build Coastguard Worker // Copyright 2011 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker //
4*d57664e9SAndroid Build Coastguard Worker 
5*d57664e9SAndroid Build Coastguard Worker // File Finder implementation.
6*d57664e9SAndroid Build Coastguard Worker // Implementation for the functions declared and documented in FileFinder.h
7*d57664e9SAndroid Build Coastguard Worker 
8*d57664e9SAndroid Build Coastguard Worker #include <androidfw/PathUtils.h>
9*d57664e9SAndroid Build Coastguard Worker #include <utils/Vector.h>
10*d57664e9SAndroid Build Coastguard Worker #include <utils/String8.h>
11*d57664e9SAndroid Build Coastguard Worker #include <utils/KeyedVector.h>
12*d57664e9SAndroid Build Coastguard Worker 
13*d57664e9SAndroid Build Coastguard Worker #include <dirent.h>
14*d57664e9SAndroid Build Coastguard Worker #include <sys/stat.h>
15*d57664e9SAndroid Build Coastguard Worker 
16*d57664e9SAndroid Build Coastguard Worker #include "DirectoryWalker.h"
17*d57664e9SAndroid Build Coastguard Worker #include "FileFinder.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker //#define DEBUG
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker using android::String8;
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker // Private function to check whether a file is a directory or not
isDirectory(const char * filename)24*d57664e9SAndroid Build Coastguard Worker bool isDirectory(const char* filename) {
25*d57664e9SAndroid Build Coastguard Worker     struct stat fileStat;
26*d57664e9SAndroid Build Coastguard Worker     if (stat(filename, &fileStat) == -1) {
27*d57664e9SAndroid Build Coastguard Worker         return false;
28*d57664e9SAndroid Build Coastguard Worker     }
29*d57664e9SAndroid Build Coastguard Worker     return(S_ISDIR(fileStat.st_mode));
30*d57664e9SAndroid Build Coastguard Worker }
31*d57664e9SAndroid Build Coastguard Worker 
32*d57664e9SAndroid Build Coastguard Worker 
33*d57664e9SAndroid Build Coastguard Worker // Private function to check whether a file is a regular file or not
isFile(const char * filename)34*d57664e9SAndroid Build Coastguard Worker bool isFile(const char* filename) {
35*d57664e9SAndroid Build Coastguard Worker     struct stat fileStat;
36*d57664e9SAndroid Build Coastguard Worker     if (stat(filename, &fileStat) == -1) {
37*d57664e9SAndroid Build Coastguard Worker         return false;
38*d57664e9SAndroid Build Coastguard Worker     }
39*d57664e9SAndroid Build Coastguard Worker     return(S_ISREG(fileStat.st_mode));
40*d57664e9SAndroid Build Coastguard Worker }
41*d57664e9SAndroid Build Coastguard Worker 
findFiles(String8 basePath,Vector<String8> & extensions,KeyedVector<String8,time_t> & fileStore,DirectoryWalker * dw)42*d57664e9SAndroid Build Coastguard Worker bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,
43*d57664e9SAndroid Build Coastguard Worker                                  KeyedVector<String8,time_t>& fileStore,
44*d57664e9SAndroid Build Coastguard Worker                                  DirectoryWalker* dw)
45*d57664e9SAndroid Build Coastguard Worker {
46*d57664e9SAndroid Build Coastguard Worker     // Scan the directory pointed to by basePath
47*d57664e9SAndroid Build Coastguard Worker     // check files and recurse into subdirectories.
48*d57664e9SAndroid Build Coastguard Worker     if (!dw->openDir(basePath)) {
49*d57664e9SAndroid Build Coastguard Worker         return false;
50*d57664e9SAndroid Build Coastguard Worker     }
51*d57664e9SAndroid Build Coastguard Worker     /*
52*d57664e9SAndroid Build Coastguard Worker      *  Go through all directory entries. Check each file using checkAndAddFile
53*d57664e9SAndroid Build Coastguard Worker      *  and recurse into sub-directories.
54*d57664e9SAndroid Build Coastguard Worker      */
55*d57664e9SAndroid Build Coastguard Worker     struct dirent* entry;
56*d57664e9SAndroid Build Coastguard Worker     while ((entry = dw->nextEntry()) != NULL) {
57*d57664e9SAndroid Build Coastguard Worker         String8 entryName(entry->d_name);
58*d57664e9SAndroid Build Coastguard Worker         if (entry->d_name[0] == '.') // Skip hidden files and directories
59*d57664e9SAndroid Build Coastguard Worker             continue;
60*d57664e9SAndroid Build Coastguard Worker 
61*d57664e9SAndroid Build Coastguard Worker         String8 fullPath = appendPathCopy(basePath, entryName);
62*d57664e9SAndroid Build Coastguard Worker         // If this entry is a directory we'll recurse into it
63*d57664e9SAndroid Build Coastguard Worker         if (isDirectory(fullPath.c_str()) ) {
64*d57664e9SAndroid Build Coastguard Worker             DirectoryWalker* copy = dw->clone();
65*d57664e9SAndroid Build Coastguard Worker             findFiles(fullPath, extensions, fileStore,copy);
66*d57664e9SAndroid Build Coastguard Worker             delete copy;
67*d57664e9SAndroid Build Coastguard Worker         }
68*d57664e9SAndroid Build Coastguard Worker 
69*d57664e9SAndroid Build Coastguard Worker         // If this entry is a file, we'll pass it over to checkAndAddFile
70*d57664e9SAndroid Build Coastguard Worker         if (isFile(fullPath.c_str()) ) {
71*d57664e9SAndroid Build Coastguard Worker             checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
72*d57664e9SAndroid Build Coastguard Worker         }
73*d57664e9SAndroid Build Coastguard Worker     }
74*d57664e9SAndroid Build Coastguard Worker 
75*d57664e9SAndroid Build Coastguard Worker     // Clean up
76*d57664e9SAndroid Build Coastguard Worker     dw->closeDir();
77*d57664e9SAndroid Build Coastguard Worker 
78*d57664e9SAndroid Build Coastguard Worker     return true;
79*d57664e9SAndroid Build Coastguard Worker }
80*d57664e9SAndroid Build Coastguard Worker 
checkAndAddFile(const String8 & path,const struct stat * stats,Vector<String8> & extensions,KeyedVector<String8,time_t> & fileStore)81*d57664e9SAndroid Build Coastguard Worker void SystemFileFinder::checkAndAddFile(const String8& path, const struct stat* stats,
82*d57664e9SAndroid Build Coastguard Worker                                        Vector<String8>& extensions,
83*d57664e9SAndroid Build Coastguard Worker                                        KeyedVector<String8,time_t>& fileStore)
84*d57664e9SAndroid Build Coastguard Worker {
85*d57664e9SAndroid Build Coastguard Worker     // Loop over the extensions, checking for a match
86*d57664e9SAndroid Build Coastguard Worker     bool done = false;
87*d57664e9SAndroid Build Coastguard Worker     String8 ext(getPathExtension(path));
88*d57664e9SAndroid Build Coastguard Worker     ext.toLower();
89*d57664e9SAndroid Build Coastguard Worker     for (size_t i = 0; i < extensions.size() && !done; ++i) {
90*d57664e9SAndroid Build Coastguard Worker         String8 ext2 = getPathExtension(extensions[i]);
91*d57664e9SAndroid Build Coastguard Worker         ext2.toLower();
92*d57664e9SAndroid Build Coastguard Worker         // Compare the extensions. If a match is found, add to storage.
93*d57664e9SAndroid Build Coastguard Worker         if (ext == ext2) {
94*d57664e9SAndroid Build Coastguard Worker             done = true;
95*d57664e9SAndroid Build Coastguard Worker             fileStore.add(path,stats->st_mtime);
96*d57664e9SAndroid Build Coastguard Worker         }
97*d57664e9SAndroid Build Coastguard Worker     }
98*d57664e9SAndroid Build Coastguard Worker }
99*d57664e9SAndroid Build Coastguard Worker 
100