bool Directory::GetAttribute(const String& fileName, nextar::FileAttribute & attr) { String path; MultiStringHelper pathsL(paths); MultiStringHelper::Iterator it = pathsL.Iterate(); while (it.HasNext(path)) { String fullPath = URL::GetAppendedPath(path, fileName); #if NEX_WINDOWS==1 if (StringUtils::IsAscii(fullPath)) { struct stat filestat; int ret = stat(fullPath.c_str(), &filestat); if (ret == 0) { attr.fileName = URL(GetName(), fileName); attr.flags = 0; StatToAttribute(filestat, attr); } else return false; } else { UniString fullPathUni = StringUtils::ToUtf16(fullPath); DWORD flags = GetFileAttributesW((const wchar_t*)fullPathUni.c_str()); if (flags == INVALID_FILE_ATTRIBUTES) return false; else attr.fileName = URL(GetName(), fileName); if (flags & FILE_ATTRIBUTE_DIRECTORY) attr.flags = FileAttribute::ATTRIB_DIR; if ((flags & FILE_ATTRIBUTE_READONLY)) attr.flags |= FileAttribute::ATTRIB_READONLY; if ((flags & FILE_ATTRIBUTE_ARCHIVE)) attr.flags |= FileAttribute::ATTRIB_ARC; if ((flags & FILE_ATTRIBUTE_COMPRESSED)) attr.flags |= FileAttribute::ATTRIB_COMPRESSED; HANDLE hFile = CreateFileW((const wchar_t*)fullPathUni.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { FILETIME lastWriteTime; if (GetFileTime(hFile, NULL, NULL, &lastWriteTime)) WriteFileTime(attr.fileTime, lastWriteTime); } attr.uncompressedSize = GetFileSize(hFile, NULL); if ((flags & FILE_ATTRIBUTE_COMPRESSED)) attr.compressedSize = GetCompressedFileSizeW((const wchar_t*)fullPathUni.c_str(), NULL); } #elif NEX_LINUX==1 struct stat filestat; int ret = stat(fullPath.c_str(), &filestat); if (ret == 0) { attr.fileName = URL(GetName(), fileName); attr.flags = 0; StatToAttribute(filestat, attr); } else return false; #else //problem # error Platform error #endif return true; } return false;
void Directory::_VisitDirectory(const String& path, const String& pattern, const String& subPath, ScanCallback* callback, bool recursive) { FileAttribute attr; String fullPath; fullPath = path; if (subPath.length()) fullPath = URL::GetAppendedPath(fullPath, subPath); else fullPath = path; #if defined(NEX_MSVC) if (pattern.length()) fullPath = URL::GetAppendedPath(fullPath, pattern); UniString fullPathUni = StringUtils::ToUtf16(fullPath); intptr_t fileHandle, res; struct _wfinddata_t data; fileHandle = _wfindfirst((const wchar_t*)fullPathUni.c_str(), &data); res = 0; while (fileHandle != -1 && res != -1) { String utf8path = StringUtils::ToUtf8((const char16_t*)data.name); String fullPath = URL::GetAppendedPath(path, utf8path); attr.fileName = URL(GetName(), URL::GetAppendedPath(subPath, utf8path)); attr.flags = 0; if ((data.attrib & _A_SUBDIR)) { if ((!URL::IsReservedPath(utf8path.c_str())) && recursive) _VisitDirectory(fullPath, pattern, attr.fileName.GetRelativePath(), callback, true); attr.flags = FileAttribute::ATTRIB_DIR; } else if (data.attrib * _A_ARCH) attr.flags = FileAttribute::ATTRIB_ARC; if (data.attrib * _A_RDONLY) attr.flags |= FileAttribute::ATTRIB_READONLY; NEX_SET_FILE_TIME(attr.fileTime, data.time_write); attr.compressedSize = data.size; attr.uncompressedSize = data.size; callback->FoundFile(attr, this); res = _wfindnext(fileHandle, &data); } if (fileHandle != -1) _findclose(fileHandle); #elif defined(NEX_GCC) /** todo Fix this */ DIR *dp; struct dirent *dirp; fullPath = path + "/" + subPath; dp = opendir(fullPath.c_str()); if (dp) { while ((dirp = readdir(dp)) != NULL) { if (!pattern.length() || StringUtils::PatternMatch(pattern.c_str(), dirp->d_name, true)) { String fullPathName = URL::GetAppendedPath(fullPath, dirp->d_name); attr.fileName = URL(GetName(), URL::GetAppendedPath(subPath, dirp->d_name)); attr.flags = 0; struct stat filestat; int ret = stat(fullPathName.c_str(), &filestat); if (ret == 0) StatToAttribute(filestat, attr); callback->FoundFile(attr, this); if (recursive && (attr.flags & FileAttribute::ATTRIB_DIR) && !URL::IsReservedPath(dirp->d_name)) _VisitDirectory(fullPath, pattern, attr.fileName.GetRelativePath(), callback, true); } } closedir(dp); } #endif }