mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 00:37:23 +01:00
164 lines
4.3 KiB
C
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);
|
|
}
|