A collection of basic/generally desirable code I use across multiple C++ projects.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

209 lines
4.9 KiB

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> // fopen, fseek, ftell, fclose
#undef _CRT_SECURE_NO_WARNINGS
#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 <windows.h>
// writes the filenames into the provided array |outFileNames|, must be allocated ahead of time.
void File::GetFileNamesInFolder(const char* path, Array<char*>* 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 <dirent.h>
void File::GetFileNamesInFolder(const char* path, Array<char*>* 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 <sys/types.h>
#include <sys/stat.h>
#ifndef WIN32
#include <unistd.h>
#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);
}