2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #include <unordered_map>
34 bool ICompare(const std::string& a, const std::string& b)
36 return a.length() == b.length() &&
37 std::equal(b.begin(), b.end(), a.begin(),
38 [](unsigned char a, unsigned char b)
39 { return std::tolower(a) == std::tolower(b); });
42 bool ICompare(const std::string& a, int a_offset, const std::string& b, int b_offset, int length)
44 return static_cast<int>(a.length()) - length >= a_offset &&
45 static_cast<int>(b.length()) - length >= b_offset &&
46 std::equal(b.begin() + b_offset, b.begin() + b_offset + length, a.begin() + a_offset,
47 [](unsigned char a, unsigned char b)
48 { return std::tolower(a) == std::tolower(b); });
51 bool IsManagedAssembly(const std::string& filename)
53 return ICompare(filename, filename.size()-4, ".dll", 0, 4) ||
54 ICompare(filename, filename.size()-4, ".exe", 0, 4);
57 bool IsNativeImage(const std::string& filename)
59 return ICompare(filename, filename.size()-7, ".ni", 0, 3);
62 std::string ReadSelfPath()
65 ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
68 return std::string(buff);
74 std::string ConcatPath(const std::string& path1, const std::string& path2)
76 std::string path(path1);
77 if (path.back() == PATH_SEPARATOR)
83 path += PATH_SEPARATOR;
90 void AppendPath(std::string& path1, const std::string& path2)
92 if (path1.back() == PATH_SEPARATOR)
98 path1 += PATH_SEPARATOR;
103 std::string AbsolutePath(const std::string& path)
107 char realPath[PATH_MAX];
108 if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0')
110 absPath.assign(realPath);
116 std::string Basename(const std::string& path)
118 auto pos = path.find_last_of(PATH_SEPARATOR);
119 if (pos != std::string::npos)
121 return path.substr(0, pos);
125 return std::string(".");
130 bool EndWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& filename)
132 std::string::size_type len1 = str1.length();
133 std::string::size_type len2 = str2.length();
134 if (len2 > len1) return false;
137 bool result = std::all_of(str1.cend() - len2, str1.end(),
138 [&i, &str2] (char x) {
139 return std::tolower(x) == std::tolower(str2[i++]);
143 filename = str1.substr(0, len1 - len2);
148 bool FileNotExist(const std::string& path)
151 return stat(path.c_str(), &sb) != 0;
154 static bool ExtCheckAndGetFileNameIfExist(const std::string& dir, const std::string& ext, struct dirent* entry, std::string& filename)
156 std::string fname(entry->d_name);
157 if (fname.length() < ext.length() ||
158 fname.compare(fname.length() - ext.length(), ext.length(), ext) != 0)
162 std::string fullname = ConcatPath(dir, entry->d_name);
163 switch (entry->d_type)
168 if (FileNotExist(fullname))
181 std::string StripNIDLL(const std::string& path)
183 std::string npath(path);
184 if (path.size() < 5) return npath;
185 if (!strncasecmp(path.c_str() + path.size() - 4, ".dll", 4))
187 npath = path.substr(0, path.size()-4);
188 }else if (!strncasecmp(path.c_str() + path.size() - 4, ".exe", 4))
190 npath = path.substr(0, path.size()-4);
192 if (!strncasecmp(npath.c_str() + npath.size() - 3, ".ni", 3))
194 return npath.substr(0, npath.size()-3);
199 std::string JoinStrings(const std::vector<std::string>& strings, const char* const delimeter)
201 switch (strings.size())
208 std::ostringstream os;
209 std::copy(strings.begin(), strings.end()-1, std::ostream_iterator<std::string>(os, delimeter));
210 os << *strings.rbegin();
221 bool operator == (const AssemblyFile& lhs, const AssemblyFile& rhs)
223 return lhs.noext == rhs.noext && lhs.ext == rhs.ext;
229 struct hash<AssemblyFile>
231 std::size_t operator () (const AssemblyFile& f) const
233 const std::size_t h1 = std::hash<std::string>{}(f.noext);
234 const std::size_t h2 = std::hash<std::string>{}(f.ext);
236 return h1 ^ (h2 << 1);
241 void AssembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList)
243 std::map<std::string, std::string> assemblyList;
244 std::map<std::string, std::string> tmpList;
246 auto reader = [&assemblyList, &tmpList] (const char* path, const char* name)
248 std::string _path(path);
249 if (IsManagedAssembly(_path))
251 std::string dll_name = StripNIDLL(name);
252 std::pair<std::map<std::string, std::string>::iterator, bool> ret;
253 ret = tmpList.insert(std::pair<std::string, std::string>(dll_name, _path));
254 if (ret.second == false)
256 if (IsNativeImage(_path))
258 tmpList[dll_name] = _path;
264 for (auto directory : directories)
266 ScanFilesInDir(directory.c_str(), reader, 1);
267 // merge scaned dll list to tpa list.
268 // if the dll is already exist in the list, that is skipped.
269 assemblyList.insert(tmpList.begin(), tmpList.end());
272 std::map<std::string, std::string>::iterator it;
273 for (it = assemblyList.begin(); it != assemblyList.end(); it++)
275 tpaList += it->second + ':';
277 if (tpaList.back() == ':')
283 void ScanFilesInDir(const char* directory, FileReader reader, unsigned int depth)
286 struct dirent* entry;
289 dir = opendir(directory);
293 //_ERR("Can not open directory : %s", directory);
297 std::vector<std::string> innerDirectories;
299 while ((entry = readdir(dir)) != nullptr)
302 std::string path = ConcatPath(directory, entry->d_name);
303 switch (entry->d_type)
312 if (stat(path.c_str(), &sb) == -1)
317 if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))
326 reader(path.c_str(), entry->d_name);
328 else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
330 innerDirectories.push_back(path);
336 for (auto& d : innerDirectories)
338 ScanFilesInDir(d.c_str(), reader, depth-1);