#ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include // fopen, fseek, ftell, fclose #endif #include "alloc.h" #include "array.hpp" #include "file.h" #include "print.h" #include "types.h" FILE* File :: Open(const char* path, const char* mode) { ULE_TYPES_H_FTAG; return fopen(path, mode); } FILE* File :: Open(const char* path, size_t* outSize, const char* mode) { ULE_TYPES_H_FTAG; FILE* fp = File :: Open(path, mode); if (fp == null) { return null; } // get the file's size in bytes fseek(fp, 0, SEEK_END); *outSize = ftell(fp); fseek(fp, 0L, SEEK_SET); return fp; } void File :: Close(FILE* file) { fclose(file); } size_t File :: Size(const char* path) { ULE_TYPES_H_FTAG; FILE* fp = File :: Open(path); // get the file's size in bytes fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0L, SEEK_SET); fclose(fp); return size; } size_t File :: Size(FILE* fp) { ULE_TYPES_H_FTAG; fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0L, SEEK_SET); return size; } u8* File :: Read(const char* path) { ULE_TYPES_H_FTAG; FILE* fp = File :: Open(path, "rb"); if (fp == null) { return null; } // get the file's size in bytes fseek(fp, 0, SEEK_END); u32 size = ftell(fp); fseek(fp, 0L, SEEK_SET); char* buffer = (char*) pMalloc(size + 1); fread(buffer, sizeof (char), size + 1, fp); buffer[size] = '\0'; fclose(fp); return (u8*) buffer; } u8* File :: Read(const char* path, size_t* outSize) { ULE_TYPES_H_FTAG; FILE* fp = File :: Open(path, "rb"); if (fp == null) { return null; } // get the file's size in bytes fseek(fp, 0, SEEK_END); size_t size = ftell(fp); // if we got a valid pointer to a size_t we should report the size back. if (outSize != null) { *outSize = size; } fseek(fp, 0L, SEEK_SET); char* buffer = (char*) pMalloc(size + 1); fread(buffer, sizeof (char), size + 1, fp); buffer[size] = '\0'; fclose(fp); return (u8*) buffer; } size_t File :: Read(FILE* fp, void* destination) { ULE_TYPES_H_FTAG; fseek(fp, 0, SEEK_END); size_t size = ftell(fp); fseek(fp, 0L, SEEK_SET); fread(destination, sizeof (char), size + 1, fp); return size; } size_t File :: Read(FILE* fp, void* destination, size_t size) { ULE_TYPES_H_FTAG; return fread(destination, sizeof (char), size + 1, fp); } s32 File :: Write(const char* path, char* data, u32 count) { ULE_TYPES_H_FTAG; FILE* fp = File :: Open(path, "wb"); if (fp == null) { return -1; // failed to open the file } size_t writtenCount = fwrite(data, 1, count, fp); fclose(fp); if (writtenCount != count) { return -2; // wrote only partially } return 0; } #if _WIN32 #include // writes the filenames into the provided array |outFileNames|, must be allocated ahead of time. void File :: GetFileNamesInFolder(const char* path, Array* outFileNames) { ULE_TYPES_H_FTAG; massert(path != null, "provided 'null' for path argument"); massert(outFileNames != null, "provided 'null' for array argument"); WIN32_FIND_DATAA findData; HANDLE hFind = INVALID_HANDLE_VALUE; String str; if (path[String::len(path) - 1] != '/') { str = String64f("%s/*", path); } else { str = String64f("%s*", path); } hFind = FindFirstFileA(str.c_str(), &findData); if (hFind == INVALID_HANDLE_VALUE) die("failed to open folder: %s", path); while (FindNextFileA(hFind, &findData) != 0) { if (findData.cFileName[0] != '.') { outFileNames->push(String::cpy(findData.cFileName)); } } FindClose(hFind); } #else #include void File :: GetFileNamesInFolder(const char* path, Array* outFileNames) { ULE_TYPES_H_FTAG; massert(path != null, "provided 'null' for path argument"); massert(outFileNames != null, "provided 'null' for array argument"); DIR* dir = opendir(path); struct dirent* d; if (dir == null) die("failed to open folder: %s", path); do { d = readdir(dir); if (d == null) break; if (d->d_name[0] != '.') outFileNames->push(String::cpy(d->d_name)); } while (1); closedir(dir); } #endif #include #include #ifndef WIN32 #include #endif // msvc provides a 'stat' equivalent as _stat. #ifdef WIN32 #define stat _stat #endif time_t File :: LastModified(const char* path) { ULE_TYPES_H_FTAG; struct stat result; if (stat(path, &result) == 0) { return result.st_mtime; } massert(false, "failed to get last modified timestamp."); return -1; } #undef stat s32 File :: Rename(const char* oldFilename, const char* newFilename) { return rename(oldFilename, newFilename); } s32 File :: Remove(const char* path) { return remove(path); } #ifdef _WIN32 #include FILE* OpenExclusive(const char* path) { HFILE result = OpenFile(path, null, OF_SHARE_EXCLUSIVE); if (result == HFILE_ERROR) { println("failed"); } return null; } #else FILE* OpenExclusive(const char* path) { return null; } #endif