summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2019-03-15 15:47:02 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2019-03-15 15:47:02 (GMT)
commitd2591ce377bb027d210a100c5a738e3cdd82378e (patch)
treec8a4cf3b5a11d712ae095a1daf58a4a0771ee5ec /src
parenta0c5d9a1d3ffbff3c78982a4d08bd8f1550f535d (diff)
parent0c20c65e2f3abf390ad87c9167daca4cdff2de39 (diff)
downloadhdf5-d2591ce377bb027d210a100c5a738e3cdd82378e.zip
hdf5-d2591ce377bb027d210a100c5a738e3cdd82378e.tar.gz
hdf5-d2591ce377bb027d210a100c5a738e3cdd82378e.tar.bz2
Merge pull request #1602 in HDFFV/hdf5 from ~DEROBINS/hdf5_der:wopen_squash to develop
* commit '0c20c65e2f3abf390ad87c9167daca4cdff2de39': Added the HDopen work-around on windows to pio_engine.c Adds _wopen support on Windows so that files with UTF-8 names can be opened.
Diffstat (limited to 'src')
-rw-r--r--src/H5system.c126
-rw-r--r--src/H5win32defs.h14
2 files changed, 134 insertions, 6 deletions
diff --git a/src/H5system.c b/src/H5system.c
index f47d057..2ddc29a 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -985,6 +985,132 @@ Wroundf(float arg)
return (float)(arg < 0.0F ? HDceil(arg - 0.5F) : HDfloor(arg + 0.5F));
}
+/*-------------------------------------------------------------------------
+* Function: H5_get_utf16_str
+*
+* Purpose: Gets a UTF-16 string from an UTF-8 (or ASCII) string.
+*
+* Return: Success: A pointer to a UTF-16 string
+* This must be freed by the caller using H5MM_xfree()
+* Failure: NULL
+*
+* Programmer: Dana Robinson
+* Spring 2019
+*
+*-------------------------------------------------------------------------
+*/
+const wchar_t *
+H5_get_utf16_str(const char *s)
+{
+ int nwchars = -1; /* Length of the UTF-16 buffer */
+ wchar_t *ret_s = NULL; /* UTF-16 version of the string */
+
+ /* Get the number of UTF-16 characters needed */
+ if(0 == (nwchars = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0)))
+ goto error;
+
+ /* Allocate a buffer for the UTF-16 string */
+ if(NULL == (ret_s = (wchar_t *)H5MM_calloc(sizeof(wchar_t) * (size_t)nwchars)))
+ goto error;
+
+ /* Convert the input UTF-8 string to UTF-16 */
+ if(0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ret_s, nwchars))
+ goto error;
+
+ return ret_s;
+
+error:
+ if(ret_s)
+ H5MM_xfree((void *)ret_s);
+ return NULL;
+} /* end H5_get_utf16_str() */
+
+/*-------------------------------------------------------------------------
+ * Function: Wopen_utf8
+ *
+ * Purpose: UTF-8 equivalent of open(2) for use on Windows.
+ * Converts a UTF-8 input path to UTF-16 and then opens the
+ * file via _wopen() under the hood
+ *
+ * Return: Success: A POSIX file descriptor
+ * Failure: -1
+ *
+ * Programmer: Dana Robinson
+ * Spring 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+Wopen_utf8(const char *path, int oflag, ...)
+{
+ int fd = -1; /* POSIX file descriptor to be returned */
+ wchar_t *wpath = NULL; /* UTF-16 version of the path */
+ int pmode = 0; /* mode (optionally set via variable args) */
+
+ /* Convert the input UTF-8 path to UTF-16 */
+ if(NULL == (wpath = H5_get_utf16_str(path)))
+ goto done;
+
+ /* _O_BINARY must be set in Windows to avoid CR-LF <-> LF EOL
+ * transformations when performing I/O. Note that this will
+ * produce Unix-style text files, though.
+ */
+ oflag |= _O_BINARY;
+
+ /* Get the mode, if O_CREAT was specified */
+ if(oflag & O_CREAT) {
+ va_list vl;
+
+ HDva_start(vl, oflag);
+ pmode = HDva_arg(vl, int);
+ HDva_end(vl);
+ }
+
+ /* Open the file */
+ fd = _wopen(wpath, oflag, pmode);
+
+done:
+ if(wpath)
+ H5MM_xfree((void *)wpath);
+
+ return fd;
+} /* end Wopen_utf8() */
+
+/*-------------------------------------------------------------------------
+ * Function: Wremove_utf8
+ *
+ * Purpose: UTF-8 equivalent of remove(3) for use on Windows.
+ * Converts a UTF-8 input path to UTF-16 and then opens the
+ * file via _wremove() under the hood
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Dana Robinson
+ * Spring 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+Wremove_utf8(const char *path)
+{
+ wchar_t *wpath = NULL; /* UTF-16 version of the path */
+ int ret;
+
+ /* Convert the input UTF-8 path to UTF-16 */
+ if(NULL == (wpath = H5_get_utf16_str(path)))
+ goto done;
+
+ /* Open the file */
+ ret = _wremove(wpath);
+
+done:
+ if(wpath)
+ H5MM_xfree((void *)wpath);
+
+ return ret;
+} /* end Wremove_utf8() */
+
#endif /* H5_HAVE_WIN32_API */
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 140afc3..2ae2575 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -34,6 +34,7 @@ typedef __int64 h5_stat_size_t;
#define HDaccess(F,M) _access(F,M)
#define HDchdir(S) _chdir(S)
#define HDclose(F) _close(F)
+#define HDcreat(S,M) Wopen_utf8(S,O_CREAT|O_TRUNC|O_RDWR,M)
#define HDdup(F) _dup(F)
#define HDfdopen(N,S) _fdopen(N,S)
#define HDfileno(F) _fileno(F)
@@ -47,15 +48,13 @@ typedef __int64 h5_stat_size_t;
#define HDmkdir(S,M) _mkdir(S)
#define HDnanosleep(N, O) Wnanosleep(N, O)
#define HDoff_t __int64
-/* _O_BINARY must be set in Windows to avoid CR-LF <-> LF EOL
- * transformations when performing I/O. Note that this will
- * produce Unix-style text files, though.
- *
- * Also note that the variadic macro is using a VC++ extension
+
+/* Note that the variadic HDopen macro is using a VC++ extension
* where the comma is dropped if nothing is passed to the ellipsis.
*/
-#define HDopen(S,F,...) _open(S, F | _O_BINARY, __VA_ARGS__)
+#define HDopen(S,F,...) Wopen_utf8(S,F,__VA_ARGS__)
#define HDread(F,M,Z) _read(F,M,Z)
+#define HDremove(S) Wremove_utf8(S)
#define HDrmdir(S) _rmdir(S)
#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,(Z>1?Z:2))
#define HDsleep(S) Sleep(S*1000)
@@ -128,6 +127,9 @@ extern "C" {
H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap);
H5_DLL int Wnanosleep(const struct timespec *req, struct timespec *rem);
H5_DLL herr_t H5_expand_windows_env_vars(char **env_var);
+ H5_DLL const wchar_t *H5_get_utf16_str(const char *s);
+ H5_DLL int Wopen_utf8(const char *path, int oflag, ...);
+ H5_DLL int Wremove_utf8(const char *path);
/* Round functions only needed for VS2012 and earlier.
* They are always built to ensure they don't go stale and