Skip to content

Commit 9a2ef52

Browse files
authored
Merge pull request #2020 from compnerd/iterating-directories
CoreFoundation: simplify and fix `CFIterateDirectory`
2 parents 44e1e4c + a401de4 commit 9a2ef52

File tree

1 file changed

+36
-54
lines changed

1 file changed

+36
-54
lines changed

CoreFoundation/Base.subproj/CFFileUtilities.c

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,66 +1024,48 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
10241024
if (!CFStringGetFileSystemRepresentation(directoryPath, directoryPathBuf, CFMaxPathSize)) return;
10251025

10261026
#if DEPLOYMENT_TARGET_WINDOWS
1027-
CFIndex cpathLen = strlen(directoryPathBuf);
10281027
// Make sure there is room for the additional space we need in the win32 api
1029-
if (cpathLen + 2 < CFMaxPathSize) {
1030-
WIN32_FIND_DATAW file;
1031-
HANDLE handle;
1032-
1033-
directoryPathBuf[cpathLen++] = '\\';
1034-
directoryPathBuf[cpathLen++] = '*';
1035-
directoryPathBuf[cpathLen] = '\0';
1036-
1037-
// Convert UTF8 buffer to windows appropriate UTF-16LE
1038-
// Get the real length of the string in UTF16 characters
1039-
CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, directoryPathBuf, kCFStringEncodingUTF8);
1040-
cpathLen = CFStringGetLength(cfStr);
1041-
// Allocate a wide buffer to hold the converted string, including space for a NULL terminator
1042-
wchar_t *wideBuf = (wchar_t *)malloc((cpathLen + 1) * sizeof(wchar_t));
1043-
// Copy the string into the buffer and terminate
1044-
CFStringGetCharacters(cfStr, CFRangeMake(0, cpathLen), (UniChar *)wideBuf);
1045-
wideBuf[cpathLen] = 0;
1046-
CFRelease(cfStr);
1047-
1048-
WCHAR directory[MAX_PATH + 1];
1049-
if (!CFStringGetCString(directoryPath, directory, MAX_PATH, kCFStringEncodingUTF16))
1050-
return;
1051-
1052-
handle = FindFirstFileW(wideBuf, (LPWIN32_FIND_DATAW)&file);
1053-
if (handle != INVALID_HANDLE_VALUE) {
1054-
WCHAR path[MAX_PATH + 1];
1055-
1056-
do {
1057-
CFIndex nameLen = wcslen(file.cFileName);
1058-
if (file.cFileName[0] == '.' && (nameLen == 1 || (nameLen == 2 && file.cFileName[1] == '.'))) {
1059-
continue;
1060-
}
1028+
if (strlen(directoryPathBuf) > CFMaxPathSize - 2) return;
10611029

1062-
if (!PathCombineW(path, directory, file.cFileName)) {
1063-
continue;
1064-
}
1030+
strlcat(directoryPathBuf, "\\*", CFMaxPathSize);
10651031

1066-
CFStringRef filePath = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)path, wcslen(path) * sizeof(WCHAR), kCFStringEncodingUTF16, NO);
1067-
if (!filePath) {
1068-
continue;
1069-
}
1032+
UniChar wideBuf[CFMaxPathSize];
10701033

1071-
CFStringRef fileName = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)file.cFileName, nameLen * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
1072-
if (!fileName) {
1073-
CFRelease(filePath);
1074-
continue;
1075-
}
1034+
// Convert UTF8 buffer to windows appropriate UTF-16LE
1035+
// Get the real length of the string in UTF16 characters
1036+
CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, directoryPathBuf, kCFStringEncodingUTF8);
10761037

1077-
Boolean isDirectory = file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
1078-
Boolean result = fileHandler(fileName, filePath, isDirectory ? DT_DIR : DT_REG);
1079-
CFRelease(fileName);
1080-
CFRelease(filePath);
1081-
if (!result) break;
1082-
} while (FindNextFileW(handle, &file));
1038+
// Copy the string into the buffer and terminate
1039+
CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), wideBuf);
1040+
wideBuf[CFStringGetLength(cfStr)] = L'\0';
10831041

1084-
FindClose(handle);
1085-
}
1086-
free(wideBuf);
1042+
CFRelease(cfStr);
1043+
1044+
WIN32_FIND_DATAW file;
1045+
HANDLE handle = FindFirstFileW(wideBuf, &file);
1046+
if (handle != INVALID_HANDLE_VALUE) {
1047+
do {
1048+
CFIndex nameLen = wcslen(file.cFileName);
1049+
if (file.cFileName[0] == '.' && (nameLen == 1 || (nameLen == 2 && file.cFileName[1] == '.'))) {
1050+
continue;
1051+
}
1052+
1053+
CFStringRef fileName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, file.cFileName, nameLen);
1054+
if (!fileName) {
1055+
continue;
1056+
}
1057+
1058+
assert(!stuffToPrefix && "prefix not yet implemented");
1059+
CFStringRef filePath = CFRetain(fileName);
1060+
1061+
Boolean isDirectory = file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
1062+
Boolean result = fileHandler(fileName, filePath, isDirectory ? DT_DIR : DT_REG);
1063+
CFRelease(fileName);
1064+
CFRelease(filePath);
1065+
if (!result) break;
1066+
} while (FindNextFileW(handle, &file));
1067+
1068+
FindClose(handle);
10871069
}
10881070
#else
10891071
DIR *dirp;

0 commit comments

Comments
 (0)