TEST(TestAliasShortcutUtils, TranslateAliasShortcut) { XFILE::CFile *tmpFile = XBMC_CREATETEMPFILE("noaliastest"); std::string noalias = XBMC_TEMPFILEPATH(tmpFile); std::string noaliastemp = noalias; #if defined(TARGET_DARWIN_OSX) XFILE::CFile *aliasDestFile = XBMC_CREATETEMPFILE("aliastest"); std::string alias = XBMC_TEMPFILEPATH(aliasDestFile); //we only need the path here so delete the alias file //which will be recreated as shortcut later: XBMC_DELETETEMPFILE(aliasDestFile); // create alias from a pointing to /Volumes CDarwinUtils::CreateAliasShortcut(alias, "/Volumes"); // resolve the shortcut TranslateAliasShortcut(alias); EXPECT_STREQ("/Volumes", alias.c_str()); XFILE::CFile::Delete(alias); #endif // translating a non-shortcut url should result in no change... TranslateAliasShortcut(noaliastemp); EXPECT_STREQ(noaliastemp.c_str(), noalias.c_str()); XBMC_DELETETEMPFILE(tmpFile); //translate empty should stay empty std::string emptyString; TranslateAliasShortcut(emptyString); EXPECT_STREQ("", emptyString.c_str()); // translate non-existent file should result in no change... std::string nonExistingFile="/IDontExistsNormally/somefile.txt"; std::string resolvedNonExistingFile=nonExistingFile; TranslateAliasShortcut(resolvedNonExistingFile); EXPECT_STREQ(resolvedNonExistingFile.c_str(), nonExistingFile.c_str()); }
BOOL FindNextFile(HANDLE hHandle, LPWIN32_FIND_DATA lpFindData) { if (lpFindData == NULL || hHandle == NULL || hHandle->GetType() != CXHandle::HND_FIND_FILE) return FALSE; if ((unsigned int) hHandle->m_nFindFileIterator >= hHandle->m_FindFileResults.size()) return FALSE; CStdString strFileName = hHandle->m_FindFileResults[hHandle->m_nFindFileIterator++]; CStdString strFileNameTest = hHandle->m_FindFileDir + strFileName; if (IsAliasShortcut(strFileNameTest)) TranslateAliasShortcut(strFileNameTest); struct stat64 fileStat; memset(&fileStat, 0, sizeof(fileStat)); if (stat64(strFileNameTest, &fileStat) == -1) return FALSE; bool bIsDir = false; if (S_ISDIR(fileStat.st_mode)) { bIsDir = true; } memset(lpFindData,0,sizeof(WIN32_FIND_DATA)); lpFindData->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; strcpy(lpFindData->cFileName, strFileName.c_str()); if (bIsDir) lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; if (strFileName[0] == '.') lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; if (access(strFileName, R_OK) == 0 && access(strFileName, W_OK) != 0) lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; TimeTToFileTime(fileStat.st_ctime, &lpFindData->ftCreationTime); TimeTToFileTime(fileStat.st_atime, &lpFindData->ftLastAccessTime); TimeTToFileTime(fileStat.st_mtime, &lpFindData->ftLastWriteTime); lpFindData->nFileSizeHigh = (DWORD)(fileStat.st_size >> 32); lpFindData->nFileSizeLow = (DWORD)fileStat.st_size; return TRUE; }
HANDLE FindFirstFile(LPCSTR szPath,LPWIN32_FIND_DATA lpFindData) { if (lpFindData == NULL || szPath == NULL) return NULL; CStdString strPath(szPath); if (IsAliasShortcut(strPath)) TranslateAliasShortcut(strPath); if (strPath.empty()) return INVALID_HANDLE_VALUE; strPath.Replace("\\","/"); // if the file name is a directory then we add a * to look for all files in this directory #if defined(__APPLE__) || defined(__FreeBSD__) DIR *testDir = opendir(strPath.c_str()); #else DIR *testDir = opendir(szPath); #endif if (testDir) { strPath += "/*"; closedir(testDir); } int nFilePos = strPath.ReverseFind(XBMC_FILE_SEP); CStdString strDir = "."; CStdString strFiles = strPath; if (nFilePos > 0) { strDir = strPath.substr(0,nFilePos); strFiles = strPath.substr(nFilePos + 1); } if (strFiles == "*.*") strFiles = "*"; strFiles = CStdString("^") + strFiles + "$"; strFiles.Replace(".","\\."); strFiles.Replace("*",".*"); strFiles.Replace("?","."); strFiles.MakeLower(); // Do we really want this case insensitive? CRegExp re(true); if (re.RegComp(strFiles.c_str()) == NULL) return(INVALID_HANDLE_VALUE); struct dirent **namelist = NULL; int n = scandir(strDir, &namelist, 0, alphasort); CXHandle *pHandle = new CXHandle(CXHandle::HND_FIND_FILE); pHandle->m_FindFileDir = strDir; while (n-- > 0) { CStdString strComp(namelist[n]->d_name); strComp.MakeLower(); if (re.RegFind(strComp.c_str()) >= 0) pHandle->m_FindFileResults.push_back(namelist[n]->d_name); free(namelist[n]); } free(namelist); if (pHandle->m_FindFileResults.size() == 0) { delete pHandle; return INVALID_HANDLE_VALUE; } FindNextFile(pHandle, lpFindData); return pHandle; }
HANDLE FindFirstFile(LPCSTR szPath,LPWIN32_FIND_DATA lpFindData) { if (lpFindData == NULL || szPath == NULL) return NULL; CStdString strPath(szPath); if (IsAliasShortcut(strPath)) TranslateAliasShortcut(strPath); if (strPath.empty()) return INVALID_HANDLE_VALUE; StringUtils::Replace(strPath, '\\','/'); // if the file name is a directory then we add a * to look for all files in this directory #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || defined(TARGET_ANDROID) DIR *testDir = opendir(strPath.c_str()); #else DIR *testDir = opendir(szPath); #endif if (testDir) { strPath += "/*"; closedir(testDir); } size_t nFilePos = strPath.rfind(XBMC_FILE_SEP); CStdString strDir = "."; CStdString strFiles = strPath; if (nFilePos > 0) { strDir = strPath.substr(0,nFilePos); strFiles = strPath.substr(nFilePos + 1); } if (strFiles == "*.*") strFiles = "*"; strFiles = CStdString("^") + strFiles + "$"; StringUtils::Replace(strFiles, ".","\\."); StringUtils::Replace(strFiles, "*",".*"); StringUtils::Replace(strFiles, "?","."); StringUtils::ToLower(strFiles); // Do we really want this case insensitive? CRegExp re(true); if (!re.RegComp(strFiles.c_str())) return(INVALID_HANDLE_VALUE); struct dirent **namelist = NULL; #if defined(TARGET_ANDROID) // android is more strict with the sort function. Let's hope it is implemented correctly. typedef int (*sortFunc)(const struct dirent ** a, const struct dirent **b); int n = scandir(strDir, &namelist, 0, (sortFunc)alphasort); #else int n = scandir(strDir, &namelist, 0, alphasort); #endif CXHandle *pHandle = new CXHandle(CXHandle::HND_FIND_FILE); pHandle->m_FindFileDir = strDir; while (n-- > 0) { CStdString strComp(namelist[n]->d_name); StringUtils::ToLower(strComp); if (re.RegFind(strComp.c_str()) >= 0) pHandle->m_FindFileResults.push_back(namelist[n]->d_name); free(namelist[n]); } free(namelist); if (pHandle->m_FindFileResults.size() == 0) { delete pHandle; return INVALID_HANDLE_VALUE; } FindNextFile(pHandle, lpFindData); return pHandle; }