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
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);
|
|
}
|
|
|