diff options
Diffstat (limited to 'source/kit/file.c')
-rw-r--r-- | source/kit/file.c | 691 |
1 files changed, 0 insertions, 691 deletions
diff --git a/source/kit/file.c b/source/kit/file.c deleted file mode 100644 index 3eafc70..0000000 --- a/source/kit/file.c +++ /dev/null @@ -1,691 +0,0 @@ -#include "file.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -enum { PATH_BUF_SIZE = 4096 }; - -#if defined(_WIN32) && !defined(__CYGWIN__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef NOMINMAX -# define NOMINMAX -# endif -# include <windows.h> -# include <shlwapi.h> -#else -# include <dirent.h> -# include <sys/mman.h> -# include <sys/stat.h> -# include <fcntl.h> -# include <unistd.h> -# include <limits.h> -#endif - -#ifdef __APPLE__ -# define st_mtim st_mtimespec -#endif - -#ifndef PATH_MAX -# define PATH_MAX MAX_PATH -#endif - -static i32 is_delim(char c) { - return c == '/' || c == '\\'; -} - -kit_str_builder_t kit_get_env(kit_str_t name, - kit_allocator_t *alloc) { - char *val = getenv(BS(name)); - i64 size = val != NULL ? (i64) strlen(val) : 0; - - str_builder_t result; - DA_INIT(result, size, alloc); - assert(result.size == size); - - if (result.size == size && size > 0) - memcpy(result.values, val, result.size); - else - DA_RESIZE(result, 0); - - return result; -} - -kit_str_builder_t kit_path_norm(kit_str_t path, - kit_allocator_t *alloc) { - str_t parent = SZ(".."); - i64 i, i1, j; - - str_builder_t norm; - DA_INIT(norm, path.size, alloc); - assert(norm.size == path.size); - - if (norm.size != path.size) - return norm; - - memcpy(norm.values, path.values, path.size); - - for (i1 = 0, i = 0; i < path.size; i++) { - if (!is_delim(path.values[i])) - continue; - - str_t s = { .size = i - i1 - 1, .values = path.values + i1 + 1 }; - if (AR_EQUAL(s, parent)) { - i32 have_parent = 0; - i64 i0 = 0; - - for (j = 0; j < i1; j++) { - if (norm.values[j] != '\0') - have_parent = 1; - if (is_delim(norm.values[j])) - i0 = j; - } - - if (have_parent) { - memset(norm.values + i0, '\0', i - i0); - - if (!is_delim(path.values[i0])) - norm.values[i] = '\0'; - } - } - - i1 = i; - } - - i64 size = 0; - - for (i = 0; i < norm.size; i++) { - if (norm.values[i] != '\0') { - if (is_delim(norm.values[i])) - norm.values[size] = KIT_PATH_DELIM_C; - else - norm.values[size] = norm.values[i]; - size++; - } - } - - norm.size = size; - return norm; -} - -kit_str_builder_t kit_path_join(kit_str_t left, kit_str_t right, - kit_allocator_t *alloc) { - i64 left_size = left.size; - i64 right_size = right.size; - char *right_values = right.values; - - if (left_size > 0 && is_delim(left.values[left_size - 1])) - left_size--; - if (right_size > 0 && is_delim(right.values[0])) { - right_size--; - right_values++; - } - - kit_str_builder_t joined; - DA_INIT(joined, left_size + right_size + 1, alloc); - assert(joined.size == left_size + right_size + 1); - - if (joined.size != left_size + right_size + 1) - return joined; - - memcpy(joined.values, left.values, left_size); - joined.values[left_size] = KIT_PATH_DELIM_C; - memcpy(joined.values + left_size + 1, right_values, right_size); - - return joined; -} - -kit_str_builder_t kit_path_user(kit_allocator_t *alloc) { - kit_str_builder_t user = kit_get_env(SZ(KIT_ENV_HOME), alloc); - if (user.size == 0) { - DA_RESIZE(user, 1); - if (user.size == 1) - user.values[0] = '.'; - } - return user; -} - -kit_str_builder_t kit_path_cache(kit_allocator_t *alloc) { - kit_str_builder_t cache, user; - - cache = kit_get_env(SZ("XDG_CACHE_HOME"), alloc); - if (cache.size != 0) - return cache; - DA_DESTROY(cache); - -#if defined(_WIN32) && !defined(__CYGWIN__) - cache = kit_get_env(SZ("TEMP"), alloc); - if (cache.size != 0) - return cache; - DA_DESTROY(cache); -#endif - - user = kit_path_user(alloc); - cache = -#ifdef __APPLE__ - kit_path_join(WRAP_STR(user), SZ("Library" PATH_DELIM "Caches"), - alloc); -#else - kit_path_join(WRAP_STR(user), SZ(".cache"), alloc); -#endif - DA_DESTROY(user); - - return cache; -} - -kit_str_builder_t kit_path_data(kit_allocator_t *alloc) { - kit_str_builder_t data, user; - - data = kit_get_env(SZ("XDG_DATA_HOME"), alloc); - if (data.size != 0) - return data; - DA_DESTROY(data); - -#if defined(_WIN32) && !defined(__CYGWIN__) - data = kit_get_env(SZ("LOCALAPPDATA"), alloc); - if (data.size != 0) - return data; - DA_DESTROY(data); -#endif - - user = kit_path_user(alloc); - data = -#ifdef __APPLE__ - kit_path_join(WRAP_STR(user), SZ("Library"), alloc); -#else - kit_path_join(WRAP_STR(user), SZ(".local" PATH_DELIM "share"), - alloc); -#endif - DA_DESTROY(user); - - return data; -} - -kit_str_t kit_path_index(kit_str_t path, i64 index) { - str_t s = { .size = 0, .values = NULL }; - - i64 i0 = 0; - i64 i = 0; - i64 n = 0; - - for (; i < path.size; i++) { - if (!is_delim(path.values[i])) - continue; - - if (i0 < i) { - if (n++ == index) { - s.values = path.values + i0; - s.size = i - i0; - return s; - } - } - - i0 = i + 1; - } - - if (n == index) { - s.values = path.values + i0; - s.size = i - i0; - } - - return s; -} - -kit_str_t kit_path_take(kit_str_t path, i64 count) { - str_t s = { .size = 0, .values = path.values }; - - i64 i0 = 0; - i64 i = 0; - i64 n = 0; - - for (; i < path.size; i++) { - if (!is_delim(path.values[i])) - continue; - - if (i0 < i) { - if (n++ == count) { - s.size = i; - return s; - } - } - - i0 = i + 1; - } - - if (n == count) - s.size = i; - - return s; -} - -// TODO -// Long path support for Windows -// -static void kit_prepare_path_(char *buf, kit_str_t path) { - assert(path.size == 0 || path.values != NULL); - assert(path.size + 1 < PATH_BUF_SIZE); - - memset(buf, 0, PATH_BUF_SIZE); - if (path.size > 0 && path.size + 1 < PATH_BUF_SIZE) - memcpy(buf, path.values, path.size); -} - -#define PREPARE_PATH_BUF_ \ - char buf[PATH_BUF_SIZE]; \ - kit_prepare_path_(buf, path) - -s32 kit_folder_create(kit_str_t path) { - PREPARE_PATH_BUF_; -#if defined(_WIN32) && !defined(__CYGWIN__) - return CreateDirectoryA(buf, NULL) ? KIT_OK - : KIT_ERROR_MKDIR_FAILED; -#else - return mkdir(buf, 0775) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED; -#endif -} - -s32 kit_folder_create_recursive(kit_str_t path) { - for (i32 i = 0;; i++) { - str_t part = kit_path_take(path, i); - i32 type = kit_path_type(part); - if (type == KIT_PATH_FILE) - return KIT_ERROR_FILE_ALREADY_EXISTS; - if (type == KIT_PATH_NONE) { - s32 s = kit_folder_create(part); - if (s != KIT_OK) - return s; - } - if (part.size == path.size) - break; - } - - return KIT_OK; -} - -s32 kit_file_remove(kit_str_t path) { - PREPARE_PATH_BUF_; -#if defined(_WIN32) && !defined(__CYGWIN__) - return DeleteFileA(buf) ? KIT_OK : KIT_ERROR_UNLINK_FAILED; -#else - return unlink(buf) == 0 ? KIT_OK : KIT_ERROR_UNLINK_FAILED; -#endif -} - -s32 kit_folder_remove(kit_str_t path) { - PREPARE_PATH_BUF_; -#if defined(_WIN32) && !defined(__CYGWIN__) - return RemoveDirectoryA(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED; -#else - return rmdir(buf) == 0 ? KIT_OK : KIT_ERROR_RMDIR_FAILED; -#endif -} - -s32 kit_file_remove_recursive(kit_str_t path, - kit_allocator_t *alloc) { - i32 type = kit_path_type(path); - i64 i; - - switch (type) { - case KIT_PATH_FILE: { - s32 s = kit_file_remove(path); - assert(s == KIT_OK); - return s; - } - - case KIT_PATH_FOLDER: { - kit_path_list_t list = kit_folder_enum(path, alloc); - - assert(list.status == KIT_OK); - if (list.status != KIT_OK) { - kit_path_list_destroy(list); - return list.status; - } - - for (i = 0; i < list.files.size; i++) { - str_builder_t full_path = kit_path_join( - path, WRAP_STR(list.files.values[i]), alloc); - s32 s = kit_file_remove_recursive(WRAP_STR(full_path), alloc); - DA_DESTROY(full_path); - assert(s == KIT_OK); - } - - kit_path_list_destroy(list); - - s32 s = kit_folder_remove(path); - assert(s == KIT_OK); - return s; - } - - default:; - } - - return KIT_ERROR_FILE_DOES_NOT_EXIST; -} - -kit_path_type_t kit_path_type(kit_str_t path) { - PREPARE_PATH_BUF_; -#if defined(_WIN32) && !defined(__CYGWIN__) - if (PathFileExistsA(buf)) { - if ((GetFileAttributesA(buf) & FILE_ATTRIBUTE_DIRECTORY) != 0) - return KIT_PATH_FOLDER; - else - return KIT_PATH_FILE; - } -#else - struct stat info; - if (stat(buf, &info) == 0) { - if (S_ISREG(info.st_mode)) - return KIT_PATH_FILE; - if (S_ISDIR(info.st_mode)) - return KIT_PATH_FOLDER; - } -#endif - return KIT_PATH_NONE; -} - -kit_file_info_t kit_file_info(kit_str_t path) { - kit_file_info_t result; - memset(&result, 0, sizeof result); - - PREPARE_PATH_BUF_; - -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE f = CreateFileA(buf, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (f != INVALID_HANDLE_VALUE) { - FILETIME ft; - if (GetFileTime(f, NULL, NULL, &ft) != 0) { - i64 nsec100 = (((u64) ft.dwHighDateTime) << 32) | - (u64) ft.dwLowDateTime; - result.time_modified_sec = (i64) (nsec100 / 10000000); - result.time_modified_nsec = (i32) (100 * (nsec100 % 10000000)); - } else { - assert(0); - } - - DWORD high; - DWORD low = GetFileSize(f, &high); - - result.size = (i64) ((((u64) high) << 32) | (u64) low); - result.status = KIT_OK; - - CloseHandle(f); - return result; - } -#else - struct stat info; - if (stat(buf, &info) == 0 && S_ISREG(info.st_mode)) { - result.size = (i64) info.st_size; -# ifndef st_mtime - // No support for nanosecond timestamps. - // - result.time_modified_sec = (i64) info.st_mtime; -# else - result.time_modified_sec = (i64) info.st_mtim.tv_sec; - result.time_modified_nsec = (i32) info.st_mtim.tv_nsec; -# endif - result.status = KIT_OK; - return result; - } -#endif - - result.status = KIT_ERROR_FILE_DOES_NOT_EXIST; - return result; -} - -kit_path_list_t kit_folder_enum(kit_str_t path, - kit_allocator_t *alloc) { - PREPARE_PATH_BUF_; - - kit_path_list_t result = { .status = KIT_OK }; - DA_INIT(result.files, 0, alloc); - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (path.size + 3 >= PATH_BUF_SIZE) { - result.status = KIT_ERROR_PATH_TOO_LONG; - return result; - } - - buf[path.size] = '\\'; - buf[path.size + 1] = '*'; - - WIN32_FIND_DATAA data; - HANDLE find = FindFirstFileA(buf, &data); - - if (find == INVALID_HANDLE_VALUE) - return result; - - do { - if (strcmp(data.cFileName, ".") == 0 || - strcmp(data.cFileName, "..") == 0) - continue; - - i64 n = result.files.size; - DA_RESIZE(result.files, n + 1); - if (result.files.size != n + 1) { - result.status = KIT_ERROR_OUT_OF_MEMORY; - break; - } - - i64 size = (i64) strlen(data.cFileName); - DA_INIT(result.files.values[n], size, alloc); - if (result.files.values[n].size != size) { - DA_RESIZE(result.files, n); - result.status = KIT_ERROR_OUT_OF_MEMORY; - break; - } - - memcpy(result.files.values[n].values, data.cFileName, size); - } while (FindNextFileA(find, &data) != 0); - - FindClose(find); -#else - DIR *directory = opendir(buf); - - if (directory == NULL) - return result; - - for (;;) { - struct dirent *entry = readdir(directory); - - if (entry == NULL) - break; - - if (entry->d_name[0] == '.') - continue; - - i64 n = result.files.size; - DA_RESIZE(result.files, n + 1); - if (result.files.size != n + 1) { - result.status = KIT_ERROR_OUT_OF_MEMORY; - break; - } - - i64 size = (i64) strlen(entry->d_name); - DA_INIT(result.files.values[n], size, alloc); - if (result.files.values[n].size != size) { - DA_RESIZE(result.files, n); - result.status = KIT_ERROR_OUT_OF_MEMORY; - break; - } - - if (size > 0) - memcpy(result.files.values[n].values, entry->d_name, size); - } - - closedir(directory); -#endif - - return result; -} - -void kit_path_list_destroy(kit_path_list_t list) { - i64 i; - for (i = 0; i < list.files.size; i++) - DA_DESTROY(list.files.values[i]); - DA_DESTROY(list.files); -} - -kit_mapped_file_t kit_file_map(kit_str_t path, i64 size, i32 mode) { - assert(size > 0); - assert(path.size > 0); - assert(path.size <= PATH_MAX); - assert(path.values != NULL); - - kit_mapped_file_t mf; - memset(&mf, 0, sizeof mf); - - if (size <= 0) { - mf.status = KIT_ERROR_INVALID_SIZE; - return mf; - } - - if (path.size <= 0) { - mf.status = KIT_ERROR_INVALID_ARGUMENT; - return mf; - } - - if (path.size > PATH_MAX) { - mf.status = KIT_ERROR_PATH_TOO_LONG; - return mf; - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - char buf[MAX_PATH + 1]; - memcpy(buf, path.values, path.size); - buf[path.size] = '\0'; - - HANDLE file = CreateFileA( - buf, GENERIC_READ | GENERIC_WRITE, - mode == FILE_MAP_SHARED ? FILE_SHARE_READ | FILE_SHARE_WRITE - : 0, - NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file == INVALID_HANDLE_VALUE) { - mf.status = KIT_ERROR_OPEN_FAILED; - return mf; - } - - LONG high = (LONG) (size >> 32); - - if (SetFilePointer(file, (LONG) size, &high, FILE_BEGIN) == - INVALID_SET_FILE_POINTER) { - CloseHandle(file); - assert(0); - mf.status = KIT_ERROR_TRUNCATE_FAILED; - return mf; - } - - if (!SetEndOfFile(file)) { - CloseHandle(file); - assert(0); - mf.status = KIT_ERROR_TRUNCATE_FAILED; - return mf; - } - - HANDLE map = CreateFileMappingA(file, NULL, PAGE_READWRITE, - (DWORD) (size >> 32), (DWORD) size, - NULL); - - if (map == INVALID_HANDLE_VALUE) { - CloseHandle(file); - assert(0); - mf.status = KIT_ERROR_MAP_FAILED; - return mf; - } - - void *p = MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, - (SIZE_T) size); - - if (p == NULL) { - CloseHandle(map); - CloseHandle(file); - assert(0); - mf.status = KIT_ERROR_MAP_FAILED; - return mf; - } - - mf.status = KIT_OK; - mf.size = size; - mf.bytes = p; - mf._file = file; - mf._map = map; -#else - char buf[PATH_MAX + 1]; - memcpy(buf, path.values, path.size); - buf[path.size] = '\0'; - - i32 fd = open(buf, O_RDWR | O_CREAT, 0664); - - if (fd == -1) { - mf.status = KIT_ERROR_OPEN_FAILED; - return mf; - } - - if (ftruncate(fd, size) == -1) { - close(fd); - assert(0); - mf.status = KIT_ERROR_TRUNCATE_FAILED; - return mf; - } - - void *p = mmap( - NULL, size, PROT_READ | PROT_WRITE, - mode == KIT_FILE_MAP_SHARED ? MAP_SHARED : MAP_PRIVATE, fd, 0); - - if (p == MAP_FAILED) { - close(fd); - assert(0); - mf.status = KIT_ERROR_MAP_FAILED; - return mf; - } - - mf.status = KIT_OK; - mf.size = size; - mf.bytes = (u8 *) p; - mf._fd = fd; -#endif - - return mf; -} - -s32 kit_file_sync(kit_mapped_file_t *mf) { - assert(mf != NULL); - - if (mf == NULL) - return KIT_ERROR_INVALID_ARGUMENT; - - s32 status = KIT_OK; - -#if !defined(_WIN32) || defined(__CYGWIN__) - if (msync(mf->bytes, mf->size, MS_SYNC) != 0) - status |= KIT_ERROR_SYNC_FAILED; -#endif - - return status; -} - -s32 kit_file_unmap(kit_mapped_file_t *mf) { - assert(mf != NULL); - - if (mf == NULL) - return KIT_ERROR_INVALID_ARGUMENT; - - s32 status = KIT_OK; - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (!UnmapViewOfFile(mf->bytes)) - status |= KIT_ERROR_UNMAP_FAILED; - if (!CloseHandle(mf->_map) || !CloseHandle(mf->_file)) - status |= KIT_ERROR_CLOSE_FAILED; -#else - if (munmap(mf->bytes, mf->size) != 0) - status |= KIT_ERROR_UNMAP_FAILED; - if (close(mf->_fd) != 0) - status |= KIT_ERROR_CLOSE_FAILED; -#endif - - return status; -} |