Files
fastfetch/src/common/io/io_windows.c
T
2023-02-11 16:05:54 +08:00

164 lines
4.3 KiB
C

#include "io.h"
static void createSubfolders(const char* fileName)
{
FFstrbuf path;
ffStrbufInit(&path);
while(*fileName != '\0')
{
ffStrbufAppendC(&path, *fileName);
if(*fileName == '/')
CreateDirectoryA(path.chars, NULL);
++fileName;
}
ffStrbufDestroy(&path);
}
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
{
HANDLE handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
{
createSubfolders(fileName);
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
return false;
}
DWORD written;
bool ret = !!WriteFile(handle, data, (DWORD)dataSize, &written, NULL);
CloseHandle(handle);
return ret;
}
bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
{
DWORD readed = 0;
LARGE_INTEGER fileSize;
if(!GetFileSizeEx(handle, &fileSize))
fileSize.QuadPart = 0;
ffStrbufEnsureFree(buffer, fileSize.QuadPart > 0 ? (uint32_t)fileSize.QuadPart : 31);
uint32_t free = ffStrbufGetFree(buffer);
bool success;
while(
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &readed, NULL)) &&
(uint32_t) readed == free
) {
buffer->length += (uint32_t) readed;
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
free = ffStrbufGetFree(buffer);
}
if(readed > 0)
buffer->length += (uint32_t) readed;
buffer->chars[buffer->length] = '\0';
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
return success;
}
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
{
HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
return -1;
ssize_t readed = ffReadFDData(handle, dataSize, data);
CloseHandle(handle);
return readed;
}
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
{
HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE)
return false;
bool ret = ffAppendFDBuffer(handle, buffer);
CloseHandle(handle);
return ret;
}
bool ffPathExists(const char* path, FFPathType type)
{
DWORD attr = GetFileAttributesA(path);
if(attr == INVALID_FILE_ATTRIBUTES)
return false;
if(type & FF_PATHTYPE_REGULAR && !(attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
if(type & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
return true;
if(type & FF_PATHTYPE_LINK && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
return true;
return false;
}
bool ffSuppressIO(bool suppress)
{
(void) suppress; //Not implemented.
return false;
}
void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* folderName)
{
uint32_t folderLength = folder->length;
if(folderName != NULL)
printf("%s/\n", folderName);
ffStrbufAppendC(folder, '*');
WIN32_FIND_DATAA entry;
HANDLE hFind = FindFirstFileA(folder->chars, &entry);
if(hFind == INVALID_HANDLE_VALUE)
return;
do
{
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(strcmp(entry.cFileName, ".") == 0 || strcmp(entry.cFileName, "..") == 0)
continue;
ffStrbufSubstrBefore(folder, folderLength);
ffStrbufAppendS(folder, entry.cFileName);
ffStrbufAppendC(folder, '/');
listFilesRecursively(folder, (uint8_t) (indentation + 1), entry.cFileName);
ffStrbufSubstrBefore(folder, folderLength);
continue;
}
for(uint8_t i = 0; i < indentation; i++)
fputs(" | ", stdout);
puts(entry.cFileName);
} while (FindNextFileA(hFind, &entry));
FindClose(hFind);
}
void ffListFilesRecursively(const char* path)
{
FFstrbuf folder;
ffStrbufInitS(&folder, path);
ffStrbufEnsureEndsWithC(&folder, '/');
listFilesRecursively(&folder, 0, NULL);
ffStrbufDestroy(&folder);
}