151 lines
4.4 KiB
C
151 lines
4.4 KiB
C
#ifndef ED_FILE_IO_INCLUDED
|
|
#define ED_FILE_IO_INCLUDED
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "string.h"
|
|
|
|
uint64_t get_file_size(string file_path);
|
|
bool load_file(string file_path, size_t size, void *buffer);
|
|
|
|
#ifdef ED_FILE_IO_IMPLEMENTATION
|
|
|
|
#if defined(__unix__)
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
unsigned long get_file_size(const char *filePath) {
|
|
FILE *file = fopen(filePath, "r");
|
|
assert(file && "get_file_size: failed to open file");
|
|
|
|
fseek(file, 0, SEEK_END);
|
|
long fsize = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
fclose(file);
|
|
|
|
return fsize;
|
|
}
|
|
|
|
bool load_file(const char *filePath, unsigned long size, void *buffer) {
|
|
FILE *file = fopen(filePath, "r");
|
|
assert(file && "load_file: failed to open file");
|
|
|
|
fseek(file, 0, SEEK_END);
|
|
long fsize = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
fread(buffer, fsize, 1, file);
|
|
|
|
fclose(file);
|
|
|
|
return true;
|
|
}
|
|
|
|
#elif defined(_WIN32) || defined(WIN32)
|
|
#include <windows.h>
|
|
#define assertm(exp, msg) assert(((void)msg, exp))
|
|
|
|
VOID CALLBACK FileIOCompletionRoutine(
|
|
__in DWORD dwErrorCode,
|
|
__in DWORD dwNumberOfBytesTransfered,
|
|
__in LPOVERLAPPED lpOverlapped )
|
|
{
|
|
printf("Error code: %li", dwErrorCode);
|
|
printf("Number of bytes: %li", dwNumberOfBytesTransfered);
|
|
}
|
|
|
|
uint64_t get_file_size(string file_path) {
|
|
char *file_path_with_sentinel = malloc(file_path.len + 1);
|
|
memcpy(file_path_with_sentinel, file_path.data, file_path.len + 1);
|
|
file_path_with_sentinel[file_path.len] = 0;
|
|
|
|
// FIXME: convert to null teminated string
|
|
HANDLE hFile = CreateFile(file_path_with_sentinel,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
|
|
LARGE_INTEGER size;
|
|
assert(GetFileSizeEx(hFile, &size) && "get_file_size: failed to get file size");
|
|
|
|
free(file_path_with_sentinel);
|
|
return size.LowPart;
|
|
}
|
|
|
|
bool load_file(string file_path, size_t size, void *buffer) {
|
|
char *file_path_with_sentinel = malloc(file_path.len + 1);
|
|
memcpy(file_path_with_sentinel, file_path.data, file_path.len + 1);
|
|
file_path_with_sentinel[file_path.len] = 0;
|
|
|
|
// FIXME: convert to null teminated string
|
|
HANDLE hFile = CreateFile(file_path_with_sentinel,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
OVERLAPPED ol = {0};
|
|
unsigned long bytesRead = 0;
|
|
if (!ReadFile(hFile, buffer, size, &bytesRead, NULL)) {
|
|
unsigned long error = GetLastError();
|
|
unsigned long msg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, size, NULL);
|
|
|
|
printf("failed to load file: %s\n", (char *)buffer);
|
|
assert(false && "failed to read file");
|
|
}
|
|
assert(bytesRead == size && "load_file: didn't one-shot read the whole file");
|
|
|
|
free(file_path_with_sentinel);
|
|
return true;
|
|
}
|
|
#elif defined(__APPLE__)
|
|
#include <Foundation/Foundation.h>
|
|
|
|
uint64_t get_file_size(string file_path) {
|
|
NSFileManager* file_manager = [NSFileManager defaultManager];
|
|
NSString *path = [file_manager stringWithFileSystemRepresentation:(const char *)file_path.data length:file_path.len];
|
|
|
|
NSError *error = NULL;
|
|
NSDictionary<NSFileAttributeKey, id> *attributes = [file_manager attributesOfItemAtPath:path error:&error];
|
|
|
|
if (error) {
|
|
NSLog(@"error getting file attributes: %@\n", error.description);
|
|
return 0;
|
|
}
|
|
|
|
NSNumber *file_size = [attributes objectForKey:NSFileSize];
|
|
|
|
return file_size.unsignedLongLongValue;
|
|
}
|
|
|
|
bool load_file(string file_path, size_t size, void *buffer) {
|
|
NSFileManager* file_manager = [NSFileManager defaultManager];
|
|
NSString *path = [file_manager stringWithFileSystemRepresentation:(const char *)file_path.data length:file_path.len];
|
|
|
|
NSData *data = [file_manager contentsAtPath:path];
|
|
if (data == NULL) {
|
|
fprintf(stderr, "failed to load file: %.*s\n", (int)file_path.len, file_path.data);
|
|
return false;
|
|
}
|
|
|
|
if (data.length > size) {
|
|
fprintf(stderr, "buffer not large enough for file: %.*s\n", (int)file_path.len, file_path.data);
|
|
}
|
|
|
|
memcpy(buffer, data.bytes, data.length);
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|