mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 22:43:25 +00:00
Files: add wrappers for certain open() methods
Due to filepath encoding issues on win32 we need wrappers for: - open() - fopen() - opendir() - zip_open() (this is readonly on win32) Patch only declares/defines the wrappers in dive.h, windows.c, linux.c, macos.c. Suggestions-by: Thiago Macieira <thiago@macieira.org> Suggestions-by: Jef Driesen <jefdriesen@telenet.be> Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
cad0d45fe1
commit
f487953ad3
4 changed files with 157 additions and 0 deletions
7
dive.h
7
dive.h
|
@ -5,6 +5,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <zip.h>
|
||||||
|
|
||||||
/* Windows has no MIN/MAX macros - so let's just roll our own */
|
/* Windows has no MIN/MAX macros - so let's just roll our own */
|
||||||
#define MIN(x, y) ({ \
|
#define MIN(x, y) ({ \
|
||||||
|
@ -633,6 +634,12 @@ extern void save_dives_logic(const char *filename, bool select_only);
|
||||||
extern void save_dive(FILE *f, struct dive *dive);
|
extern void save_dive(FILE *f, struct dive *dive);
|
||||||
extern void export_dives_uddf(const char *filename, const bool selected);
|
extern void export_dives_uddf(const char *filename, const bool selected);
|
||||||
|
|
||||||
|
extern int subsurface_open(const char *path, int oflags, mode_t mode);
|
||||||
|
extern FILE *subsurface_fopen(const char *path, const char *mode);
|
||||||
|
extern void *subsurface_opendir(const char *path);
|
||||||
|
extern struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp);
|
||||||
|
extern int subsurface_zip_close(struct zip *zip);
|
||||||
|
|
||||||
extern void shift_times(const timestamp_t amount);
|
extern void shift_times(const timestamp_t amount);
|
||||||
|
|
||||||
extern xsltStylesheetPtr get_stylesheet(const char *name);
|
extern xsltStylesheetPtr get_stylesheet(const char *name);
|
||||||
|
|
28
linux.c
28
linux.c
|
@ -6,6 +6,8 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
const char system_divelist_default_font[] = "Sans 8";
|
const char system_divelist_default_font[] = "Sans 8";
|
||||||
|
|
||||||
|
@ -97,3 +99,29 @@ int enumerate_devices (device_callback_t callback, void *userdata)
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOP wrappers to comform with windows.c */
|
||||||
|
int subsurface_open(const char *path, int oflags, mode_t mode)
|
||||||
|
{
|
||||||
|
return open(path, oflags, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *subsurface_fopen(const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
return fopen(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *subsurface_opendir(const char *path)
|
||||||
|
{
|
||||||
|
return (void *)opendir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp)
|
||||||
|
{
|
||||||
|
return zip_open(path, flags, errorp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int subsurface_zip_close(struct zip *zip)
|
||||||
|
{
|
||||||
|
return zip_close(zip);
|
||||||
|
}
|
||||||
|
|
29
macos.c
29
macos.c
|
@ -9,6 +9,9 @@
|
||||||
#include <CoreServices/CoreServices.h>
|
#include <CoreServices/CoreServices.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
#include <sys/syslimits.h>
|
#include <sys/syslimits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
/* macos defines CFSTR to create a CFString object from a constant,
|
/* macos defines CFSTR to create a CFString object from a constant,
|
||||||
* but no similar macros if a C string variable is supposed to be
|
* but no similar macros if a C string variable is supposed to be
|
||||||
|
@ -77,3 +80,29 @@ int enumerate_devices (device_callback_t callback, void *userdata)
|
||||||
closedir (dp);
|
closedir (dp);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOP wrappers to comform with windows.c */
|
||||||
|
int subsurface_open(const char *path, int oflags, mode_t mode)
|
||||||
|
{
|
||||||
|
return open(path, oflags, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *subsurface_fopen(const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
return fopen(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *subsurface_opendir(const char *path)
|
||||||
|
{
|
||||||
|
return (void *)opendir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp)
|
||||||
|
{
|
||||||
|
return zip_open(path, flags, errorp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int subsurface_zip_close(struct zip *zip)
|
||||||
|
{
|
||||||
|
return zip_close(zip);
|
||||||
|
}
|
||||||
|
|
93
windows.c
93
windows.c
|
@ -4,6 +4,11 @@
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <zip.h>
|
||||||
|
|
||||||
const char system_divelist_default_font[] = "Sans 8";
|
const char system_divelist_default_font[] = "Sans 8";
|
||||||
|
|
||||||
|
@ -78,3 +83,91 @@ int enumerate_devices (device_callback_t callback, void *userdata)
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this function converts a utf-8 string to win32's utf-16 2 byte string.
|
||||||
|
* the caller function should manage the allocated memory.
|
||||||
|
*/
|
||||||
|
static wchar_t *utf8_to_utf16_fl(const char *utf8, char *file, int line)
|
||||||
|
{
|
||||||
|
assert(utf8 != NULL);
|
||||||
|
assert(file != NULL);
|
||||||
|
assert(line);
|
||||||
|
/* estimate buffer size */
|
||||||
|
const int sz = strlen(utf8) + 1;
|
||||||
|
wchar_t *utf16 = (wchar_t *)malloc(sizeof(wchar_t) * sz);
|
||||||
|
if (!utf16) {
|
||||||
|
fprintf(stderr, "%s:%d: %s %d.", file, line, "cannot allocate buffer of size", sz);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, sz))
|
||||||
|
return utf16;
|
||||||
|
fprintf(stderr, "%s:%d: %s", file, line, "cannot convert string.");
|
||||||
|
free((void *)utf16);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define utf8_to_utf16(s) utf8_to_utf16_fl(s, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
/* bellow we provide a set of wrappers for some I/O functions to use wchar_t.
|
||||||
|
* on win32 this solves the issue that we need paths to be utf-16 encoded.
|
||||||
|
*/
|
||||||
|
int subsurface_open(const char *path, int oflags, mode_t mode)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
wchar_t *wpath = utf8_to_utf16(path);
|
||||||
|
if (wpath) {
|
||||||
|
ret = _wopen(wpath, oflags, mode);
|
||||||
|
free((void *)wpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *subsurface_fopen(const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
FILE *ret = NULL;
|
||||||
|
wchar_t *wpath = utf8_to_utf16(path);
|
||||||
|
if (wpath) {
|
||||||
|
const int len = strlen(mode);
|
||||||
|
wchar_t wmode[len + 1];
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
wmode[i] = (wchar_t)mode[i];
|
||||||
|
wmode[len] = 0;
|
||||||
|
ret = _wfopen(wpath, wmode);
|
||||||
|
free((void *)wpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* here we return a void pointer instead of _WDIR or DIR pointer */
|
||||||
|
void *subsurface_opendir(const char *path)
|
||||||
|
{
|
||||||
|
_WDIR *ret = NULL;
|
||||||
|
wchar_t *wpath = utf8_to_utf16(path);
|
||||||
|
if (wpath) {
|
||||||
|
ret = _wopendir(wpath);
|
||||||
|
free((void *)wpath);
|
||||||
|
return (void *)ret;
|
||||||
|
}
|
||||||
|
return (void *)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* we use zip_fdopen since zip_open doesn't have a wchar_t version */
|
||||||
|
struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp)
|
||||||
|
{
|
||||||
|
int fd = subsurface_open(path, O_RDONLY | O_BINARY, 0);
|
||||||
|
struct zip *ret = zip_fdopen(fd, flags, errorp);
|
||||||
|
if (!ret)
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int subsurface_zip_close(struct zip *zip)
|
||||||
|
{
|
||||||
|
return zip_close(zip);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue