summaryrefslogtreecommitdiff
path: root/libavformat/os_support.h
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-11-25 02:52:54 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-11-25 02:52:54 +0100
commitecfafc5f2b632780dd310def1d6b3a2c10565465 (patch)
tree3a87ca7ab687afe953c778b0503af3393969ecb0 /libavformat/os_support.h
parent71ecfcf2d31e4f906f52c3450f4fb46c5087f50e (diff)
parent960aff379da46dcaff61504a57714d4d4e758e41 (diff)
Merge commit '960aff379da46dcaff61504a57714d4d4e758e41'
* commit '960aff379da46dcaff61504a57714d4d4e758e41': lavf: Use wchar functions for filenames on windows for mkdir/rmdir/rename/unlink Conflicts: libavformat/os_support.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/os_support.h')
-rw-r--r--libavformat/os_support.h99
1 files changed, 91 insertions, 8 deletions
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index bc72e96a4c..256890b2b9 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -31,6 +31,15 @@
#include <sys/stat.h>
+#ifdef _WIN32
+#if HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#endif
+
#if defined(_WIN32) && !defined(__MINGW32CE__)
# include <fcntl.h>
# ifdef lseek
@@ -47,14 +56,6 @@
# define fstat(f,s) _fstati64((f), (s))
#endif /* defined(_WIN32) && !defined(__MINGW32CE__) */
-#ifdef _WIN32
-#if HAVE_DIRECT_H
-#include <direct.h>
-#elif HAVE_IO_H
-#include <io.h>
-#endif
-#define mkdir(a, b) _mkdir(a)
-#endif
#ifdef __ANDROID__
# if HAVE_UNISTD_H
@@ -138,4 +139,86 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout);
#endif /* HAVE_POLL_H */
#endif /* CONFIG_NETWORK */
+#if defined(__MINGW32CE__)
+#define mkdir(a, b) _mkdir(a)
+#elif defined(_WIN32)
+#include <stdio.h>
+#include <windows.h>
+#include "libavutil/mem.h"
+
+static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w)
+{
+ int num_chars;
+ num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
+ if (num_chars <= 0) {
+ *filename_w = NULL;
+ return 0;
+ }
+ *filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
+ if (!*filename_w) {
+ errno = ENOMEM;
+ return -1;
+ }
+ MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, *filename_w, num_chars);
+ return 0;
+}
+
+#define DEF_FS_FUNCTION(name, wfunc, afunc) \
+static inline int win32_##name(const char *filename_utf8) \
+{ \
+ wchar_t *filename_w; \
+ int ret; \
+ \
+ if (utf8towchar(filename_utf8, &filename_w)) \
+ return -1; \
+ if (!filename_w) \
+ goto fallback; \
+ \
+ ret = wfunc(filename_w); \
+ av_free(filename_w); \
+ return ret; \
+ \
+fallback: \
+ /* filename may be be in CP_ACP */ \
+ return afunc(filename_utf8); \
+}
+
+DEF_FS_FUNCTION(unlink, _wunlink, _unlink)
+DEF_FS_FUNCTION(mkdir, _wmkdir, _mkdir)
+DEF_FS_FUNCTION(rmdir, _wrmdir , _rmdir)
+
+static inline int win32_rename(const char *src_utf8, const char *dest_utf8)
+{
+ wchar_t *src_w, *dest_w;
+ int ret;
+
+ if (utf8towchar(src_utf8, &src_w))
+ return -1;
+ if (utf8towchar(dest_utf8, &dest_w)) {
+ av_free(src_w);
+ return -1;
+ }
+ if (!src_w || !dest_w) {
+ av_free(src_w);
+ av_free(dest_w);
+ goto fallback;
+ }
+
+ ret = _wrename(src_w, dest_w);
+ av_free(src_w);
+ av_free(dest_w);
+ return ret;
+
+fallback:
+ /* filename may be be in CP_ACP */
+ return rename(src_utf8, dest_utf8);
+}
+
+#define mkdir(a, b) win32_mkdir(a)
+#define rename win32_rename
+#define rmdir win32_rmdir
+#define unlink win32_unlink
+
+#endif
+
#endif /* AVFORMAT_OS_SUPPORT_H */