Compare commits
2 commits
66ab9fbbdf
...
6a5a80b3f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a5a80b3f5 | ||
|
|
d44d460cad |
3 changed files with 129 additions and 12 deletions
|
|
@ -23,7 +23,7 @@ typedef enum {
|
||||||
COSMS_FILE_FAILED_TO_WRITE = -8,
|
COSMS_FILE_FAILED_TO_WRITE = -8,
|
||||||
} CosmsFileError;
|
} CosmsFileError;
|
||||||
|
|
||||||
CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned int *size);
|
CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned long long *size);
|
||||||
CosmsFileError cosms_core_file_write(const char *path, const char *content, unsigned int size, bool override);
|
CosmsFileError cosms_core_file_write(const char *path, const char *content, unsigned long long size, bool override);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
133
src/file.c
133
src/file.c
|
|
@ -9,6 +9,7 @@
|
||||||
#include "cosms-core/file.h"
|
#include "cosms-core/file.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -16,9 +17,10 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned int *size) {
|
CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned long long *size) {
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
int file = open(path, O_RDONLY);
|
int file = open(path, O_RDONLY);
|
||||||
if (file == -1) {
|
if (file == -1) {
|
||||||
|
|
@ -45,17 +47,24 @@ CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned i
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = file_stat.st_size;
|
*size = file_stat.st_size;
|
||||||
*content = (char*)malloc(file_stat.st_size * sizeof(char));
|
*content = (char*)malloc((file_stat.st_size + 1) * sizeof(char));
|
||||||
if (content == NULL) {
|
if (content == NULL) {
|
||||||
close(file);
|
close(file);
|
||||||
return COSMS_FILE_FAILED_TO_ALLOCATE;
|
return COSMS_FILE_FAILED_TO_ALLOCATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int remaining_bytes = file_stat.st_size;
|
unsigned long long remaining_bytes = file_stat.st_size;
|
||||||
while (remaining_bytes != 0) {
|
while (remaining_bytes != 0) {
|
||||||
int read_bytes = read(file, (*content) + (file_stat.st_size - remaining_bytes), remaining_bytes);
|
unsigned int bytes_to_read;
|
||||||
|
if (remaining_bytes > UINT_MAX) {
|
||||||
|
bytes_to_read = UINT_MAX;
|
||||||
|
} else {
|
||||||
|
bytes_to_read = (unsigned int)remaining_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_bytes = read(file, (*content) + (file_stat.st_size - remaining_bytes), bytes_to_read);
|
||||||
if (read_bytes == -1) {
|
if (read_bytes == -1) {
|
||||||
free(content);
|
free(*content);
|
||||||
close(file);
|
close(file);
|
||||||
return COSMS_FILE_FAILED_TO_READ;
|
return COSMS_FILE_FAILED_TO_READ;
|
||||||
}
|
}
|
||||||
|
|
@ -63,14 +72,71 @@ CosmsFileError cosms_core_file_read(const char *path, char **content, unsigned i
|
||||||
remaining_bytes -= read_bytes;
|
remaining_bytes -= read_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*content)[file_stat.st_size] = '\0';
|
||||||
close(file);
|
close(file);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
HANDLE file = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (file == INVALID_HANDLE_VALUE) {
|
||||||
|
switch(GetLastError()) {
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
return COSMS_FILE_NOT_FOUND;
|
||||||
|
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_LOCK_VIOLATION:
|
||||||
|
return COSMS_FILE_NO_ACCESS;
|
||||||
|
|
||||||
|
case ERROR_TOO_MANY_OPEN_FILES:
|
||||||
|
return COSMS_FILE_LIMIT_REACHED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return COSMS_FILE_UNKOWN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD high_size;
|
||||||
|
DWORD low_size = GetFileSize(file, &high_size);
|
||||||
|
if (low_size == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return COSMS_FILE_COULD_NOT_READ_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long file_size = ((unsigned long long)high_size << 32) | low_size;
|
||||||
|
|
||||||
|
*size = file_size;
|
||||||
|
*content = (char*)malloc((file_size + 1) * sizeof(char));
|
||||||
|
if (content == NULL) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return COSMS_FILE_FAILED_TO_ALLOCATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long remaining_bytes = file_size;
|
||||||
|
while (remaining_bytes != 0) {
|
||||||
|
DWORD bytes_to_read, read_bytes;
|
||||||
|
if (remaining_bytes > UINT_MAX) {
|
||||||
|
bytes_to_read = UINT_MAX;
|
||||||
|
} else {
|
||||||
|
bytes_to_read = (DWORD)remaining_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadFile(file, (*content) + (file_size - remaining_bytes), bytes_to_read, &read_bytes, NULL)) {
|
||||||
|
free(*content);
|
||||||
|
CloseHandle(file);
|
||||||
|
return COSMS_FILE_FAILED_TO_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining_bytes -= read_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*content)[file_size] = '\0';
|
||||||
|
CloseHandle(file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return COSMS_FILE_OK;
|
return COSMS_FILE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CosmsFileError cosms_core_file_write(const char *path, const char *content, unsigned int size, bool override) {
|
CosmsFileError cosms_core_file_write(const char *path, const char *content, unsigned long long size, bool override) {
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
int file;
|
int file;
|
||||||
if (override) {
|
if (override) {
|
||||||
|
|
@ -96,9 +162,16 @@ CosmsFileError cosms_core_file_write(const char *path, const char *content, unsi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int remaining_bytes = size;
|
unsigned long long remaining_bytes = size;
|
||||||
while (remaining_bytes != 0) {
|
while (remaining_bytes != 0) {
|
||||||
int written_bytes = write(file, content + (size - remaining_bytes), remaining_bytes);
|
unsigned int bytes_to_write;
|
||||||
|
if (remaining_bytes > UINT_MAX) {
|
||||||
|
bytes_to_write = UINT_MAX;
|
||||||
|
} else {
|
||||||
|
bytes_to_write = (unsigned int)remaining_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int written_bytes = write(file, content + (size - remaining_bytes), bytes_to_write);
|
||||||
if (written_bytes == -1) {
|
if (written_bytes == -1) {
|
||||||
close(file);
|
close(file);
|
||||||
return COSMS_FILE_FAILED_TO_WRITE;
|
return COSMS_FILE_FAILED_TO_WRITE;
|
||||||
|
|
@ -109,6 +182,50 @@ CosmsFileError cosms_core_file_write(const char *path, const char *content, unsi
|
||||||
|
|
||||||
close(file);
|
close(file);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
HANDLE file;
|
||||||
|
if (override) {
|
||||||
|
file = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
} else {
|
||||||
|
file = CreateFile(path, FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == INVALID_HANDLE_VALUE) {
|
||||||
|
switch(GetLastError()) {
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
return COSMS_FILE_NOT_FOUND;
|
||||||
|
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_LOCK_VIOLATION:
|
||||||
|
return COSMS_FILE_NO_ACCESS;
|
||||||
|
|
||||||
|
case ERROR_TOO_MANY_OPEN_FILES:
|
||||||
|
return COSMS_FILE_LIMIT_REACHED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return COSMS_FILE_UNKOWN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long remaining_bytes = size;
|
||||||
|
while (remaining_bytes != 0) {
|
||||||
|
DWORD bytes_to_write, written_bytes;
|
||||||
|
if (remaining_bytes > UINT_MAX) {
|
||||||
|
bytes_to_write = UINT_MAX;
|
||||||
|
} else {
|
||||||
|
bytes_to_write = (DWORD)remaining_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteFile(file, content + (size - remaining_bytes), bytes_to_write, &written_bytes, NULL)) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return COSMS_FILE_FAILED_TO_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining_bytes -= written_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return COSMS_FILE_OK;
|
return COSMS_FILE_OK;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
unsigned int buffer_size;
|
unsigned long long buffer_size;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
CosmsFileError error = cosms_core_file_read("test.txt", &buffer, &buffer_size);
|
CosmsFileError error = cosms_core_file_read("test.txt", &buffer, &buffer_size);
|
||||||
if (error != COSMS_FILE_OK) {
|
if (error != COSMS_FILE_OK) {
|
||||||
|
|
@ -11,7 +11,7 @@ int main(void) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("File read with content:\n %s\n", buffer);
|
printf("File read with content:\n%s\n", buffer);
|
||||||
|
|
||||||
char *temp_buffer = "Hello, World!";
|
char *temp_buffer = "Hello, World!";
|
||||||
error = cosms_core_file_write("write-file.txt", temp_buffer, 13, true);
|
error = cosms_core_file_write("write-file.txt", temp_buffer, 13, true);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue