diff -r 90a6d6952d83 -r 0b9bea2d7283 dav/system.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dav/system.c Fri Jun 08 19:58:17 2018 +0200 @@ -0,0 +1,183 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2018 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "system.h" + +void sys_freedirent(SysDirEnt *ent) { + free(ent->name); + free(ent); +} + +#ifndef _WIN32 +/* ---------- POSIX implementation ---------- */ + +SYS_DIR sys_opendir(const char *path) { + return opendir(path); +} + +SysDirEnt* sys_readdir(SYS_DIR dir) { + struct dirent *ent = readdir(dir); + if(ent) { + SysDirEnt *e = malloc(sizeof(SysDirEnt)); + e->name = strdup(ent->d_name); + return e; + } + return NULL; +} + +void sys_closedir(SYS_DIR dir) { + closedir(dir); +} + +FILE* sys_fopen(const char *path, const char *mode) { + return fopen(path, mode); +} + +int sys_stat(const char *path, SYS_STAT *s) { + return stat(path, s); +} + + +#else +/* ---------- Windows implementation ---------- */ + +static wchar_t* path2winpath(const char *path, int dir, int *newlen) { + size_t len = strlen(path); + size_t lenadd = dir ? 2 : 0; + + + wchar_t *wpath = calloc(len+lenadd, sizeof(wchar_t)); + int wlen = MultiByteToWideChar( + CP_UTF8, + 0, + path, + len, + wpath, + len+1 + ); + if(newlen) { + *newlen = wlen; + } + for(int i=0;ifirst = 1; + dir->handle = FindFirstFileW(dirpath, &dir->finddata); + free(dirpath); + if(dir->handle == INVALID_HANDLE_VALUE) { + free(dir); + return NULL; + } + return dir; +} + +SysDirEnt* sys_readdir(SYS_DIR dir) { + if(dir->first) { + dir->first = 0; + } else { + if(FindNextFileW(dir->handle, &dir->finddata) == 0) { + return NULL; + } + } + + size_t namelen = wcslen(dir->finddata.cFileName); + + char *name = malloc((namelen+1)*4); + int nlen = WideCharToMultiByte( + CP_UTF8, + 0, + dir->finddata.cFileName, + -1, + name, + 256, + NULL, + NULL); + if(nlen > 0) { + name[nlen] = 0; + SysDirEnt *ent = malloc(sizeof(SysDirEnt)); + ent->name = name; + return ent; + } else { + return NULL; + } +} + +void sys_closedir(SYS_DIR dir) { + FindClose(dir->handle); + free(dir); +} + +FILE* sys_fopen(const char *path, const char *mode) { + wchar_t *fpath = path2winpath(path, FALSE, NULL); + wchar_t *fmode = path2winpath(mode, FALSE, NULL); + + FILE *file = (fpath && fmode) ? _wfopen(fpath, fmode) : NULL; + free(fpath); + free(fmode); + return file; +} + +int sys_stat(const char *path, SYS_STAT *s) { + wchar_t *fpath = path2winpath(path, FALSE, NULL); + if(!fpath) { + fprintf(stderr, "Cannot convert path \"%s\" to UTF16\n", path); + return -1; + } + int ret = _wstat64(fpath, s); + free(fpath); + return ret; +} + +#endif \ No newline at end of file